CernVM-FS  2.13.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
manifest.cc
Go to the documentation of this file.
1 
5 #include "manifest.h"
6 
7 #include <cstdio>
8 #include <map>
9 #include <vector>
10 
11 #include "catalog.h"
12 #include "util/posix.h"
13 #include "util/string.h"
14 
15 using namespace std; // NOLINT
16 
17 namespace manifest {
18 
19 Breadcrumb::Breadcrumb(const std::string &from_string) {
20  timestamp = 0;
21  revision = 0; // for backward compatibility: no revision --> revision = 0
22 
23  if (from_string.empty()) {
24  return;
25  }
26 
27  // Separate hash from timestamp
28  std::vector<std::string> vec_split_timestamp = SplitString(from_string, 'T');
29 
30  catalog_hash = shash::MkFromHexPtr(shash::HexPtr(vec_split_timestamp[0]),
32 
33  if (vec_split_timestamp.size() > 1) {
34  // check if revision number is included
35  std::vector<std::string> vec_split_revision = SplitString(
36  vec_split_timestamp[1], 'R');
37 
38  // Get local last modified time
39  timestamp = String2Uint64(vec_split_revision[0]);
40 
41  // Get local revision
42  if (vec_split_revision.size() > 1) {
43  revision = String2Uint64(vec_split_revision[1]);
44  }
45  }
46 }
47 
48 bool Breadcrumb::Export(const string &fqrn, const string &directory,
49  const int mode) const {
50  string breadcrumb_path = MakeCanonicalPath(directory) + "/cvmfschecksum."
51  + fqrn;
52  string tmp_path;
53  FILE *fbreadcrumb = CreateTempFile(breadcrumb_path, mode, "w", &tmp_path);
54  if (fbreadcrumb == NULL)
55  return false;
56  string str_breadcrumb = ToString();
57  int written = fwrite(&(str_breadcrumb[0]), 1, str_breadcrumb.length(),
58  fbreadcrumb);
59  fclose(fbreadcrumb);
60  if (static_cast<unsigned>(written) != str_breadcrumb.length()) {
61  unlink(tmp_path.c_str());
62  return false;
63  }
64  int retval = rename(tmp_path.c_str(), breadcrumb_path.c_str());
65  if (retval != 0) {
66  unlink(tmp_path.c_str());
67  return false;
68  }
69  return true;
70 }
71 
72 std::string Breadcrumb::ToString() const {
73  return catalog_hash.ToString() + "T"
74  + StringifyInt(static_cast<int64_t>(timestamp)) + "R"
75  + StringifyUint(revision);
76 }
77 
78 
79 //------------------------------------------------------------------------------
80 
81 
82 Manifest *Manifest::LoadMem(const unsigned char *buffer,
83  const unsigned length) {
84  map<char, string> content;
85  ParseKeyvalMem(buffer, length, &content);
86 
87  return Load(content);
88 }
89 
90 
91 Manifest *Manifest::LoadFile(const std::string &from_path) {
92  map<char, string> content;
93  if (!ParseKeyvalPath(from_path, &content))
94  return NULL;
95 
96  return Load(content);
97 }
98 
99 
100 Manifest *Manifest::Load(const map<char, string> &content) {
101  map<char, string>::const_iterator iter;
102 
103  // Required keys
104  shash::Any catalog_hash;
105  shash::Md5 root_path;
106  uint32_t ttl;
107  uint64_t revision;
108 
109  iter = content.find('C');
110  if ((iter = content.find('C')) == content.end())
111  return NULL;
112  catalog_hash = MkFromHexPtr(shash::HexPtr(iter->second),
114  if ((iter = content.find('R')) == content.end())
115  return NULL;
116  root_path = shash::Md5(shash::HexPtr(iter->second));
117  if ((iter = content.find('D')) == content.end())
118  return NULL;
119  ttl = String2Uint64(iter->second);
120  if ((iter = content.find('S')) == content.end())
121  return NULL;
122  revision = String2Uint64(iter->second);
123 
124 
125  // Optional keys
126  uint64_t catalog_size = 0;
127  shash::Any micro_catalog_hash;
128  string repository_name;
129  shash::Any certificate;
131  uint64_t publish_timestamp = 0;
132  bool garbage_collectable = false;
133  bool has_alt_catalog_path = false;
135  shash::Any reflog_hash;
136 
137  if ((iter = content.find('B')) != content.end())
138  catalog_size = String2Uint64(iter->second);
139  if ((iter = content.find('L')) != content.end())
140  micro_catalog_hash = MkFromHexPtr(shash::HexPtr(iter->second),
142  if ((iter = content.find('N')) != content.end())
143  repository_name = iter->second;
144  if ((iter = content.find('X')) != content.end())
145  certificate = MkFromHexPtr(shash::HexPtr(iter->second),
147  if ((iter = content.find('H')) != content.end())
148  history = MkFromHexPtr(shash::HexPtr(iter->second), shash::kSuffixHistory);
149  if ((iter = content.find('T')) != content.end())
150  publish_timestamp = String2Uint64(iter->second);
151  if ((iter = content.find('G')) != content.end())
152  garbage_collectable = (iter->second == "yes");
153  if ((iter = content.find('A')) != content.end())
154  has_alt_catalog_path = (iter->second == "yes");
155  if ((iter = content.find('M')) != content.end())
156  meta_info = MkFromHexPtr(shash::HexPtr(iter->second),
158  if ((iter = content.find('Y')) != content.end()) {
159  reflog_hash = MkFromHexPtr(shash::HexPtr(iter->second));
160  }
161 
162  return new Manifest(catalog_hash, catalog_size, root_path, ttl, revision,
163  micro_catalog_hash, repository_name, certificate, history,
164  publish_timestamp, garbage_collectable,
165  has_alt_catalog_path, meta_info, reflog_hash);
166 }
167 
168 
169 Manifest::Manifest(const shash::Any &catalog_hash,
170  const uint64_t catalog_size,
171  const string &root_path)
172  : catalog_hash_(catalog_hash)
173  , catalog_size_(catalog_size)
174  , root_path_(shash::Md5(shash::AsciiPtr(root_path)))
175  , ttl_(catalog::Catalog::kDefaultTTL)
176  , revision_(0)
177  , publish_timestamp_(0)
178  , garbage_collectable_(false)
179  , has_alt_catalog_path_(false) { }
180 
181 
185 string Manifest::ExportString() const {
186  string manifest = "C" + catalog_hash_.ToString() + "\n" + "B"
187  + StringifyInt(catalog_size_) + "\n" + "R"
188  + root_path_.ToString() + "\n" + "D" + StringifyInt(ttl_)
189  + "\n" + "S" + StringifyInt(revision_) + "\n" + "G"
190  + StringifyBool(garbage_collectable_) + "\n" + "A"
192 
194  manifest += "L" + micro_catalog_hash_.ToString() + "\n";
195  if (repository_name_ != "")
196  manifest += "N" + repository_name_ + "\n";
197  if (!certificate_.IsNull())
198  manifest += "X" + certificate_.ToString() + "\n";
199  if (!history_.IsNull())
200  manifest += "H" + history_.ToString() + "\n";
201  if (publish_timestamp_ > 0)
202  manifest += "T" + StringifyInt(publish_timestamp_) + "\n";
203  if (!meta_info_.IsNull())
204  manifest += "M" + meta_info_.ToString() + "\n";
205  if (!reflog_hash_.IsNull()) {
206  manifest += "Y" + reflog_hash_.ToString() + "\n";
207  }
208  // Reserved: Z -> for identification of channel tips
209 
210  return manifest;
211 }
212 
213 
217 bool Manifest::Export(const std::string &path) const {
218  FILE *fmanifest = fopen(path.c_str(), "w");
219  if (!fmanifest)
220  return false;
221 
222  string manifest = ExportString();
223 
224  if (fwrite(manifest.data(), 1, manifest.length(), fmanifest)
225  != manifest.length()) {
226  fclose(fmanifest);
227  unlink(path.c_str());
228  return false;
229  }
230  fclose(fmanifest);
231 
232  return true;
233 }
234 
235 
239 bool Manifest::ExportBreadcrumb(const string &directory, const int mode) const {
241  .Export(repository_name_, directory, mode);
242 }
243 
244 
249 Breadcrumb Manifest::ReadBreadcrumb(const std::string &repo_name,
250  const std::string &directory) {
251  Breadcrumb breadcrumb;
252  const string breadcrumb_path = directory + "/cvmfschecksum." + repo_name;
253  FILE *fbreadcrumb = fopen(breadcrumb_path.c_str(), "r");
254  if (!fbreadcrumb) {
255  // Return invalid breadcrumb if not found
256  return breadcrumb;
257  }
258  char tmp[164];
259  const size_t read_bytes = fread(tmp, 1, 164, fbreadcrumb);
260  if (read_bytes > 0) {
261  breadcrumb = Breadcrumb(std::string(tmp, read_bytes));
262  }
263  fclose(fbreadcrumb);
264 
265  return breadcrumb;
266 }
267 
268 } // namespace manifest
bool IsNull() const
Definition: hash.h:371
shash::Any micro_catalog_hash_
Definition: manifest.h:152
const manifest::Manifest * manifest() const
Definition: repository.h:125
bool Export(const std::string &path) const
Definition: manifest.cc:217
shash::Any meta_info_
Definition: manifest.h:170
shash::Any certificate_
Definition: manifest.h:154
shash::Md5 root_path_
Definition: manifest.h:149
FILE * CreateTempFile(const std::string &path_prefix, const int mode, const char *open_flags, std::string *final_path)
Definition: posix.cc:1013
const char kSuffixCertificate
Definition: hash.h:59
std::string ToString(const bool with_suffix=false) const
Definition: hash.h:241
const history::History * history() const
bool garbage_collectable_
Definition: manifest.h:157
const char kSuffixMicroCatalog
Definition: hash.h:56
std::string ExportString() const
Definition: manifest.cc:185
shash::Any reflog_hash_
Definition: manifest.h:175
std::string StringifyUint(const uint64_t value)
Definition: string.cc:83
string StringifyBool(const bool value)
Definition: string.cc:75
uint64_t revision_
Definition: manifest.h:151
bool ExportBreadcrumb(const std::string &directory, const int mode) const
Definition: manifest.cc:239
vector< string > SplitString(const string &str, char delim)
Definition: string.cc:306
const char kSuffixCatalog
Definition: hash.h:54
string StringifyInt(const int64_t value)
Definition: string.cc:77
const char kSuffixMetainfo
Definition: hash.h:60
bool has_alt_catalog_path_
Definition: manifest.h:164
bool Export(const std::string &fqrn, const std::string &directory, const int mode) const
Definition: manifest.cc:48
std::string repository_name_
Definition: manifest.h:153
const char kSuffixHistory
Definition: hash.h:55
uint64_t String2Uint64(const string &value)
Definition: string.cc:240
bool ParseKeyvalPath(const string &filename, map< char, string > *content)
Definition: string.cc:399
Any MkFromHexPtr(const HexPtr hex, const char suffix)
Definition: hash.cc:82
std::string meta_info() const
Definition: repository.h:128
static Breadcrumb ReadBreadcrumb(const std::string &repo_name, const std::string &directory)
Definition: manifest.cc:249
shash::Any catalog_hash_
Definition: manifest.h:147
shash::Any history_
Definition: manifest.h:155
std::string MakeCanonicalPath(const std::string &path)
Definition: posix.cc:98
uint64_t publish_timestamp_
Definition: manifest.h:156
uint64_t catalog_size_
Definition: manifest.h:148
void ParseKeyvalMem(const unsigned char *buffer, const unsigned buffer_size, map< char, string > *content)
Definition: string.cc:369