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