CernVM-FS  2.12.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
swissknife_list_reflog.cc
Go to the documentation of this file.
1 
8 #include "cvmfs_config.h"
10 
11 #include "manifest.h"
12 #include "object_fetcher.h"
13 #include "reflog.h"
14 #include "util/posix.h"
15 #include "util/string.h"
16 
17 using namespace std; // NOLINT
18 
19 namespace swissknife {
20 
21 ParameterList CommandListReflog::GetParams() const {
22  ParameterList r;
23  r.push_back(Parameter::Mandatory('r', "repository url / local storage path"));
24  r.push_back(Parameter::Mandatory('n', "fully qualified repository name"));
25  r.push_back(Parameter::Optional('R', "path to reflog.chksum file"));
26  r.push_back(Parameter::Optional('k', "repository master key(s) / dir"));
27  r.push_back(Parameter::Optional('t', "temporary directory"));
28  r.push_back(Parameter::Optional('o', "output file"));
29  r.push_back(Parameter::Optional('@', "proxy url"));
30  return r;
31 }
32 
33 int CommandListReflog::Main(const ArgumentList &args) {
34  const string &repo_url = *args.find('r')->second;
35  const string &repo_name = *args.find('n')->second;
36  const std::string &reflog_chksum_path = (args.count('R') > 0) ?
37  *args.find('R')->second : "";
38  string repo_keys = (args.count('k') > 0) ?
39  *args.find('k')->second : "";
40  if (DirectoryExists(repo_keys))
41  repo_keys = JoinStrings(FindFilesBySuffix(repo_keys, ".pub"), ":");
42  const string temp_directory = (args.count('t') > 0) ?
43  *args.find('t')->second : "/tmp";
44  const string output_path = (args.count('o') > 0) ?
45  *args.find('o')->second : "";
46 
47  shash::Any reflog_hash;
48  if (reflog_chksum_path != "") {
49  if (!manifest::Reflog::ReadChecksum(reflog_chksum_path, &reflog_hash)) {
50  LogCvmfs(kLogCvmfs, kLogStderr, "Could not read reflog checksum");
51  return 1;
52  }
53  }
54 
55  const bool follow_redirects = false;
56  const string proxy = (args.count('@') > 0) ? *args.find('@')->second : "";
57  if (!this->InitDownloadManager(follow_redirects, proxy) ||
58  !this->InitVerifyingSignatureManager(repo_keys)) {
59  LogCvmfs(kLogCvmfs, kLogStderr, "failed to init repo connection");
60  return 1;
61  }
62 
63  bool success;
64  if (IsHttpUrl(repo_url)) {
65  HttpObjectFetcher<> object_fetcher(repo_name,
66  repo_url,
67  temp_directory,
68  download_manager(),
69  signature_manager());
70  if (reflog_hash.IsNull()) {
73  switch (failure = object_fetcher.FetchManifest(&manifest)) {
75  reflog_hash = manifest->reflog_hash();
76  break;
77  default:
78  LogCvmfs(kLogCvmfs, kLogStderr, "Failed to fetch manifest: %s",
79  Code2Ascii(failure));
80  return 1;
81  }
82  }
83  success = Run(&object_fetcher, repo_name, output_path, reflog_hash);
84  } else {
85  LocalObjectFetcher<> object_fetcher(repo_url, temp_directory);
86  success = Run(&object_fetcher, repo_name, output_path, reflog_hash);
87  }
88 
89  return (success) ? 0 : 1;
90 }
91 
92 template <class ObjectFetcherT>
93 bool CommandListReflog::Run(ObjectFetcherT *object_fetcher, string repo_name,
94  string output_path, shash::Any reflog_hash)
95 {
96  typename ObjectFetcherT::ReflogTN *reflog;
97  reflog = FetchReflog(object_fetcher, repo_name, reflog_hash);
98 
99  shash::Any null_hash = shash::Any(reflog_hash.algorithm);
100  objects_ = new SmallHashDynamic<shash::Any, bool>;
101  objects_->Init(1024, null_hash, hasher);
102 
103  // Traverse through catalogs and regular objects
104  vector<shash::Any> catalogs;
105  if (NULL == reflog || !reflog->List(SqlReflog::kRefCatalog, &catalogs)) {
106  LogCvmfs(kLogCvmfs, kLogStderr, "Failed to list catalog reference log");
107  return false;
108  }
109  typename CatalogTraversal<ObjectFetcherT>::Parameters traversal_params;
110  traversal_params.object_fetcher = object_fetcher;
111  CatalogTraversal<ObjectFetcherT> traversal(traversal_params);
112  traversal.RegisterListener(
114  this);
115  bool success = true;
116  vector<shash::Any>::iterator i = catalogs.begin();
117  const vector<shash::Any>::const_iterator iend = catalogs.end();
118  for (; i != iend && success; i++) {
119  success &= traversal.TraverseRevision(*i,
121  }
122 
123  if (!success) {
125  "Catalog traversal aborted due to an error");
126  return false;
127  }
128 
129  // Add history, certificate, metainfo objects from reflog
130  vector<shash::Any> histories, certificates, metainfos;
131  if (!reflog->List(SqlReflog::kRefHistory, &histories)) {
133  "Failed to fetch history objects from reflog");
134  return false;
135  }
136  if (!reflog->List(SqlReflog::kRefCertificate, &certificates)) {
138  "Failed to fetch certificate objects from reflog");
139  return false;
140  }
141  if (!reflog->List(SqlReflog::kRefMetainfo, &metainfos)) {
143  "Failed to fetch metainfo objects from reflog");
144  return false;
145  }
146  InsertObjects(histories);
147  InsertObjects(certificates);
148  InsertObjects(metainfos);
149 
150  // Clean up reflog file
151  delete reflog;
152 
153  LogCvmfs(kLogCvmfs, kLogStderr, "Number of objects: %u", objects_->size());
154 
155  if (output_path == "") {
156  DumpObjects(stdout);
157  } else {
158  int fd = open(output_path.c_str(), O_WRONLY | O_CREAT, 0644);
159  assert(fd);
160  FILE *stream = fdopen(fd, "w");
161  DumpObjects(stream);
162  fclose(stream); // no need to call close after fclose
163  }
164 
165  return success;
166 }
167 
168 void CommandListReflog::CatalogCallback(
170 {
171  LogCvmfs(kLogCvmfs, kLogStderr, "Processing catalog \"%s\"",
172  data.catalog->mountpoint().c_str());
173  const catalog::Catalog::HashVector &referenced_hashes =
175  InsertObjects(referenced_hashes);
176  if (data.catalog->hash() != objects_->empty_key())
177  objects_->Insert(data.catalog->hash(), true);
178 }
179 
180 void CommandListReflog::InsertObjects(const vector<shash::Any> &list) {
181  vector<shash::Any>::const_iterator i = list.begin();
182  const vector<shash::Any>::const_iterator iend = list.end();
183  for (; i != iend; ++i) {
184  if ((*i) != objects_->empty_key())
185  objects_->Insert(*i, true);
186  }
187 }
188 
189 void CommandListReflog::DumpObjects(FILE *stream)
190 {
191  shash::Any empty_key = objects_->empty_key();
192  shash::Any *hashes = objects_->keys();
193  for (uint32_t i = 0; i < objects_->capacity(); ++i) {
194  if (hashes[i] != empty_key) {
195  fprintf(stream, "%s\n", hashes[i].ToString().c_str());
196  }
197  }
198 }
199 
200 } // namespace swissknife
const char * Code2Ascii(const ObjectFetcherFailures::Failures error)
CallbackPtr RegisterListener(typename BoundClosure< CatalogTraversalData< ObjectFetcherT::CatalogTN >, DelegateT, ClosureDataT >::CallbackMethod method, DelegateT *delegate, ClosureDataT data)
bool IsNull() const
Definition: hash.h:383
const manifest::Manifest * manifest() const
Definition: repository.h:125
void CatalogCallback(const CatalogTraversalData< catalog::Catalog > &data)
static bool ReadChecksum(const std::string &path, shash::Any *checksum)
Definition: reflog.cc:47
std::vector< Parameter > ParameterList
Definition: swissknife.h:71
string JoinStrings(const vector< string > &strings, const string &joint)
Definition: string.cc:325
bool IsHttpUrl(const std::string &path)
Definition: posix.cc:168
assert((mem||(size==0))&&"Out Of Memory")
Algorithms algorithm
Definition: hash.h:125
std::vector< shash::Any > HashVector
Definition: catalog.h:97
const HashVector & GetReferencedObjects() const
Definition: catalog.cc:464
PathString mountpoint() const
Definition: catalog.h:179
bool DirectoryExists(const std::string &path)
Definition: posix.cc:813
bool TraverseRevision(const shash::Any &root_catalog_hash, const TraversalType type=Base::kBreadthFirst)
std::map< char, SharedPtr< std::string > > ArgumentList
Definition: swissknife.h:72
Failures FetchManifest(manifest::Manifest **manifest)
shash::Any reflog_hash() const
Definition: manifest.h:140
shash::Any hash() const
Definition: catalog.h:186
void Init(uint32_t expected_size, Key empty, uint32_t(*hasher)(const Key &key))
Definition: smallhash.h:60
const char * c_str() const
Definition: shortstring.h:145
std::vector< std::string > FindFilesBySuffix(const std::string &dir, const std::string &suffix)
Definition: posix.cc:1124
CVMFS_EXPORT void LogCvmfs(const LogSource source, const int mask, const char *format,...)
Definition: logging.cc:528