GCC Code Coverage Report
Directory: cvmfs/ Exec Total Coverage
File: cvmfs/swissknife_main.cc Lines: 0 136 0.0 %
Date: 2019-02-03 02:48:13 Branches: 0 92 0.0 %

Line Branch Exec Source
1
/**
2
 * This file is part of the CernVM File System.
3
 */
4
5
#include <string>
6
7
#include "cvmfs_config.h"
8
9
#include <cassert>
10
11
#include "logging.h"
12
#include "statistics_database.h"
13
#include "swissknife.h"
14
15
#include "swissknife_check.h"
16
#include "swissknife_diff.h"
17
#include "swissknife_gc.h"
18
#include "swissknife_graft.h"
19
#include "swissknife_hash.h"
20
#include "swissknife_history.h"
21
#include "swissknife_info.h"
22
#include "swissknife_ingest.h"
23
#include "swissknife_lease.h"
24
#include "swissknife_letter.h"
25
#include "swissknife_lsrepo.h"
26
#include "swissknife_migrate.h"
27
#include "swissknife_pull.h"
28
#include "swissknife_reflog.h"
29
#include "swissknife_scrub.h"
30
#include "swissknife_sign.h"
31
#include "swissknife_sync.h"
32
#include "swissknife_zpipe.h"
33
#include "util/posix.h"
34
#include "util/string.h"
35
36
using namespace std;  // NOLINT
37
38
typedef vector<swissknife::Command *> Commands;
39
Commands command_list;
40
41
void Usage() {
42
  LogCvmfs(kLogCvmfs, kLogStdout,
43
    "CernVM-FS repository storage management commands\n"
44
    "Version %s\n"
45
    "Usage (normally called from cvmfs_server):\n"
46
    "  cvmfs_swissknife <command> [options]\n",
47
    VERSION);
48
49
  for (unsigned i = 0; i < command_list.size(); ++i) {
50
    LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak, "\n"
51
             "Command %s\n"
52
             "--------", command_list[i]->GetName().c_str());
53
    for (unsigned j = 0; j < command_list[i]->GetName().length(); ++j) {
54
      LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak, "-");
55
    }
56
    LogCvmfs(kLogCvmfs, kLogStdout, "");
57
    LogCvmfs(kLogCvmfs, kLogStdout, "%s",
58
             command_list[i]->GetDescription().c_str());
59
    swissknife::ParameterList params = command_list[i]->GetParams();
60
    if (!params.empty()) {
61
      LogCvmfs(kLogCvmfs, kLogStdout, "Options:");
62
      for (unsigned j = 0; j < params.size(); ++j) {
63
        LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak, "  -%c    %s",
64
                 params[j].key(), params[j].description().c_str());
65
        if (params[j].optional())
66
          LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak, " (optional)");
67
        LogCvmfs(kLogCvmfs, kLogStdout, "");
68
      }
69
    }  // Parameter list
70
  }  // Command list
71
72
  LogCvmfs(kLogCvmfs, kLogStdout, "");
73
}
74
75
76
int main(int argc, char **argv) {
77
  command_list.push_back(new swissknife::CommandCreate());
78
  command_list.push_back(new swissknife::CommandUpload());
79
  command_list.push_back(new swissknife::CommandRemove());
80
  command_list.push_back(new swissknife::CommandPeek());
81
  command_list.push_back(new swissknife::CommandSync());
82
  command_list.push_back(new swissknife::CommandApplyDirtab());
83
  command_list.push_back(new swissknife::CommandEditTag());
84
  command_list.push_back(new swissknife::CommandListTags());
85
  command_list.push_back(new swissknife::CommandInfoTag());
86
  command_list.push_back(new swissknife::CommandRollbackTag());
87
  command_list.push_back(new swissknife::CommandEmptyRecycleBin());
88
  command_list.push_back(new swissknife::CommandSign());
89
  command_list.push_back(new swissknife::CommandLetter());
90
  command_list.push_back(new swissknife::CommandCheck());
91
  command_list.push_back(new swissknife::CommandListCatalogs());
92
  command_list.push_back(new swissknife::CommandDiff());
93
  command_list.push_back(new swissknife::CommandPull());
94
  command_list.push_back(new swissknife::CommandZpipe());
95
  command_list.push_back(new swissknife::CommandGraft());
96
  command_list.push_back(new swissknife::CommandHash());
97
  command_list.push_back(new swissknife::CommandInfo());
98
  command_list.push_back(new swissknife::CommandVersion());
99
  command_list.push_back(new swissknife::CommandMigrate());
100
  command_list.push_back(new swissknife::CommandScrub());
101
  command_list.push_back(new swissknife::CommandGc());
102
  command_list.push_back(new swissknife::CommandReconstructReflog());
103
  command_list.push_back(new swissknife::CommandLease());
104
  command_list.push_back(new swissknife::Ingest());
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(optarg,
165
                                         swissknife::
166
                                         Command::kGenericParamSeparator);
167
      for (unsigned i = 0; i < flags.size(); ++i) {
168
        if (flags[i] == "stats") {
169
          display_statistics = true;
170
        }
171
      }
172
    }
