| Line | Branch | Exec | Source | 
    
      | 1 |  |  | /** | 
    
      | 2 |  |  | * This file is part of the CernVM File System. | 
    
      | 3 |  |  | */ | 
    
      | 4 |  |  |  | 
    
      | 5 |  |  | #include <cassert> | 
    
      | 6 |  |  | #include <string> | 
    
      | 7 |  |  |  | 
    
      | 8 |  |  | #include "statistics_database.h" | 
    
      | 9 |  |  | #include "swissknife.h" | 
    
      | 10 |  |  | #include "swissknife_check.h" | 
    
      | 11 |  |  | #include "swissknife_filestats.h" | 
    
      | 12 |  |  | #include "swissknife_gc.h" | 
    
      | 13 |  |  | #include "swissknife_graft.h" | 
    
      | 14 |  |  | #include "swissknife_history.h" | 
    
      | 15 |  |  | #include "swissknife_info.h" | 
    
      | 16 |  |  | #include "swissknife_ingest.h" | 
    
      | 17 |  |  | #include "swissknife_ingestsql.h" | 
    
      | 18 |  |  | #include "swissknife_lease.h" | 
    
      | 19 |  |  | #include "swissknife_letter.h" | 
    
      | 20 |  |  | #include "swissknife_list_reflog.h" | 
    
      | 21 |  |  | #include "swissknife_lsrepo.h" | 
    
      | 22 |  |  | #include "swissknife_migrate.h" | 
    
      | 23 |  |  | #include "swissknife_notify.h" | 
    
      | 24 |  |  | #include "swissknife_pull.h" | 
    
      | 25 |  |  | #include "swissknife_reflog.h" | 
    
      | 26 |  |  | #include "swissknife_scrub.h" | 
    
      | 27 |  |  | #include "swissknife_sign.h" | 
    
      | 28 |  |  | #include "swissknife_sync.h" | 
    
      | 29 |  |  | #include "swissknife_zpipe.h" | 
    
      | 30 |  |  | #include "util/logging.h" | 
    
      | 31 |  |  | #include "util/posix.h" | 
    
      | 32 |  |  | #include "util/string.h" | 
    
      | 33 |  |  |  | 
    
      | 34 |  |  | using namespace std;  // NOLINT | 
    
      | 35 |  |  |  | 
    
      | 36 |  |  | typedef vector<swissknife::Command *> Commands; | 
    
      | 37 |  |  | Commands command_list; | 
    
      | 38 |  |  |  | 
    
      | 39 |  | ✗ | void Usage() { | 
    
      | 40 |  | ✗ | LogCvmfs(kLogCvmfs, kLogStdout, | 
    
      | 41 |  |  | "CernVM-FS repository storage management commands\n" | 
    
      | 42 |  |  | "Usage (normally called from cvmfs_server):\n" | 
    
      | 43 |  |  | "  cvmfs_swissknife <command> [options]\n"); | 
    
      | 44 |  |  |  | 
    
      | 45 |  | ✗ | for (unsigned i = 0; i < command_list.size(); ++i) { | 
    
      | 46 |  | ✗ | LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak, | 
    
      | 47 |  |  | "\n" | 
    
      | 48 |  |  | "Command %s\n" | 
    
      | 49 |  |  | "--", | 
    
      | 50 |  |  | command_list[i]->GetName().c_str()); | 
    
      | 51 |  | ✗ | LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak, "\n"); | 
    
      | 52 |  | ✗ | LogCvmfs(kLogCvmfs, kLogStdout, "%s", | 
    
      | 53 |  |  | command_list[i]->GetDescription().c_str()); | 
    
      | 54 |  | ✗ | swissknife::ParameterList params = command_list[i]->GetParams(); | 
    
      | 55 |  | ✗ | if (!params.empty()) { | 
    
      | 56 |  | ✗ | LogCvmfs(kLogCvmfs, kLogStdout, "Options:"); | 
    
      | 57 |  | ✗ | for (unsigned j = 0; j < params.size(); ++j) { | 
    
      | 58 |  | ✗ | LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak, "  -%c    %s", | 
    
      | 59 |  |  | params[j].key(), params[j].description().c_str()); | 
    
      | 60 |  | ✗ | if (params[j].optional()) | 
    
      | 61 |  | ✗ | LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak, " (optional)"); | 
    
      | 62 |  | ✗ | LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak, "\n"); | 
    
      | 63 |  |  | } | 
    
      | 64 |  |  | }  // Parameter list | 
    
      | 65 |  | ✗ | }  // Command list | 
    
      | 66 |  |  |  | 
    
      | 67 |  | ✗ | LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak, "\n"); | 
    
      | 68 |  |  | } | 
    
      | 69 |  |  |  | 
    
      | 70 |  |  |  | 
    
      | 71 |  | ✗ | int main(int argc, char **argv) { | 
    
      | 72 |  |  | // Set default logging facilities | 
    
      | 73 |  | ✗ | DefaultLogging::Set(kLogStdout, kLogStderr); | 
    
      | 74 |  |  |  | 
    
      | 75 |  | ✗ | command_list.push_back(new swissknife::CommandCreate()); | 
    
      | 76 |  | ✗ | command_list.push_back(new swissknife::CommandUpload()); | 
    
      | 77 |  | ✗ | command_list.push_back(new swissknife::CommandRemove()); | 
    
      | 78 |  | ✗ | command_list.push_back(new swissknife::CommandPeek()); | 
    
      | 79 |  | ✗ | command_list.push_back(new swissknife::CommandSync()); | 
    
      | 80 |  | ✗ | command_list.push_back(new swissknife::CommandApplyDirtab()); | 
    
      | 81 |  | ✗ | command_list.push_back(new swissknife::CommandEditTag()); | 
    
      | 82 |  | ✗ | command_list.push_back(new swissknife::CommandListTags()); | 
    
      | 83 |  | ✗ | command_list.push_back(new swissknife::CommandInfoTag()); | 
    
      | 84 |  | ✗ | command_list.push_back(new swissknife::CommandRollbackTag()); | 
    
      | 85 |  | ✗ | command_list.push_back(new swissknife::CommandEmptyRecycleBin()); | 
    
      | 86 |  | ✗ | command_list.push_back(new swissknife::CommandSign()); | 
    
      | 87 |  | ✗ | command_list.push_back(new swissknife::CommandLetter()); | 
    
      | 88 |  | ✗ | command_list.push_back(new swissknife::CommandCheck()); | 
    
      | 89 |  | ✗ | command_list.push_back(new swissknife::CommandListCatalogs()); | 
    
      | 90 |  | ✗ | command_list.push_back(new swissknife::CommandPull()); | 
    
      | 91 |  | ✗ | command_list.push_back(new swissknife::CommandZpipe()); | 
    
      | 92 |  | ✗ | command_list.push_back(new swissknife::CommandGraft()); | 
    
      | 93 |  | ✗ | command_list.push_back(new swissknife::CommandInfo()); | 
    
      | 94 |  | ✗ | command_list.push_back(new swissknife::CommandVersion()); | 
    
      | 95 |  | ✗ | command_list.push_back(new swissknife::CommandMigrate()); | 
    
      | 96 |  | ✗ | command_list.push_back(new swissknife::CommandScrub()); | 
    
      | 97 |  | ✗ | command_list.push_back(new swissknife::CommandGc()); | 
    
      | 98 |  | ✗ | command_list.push_back(new swissknife::CommandListReflog()); | 
    
      | 99 |  | ✗ | command_list.push_back(new swissknife::CommandReconstructReflog()); | 
    
      | 100 |  | ✗ | command_list.push_back(new swissknife::CommandLease()); | 
    
      | 101 |  | ✗ | command_list.push_back(new swissknife::Ingest()); | 
    
      | 102 |  | ✗ | command_list.push_back(new swissknife::IngestSQL()); | 
    
      | 103 |  | ✗ | command_list.push_back(new swissknife::CommandNotify()); | 
    
      | 104 |  | ✗ | command_list.push_back(new swissknife::CommandFileStats()); | 
    
      | 105 |  |  |  | 
    
      | 106 |  | ✗ | if (argc < 2) { | 
    
      | 107 |  | ✗ | Usage(); | 
    
      | 108 |  | ✗ | return 1; | 
    
      | 109 |  |  | } | 
    
      | 110 |  | ✗ | if ((string(argv[1]) == "--help")) { | 
    
      | 111 |  | ✗ | Usage(); | 
    
      | 112 |  | ✗ | return 0; | 
    
      | 113 |  |  | } | 
    
      | 114 |  | ✗ | if ((string(argv[1]) == "--version")) { | 
    
      | 115 |  | ✗ | swissknife::CommandVersion().Main(swissknife::ArgumentList()); | 
    
      | 116 |  | ✗ | return 0; | 
    
      | 117 |  |  | } | 
    
      | 118 |  |  |  | 
    
      | 119 |  |  | // find the command to be run | 
    
      | 120 |  | ✗ | swissknife::Command *command = NULL; | 
    
      | 121 |  | ✗ | for (unsigned i = 0; i < command_list.size(); ++i) { | 
    
      | 122 |  | ✗ | if (command_list[i]->GetName() == string(argv[1])) { | 
    
      | 123 |  | ✗ | command = command_list[i]; | 
    
      | 124 |  | ✗ | break; | 
    
      | 125 |  |  | } | 
    
      | 126 |  |  | } | 
    
      | 127 |  |  |  | 
    
      | 128 |  | ✗ | if (NULL == command) { | 
    
      | 129 |  | ✗ | Usage(); | 
    
      | 130 |  | ✗ | return 1; | 
    
      | 131 |  |  | } | 
    
      | 132 |  |  |  | 
    
      | 133 |  | ✗ | bool display_statistics = false; | 
    
      | 134 |  |  |  | 
    
      | 135 |  |  | // parse the command line arguments for the Command | 
    
      | 136 |  | ✗ | swissknife::ArgumentList args; | 
    
      | 137 |  | ✗ | optind = 1; | 
    
      | 138 |  | ✗ | string option_string = ""; | 
    
      | 139 |  | ✗ | swissknife::ParameterList params = command->GetParams(); | 
    
      | 140 |  | ✗ | for (unsigned j = 0; j < params.size(); ++j) { | 
    
      | 141 |  | ✗ | option_string.push_back(params[j].key()); | 
    
      | 142 |  | ✗ | if (!params[j].switch_only()) | 
    
      | 143 |  | ✗ | option_string.push_back(':'); | 
    
      | 144 |  |  | } | 
    
      | 145 |  |  | // Now adding the generic -+ extra option command | 
    
      | 146 |  | ✗ | option_string.push_back(swissknife::Command::kGenericParam); | 
    
      | 147 |  | ✗ | option_string.push_back(':'); | 
    
      | 148 |  |  | int c; | 
    
      | 149 |  | ✗ | while ((c = getopt(argc, argv, option_string.c_str())) != -1) { | 
    
      | 150 |  | ✗ | bool valid_option = false; | 
    
      | 151 |  | ✗ | for (unsigned j = 0; j < params.size(); ++j) { | 
    
      | 152 |  | ✗ | if (c == params[j].key()) { | 
    
      | 153 |  | ✗ | assert(c != swissknife::Command::kGenericParam); | 
    
      | 154 |  | ✗ | valid_option = true; | 
    
      | 155 |  | ✗ | args[c].Reset(); | 
    
      | 156 |  | ✗ | if (!params[j].switch_only()) { | 
    
      | 157 |  | ✗ | args[c].Reset(new string(optarg)); | 
    
      | 158 |  |  | } | 
    
      | 159 |  | ✗ | break; | 
    
      | 160 |  |  | } | 
    
      | 161 |  |  | } | 
    
      | 162 |  | ✗ | if (c == swissknife::Command::kGenericParam) { | 
    
      | 163 |  | ✗ | valid_option = true; | 
    
      | 164 |  |  | vector<string> flags = SplitString( | 
    
      | 165 |  | ✗ | optarg, swissknife::Command::kGenericParamSeparator); | 
    
      | 166 |  | ✗ | for (unsigned i = 0; i < flags.size(); ++i) { | 
    
      | 167 |  | ✗ | if (flags[i] == "stats") { | 
    
      | 168 |  | ✗ | display_statistics = true; | 
    
      | 169 |  |  | } | 
    
      | 170 |  |  | } | 
    
      | 171 |  |  | } | 
    
      | 172 |  | ✗ | if (!valid_option) { | 
    
      | 173 |  | ✗ | Usage(); | 
    
      | 174 |  | ✗ | return 1; | 
    
      | 175 |  |  | } | 
    
      | 176 |  |  | } | 
    
      | 177 |  | ✗ | for (unsigned j = 0; j < params.size(); ++j) { | 
    
      | 178 |  | ✗ | if (!params[j].optional()) { | 
    
      | 179 |  | ✗ | if (args.find(params[j].key()) == args.end()) { | 
    
      | 180 |  | ✗ | LogCvmfs(kLogCvmfs, kLogStderr, "parameter -%c missing", | 
    
      | 181 |  |  | params[j].key()); | 
    
      | 182 |  | ✗ | return 1; | 
    
      | 183 |  |  | } | 
    
      | 184 |  |  | } | 
    
      | 185 |  |  | } | 
    
      | 186 |  |  |  | 
    
      | 187 |  |  | // run the command | 
    
      | 188 |  | ✗ | const string start_time = GetGMTimestamp(); | 
    
      | 189 |  | ✗ | const int retval = command->Main(args); | 
    
      | 190 |  | ✗ | const string finish_time = GetGMTimestamp(); | 
    
      | 191 |  |  |  | 
    
      | 192 |  | ✗ | if (display_statistics) { | 
    
      | 193 |  | ✗ | LogCvmfs(kLogCvmfs, kLogStdout, "Command statistics"); | 
    
      | 194 |  | ✗ | LogCvmfs(kLogCvmfs, kLogStdout, "%s", | 
    
      | 195 |  |  | command->statistics() | 
    
      | 196 |  |  | ->PrintList(perf::Statistics::kPrintHeader) | 
    
      | 197 |  |  | .c_str()); | 
    
      | 198 |  |  | } | 
    
      | 199 |  |  |  | 
    
      | 200 |  |  | // delete the command list | 
    
      | 201 |  | ✗ | Commands::const_iterator i = command_list.begin(); | 
    
      | 202 |  | ✗ | const Commands::const_iterator iend = command_list.end(); | 
    
      | 203 |  | ✗ | for (; i != iend; ++i) { | 
    
      | 204 |  | ✗ | delete *i; | 
    
      | 205 |  |  | } | 
    
      | 206 |  | ✗ | command_list.clear(); | 
    
      | 207 |  |  |  | 
    
      | 208 |  | ✗ | return retval; | 
    
      | 209 |  |  | } | 
    
      | 210 |  |  |  |