173
    if (!valid_option) {
174
      Usage();
175
      return 1;
176
    }
177
  }
178
  for (unsigned j = 0; j < params.size(); ++j) {
179
    if (!params[j].optional()) {
180
      if (args.find(params[j].key()) == args.end()) {
181
        LogCvmfs(kLogCvmfs, kLogStderr, "parameter -%c missing",
182
                 params[j].key());
183
        return 1;
184
      }
185
    }
186
  }
187
188
  // run the command
189
  string start_time = GetGMTimestamp();
190
  const int retval = command->Main(args);
191
  string finished_time = GetGMTimestamp();
192
193
  if (display_statistics) {
194
    LogCvmfs(kLogCvmfs, kLogStdout, "Command statistics");
195
    LogCvmfs(kLogCvmfs, kLogStdout, "%s",
196
             command->statistics()
197
             ->PrintList(perf::Statistics::kPrintHeader).c_str());
198
  }
199
200
  if (command->GetName() == "sync" || command->GetName() == "ingest"
201
      || (command->GetName() == "gc" && !(args.count('d') > 0))) {
202
    UniquePtr<StatisticsDatabase> db;
203
    string repo_name = "";
204
    if (args.find('N') != args.end()) {
205
      repo_name = *args.find('N')->second;
206
    } else if (args.find('n') != args.end()) {
207
      repo_name = *args.find('n')->second;
208
    }
209
210
    if (repo_name != "") {
211
      string db_file_path = StatisticsDatabase::GetDBPath(repo_name);
212
      if (FileExists(db_file_path)) {
213
        db = StatisticsDatabase::Open(db_file_path,
214
                                      StatisticsDatabase::kOpenReadWrite);
215
      } else {
216
        db = StatisticsDatabase::Create(db_file_path);
217
        // insert repo_name into properties table
218
        if (db.IsValid()) {
219
          if (!db->SetProperty("repo_name", repo_name)) {
220
            LogCvmfs(kLogCvmfs, kLogSyslogErr,
221
                "Couldn't insert repo_name into properties table!");
222
          }
223
        }
224
      }
225
226
      if (!db.IsValid()) {
227
        LogCvmfs(kLogCvmfs, kLogSyslogErr,
228
                "Couldn't create StatisticsDatabase object!");
229
      } else if (db->StoreStatistics(command->statistics(), start_time,
230
                                     finished_time, command->GetName(),
231
                                                             repo_name) != 0) {
232
        LogCvmfs(kLogCvmfs, kLogSyslogErr,
233
              "Couldn't store statistics in %s!",
234
              db_file_path.c_str());
235
      } else {
236
        LogCvmfs(kLogCvmfs, kLogStdout, "Statistics stored at: %s",
237
                                        db_file_path.c_str());
238
      }
239
    } else {
240
      LogCvmfs(kLogCvmfs, kLogSyslogErr,
241
                "Couldn't get repo_name!");
242
    }
243
  }
244
245
  // delete the command list
246
        Commands::const_iterator i    = command_list.begin();
247
  const Commands::const_iterator iend = command_list.end();
248
  for (; i != iend; ++i) {
249
    delete *i;
250
  }
251
  command_list.clear();
252
253
  return retval;
254
}