CernVM-FS  2.12.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
preload.cc
Go to the documentation of this file.
1 
5 #include "cvmfs_config.h"
6 
7 #include <stdio.h>
8 #include <sys/stat.h>
9 #include <unistd.h>
10 
11 #include <string>
12 
13 #include "compression.h"
14 #include "crypto/signature.h"
15 #include "network/download.h"
16 #include "statistics.h"
17 #include "swissknife.h"
18 #include "swissknife_pull.h"
19 #include "util/logging.h"
20 #include "util/posix.h"
21 #include "util/string.h"
22 #include "util/uuid.h"
23 
24 
25 using namespace std; // NOLINT
26 
27 const char *kVersion = VERSION;
28 const int kDefaultPreloaderTimeout = 10;
30 
31 namespace swissknife {
32 
33 void Usage() {
34  LogCvmfs(kLogCvmfs, kLogStderr, "Version: %s\n\n"
35  "Usage:\n"
36  "cvmfs_preload -u <Stratum 0 URL>\n"
37  " -r <alien cache directory>\n"
38  " [-d <path to dirtab file>]\n"
39  " [-k <public key>]\n"
40  " [-m <fully qualified repository name>]\n"
41  " [-n <num of parallel download threads>]\n"
42  " [-t <timeout in seconds (default %d)>]\n"
43  " [-a <number of retries (default %d)>]\n"
44  " [-x <directory for temporary files>]\n\n",
46 }
47 } // namespace swissknife
48 
49 const char gCernIt1PublicKey[] =
50  "-----BEGIN PUBLIC KEY-----\n"
51  "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo8uKvscgW7FNxzb65Uhm\n"
52  "yr8jPJiyrl2kVzb/hhgdfN14C0tCbfFoE6ciuZFg+9ytLeiL9pzM96gSC+atIFl4\n"
53  "7wTgtAFO1W4PtDQBwA/IG2bnwvNrzk19ob0JYhjZlS9tYKeh7TKCub55+vMwcEbP\n"
54  "urzo3WSNCzJngiGMh1vM5iSlGLpCdSGzdwxLGwc1VjRM7q3KAd7M7TJCynKqXZPX\n"
55  "R2xiD6I/p4xv39AnwphCFSmDh0MWE1WeeNHIiiveikvvN+l8d/ZNASIDhKNCsz6o\n"
56  "aFDsGXvjGy7dg43YzjSSYSFGUnONtl5Fe6y4bQZj1LEPbeInW334MAbMwYF4LKma\n"
57  "yQIDAQAB\n"
58  "-----END PUBLIC KEY-----\n";
59 
60 const char gCernIt4PublicKey[] =
61  "-----BEGIN PUBLIC KEY-----\n"
62  "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzlAraXimfJP5ie0KtDAE\n"
63  "rNUU5d9bzst+kqfhnb0U0OUtmCIbsueaDlbMmTdRSHMr+T0jI8i9CZxJwtxDqll+\n"
64  "UuB3Li2hYBhk0tYTy29JJYvofVULvrw1kMSLKyTWnV30/MHjYxhLHoZWfdepTjVg\n"
65  "lM0rP58K10wR3Z/AaaikOcy4z6P/MHs9ES1jdZqEBQEmmzKw5nf7pfU2QuVWJrKP\n"
66  "wZ9XeYDzipVbMc1zaLEK0slE+bm2ge/Myvuj/rpYKT+6qzbasQg62abGFuOrjgKI\n"
67  "X4/BVnilkhUfH6ssRKw4yehlKG1M5KJje2+y+iVvLbfoaw3g1Sjrf4p3Gq+ul7AC\n"
68  "PwIDAQAB\n"
69  "-----END PUBLIC KEY-----\n";
70 
71 const char gCernIt5PublicKey[] =
72  "-----BEGIN PUBLIC KEY-----\n"
73  "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqFzLLZAg2xmHJLbbq0+N\n"
74  "eYtjRDghUK5mYhARndnC3skFVowDTiqJVc9dIDX5zuxQ9HyC0iKM1HbvN64IH/Uf\n"
75  "qoXLyZLiXbFwpg6BtEJxwhijdZCiCC5PC//Bb7zSFIVZvWjndujr6ejaY6kx3+jI\n"
76  "sU1HSJ66pqorj+D1fbZCziLcWbS1GzceZ7aTYYPUdGZF1CgjBK5uKrEAoBsPgjWo\n"
77  "+YOEkjskY7swfhUzkCe0YyMyAaS0gsWgYrY2ebrpauFFqKxveKWjDVBTGcwDhiBX\n"
78  "60inUgD6CJXhUpvGHfU8V7Bv6l7dmyzhq/Bk2kRC92TIvxfaHRmS7nuknUY0hW6t\n"
79  "2QIDAQAB\n"
80  "-----END PUBLIC KEY-----\n";
81 
82 
83 static char CheckParameters(const string &params,
85  for (unsigned i = 0; i < params.length(); ++i) {
86  char param = params[i];
87  if (args->find(param) == args->end()) {
88  return param;
89  }
90  }
91  return '\0';
92 }
93 
94 static bool HasDirtabChanged(const string &dirtab_src, const string &dirtab_dst)
95 {
96  bool retval;
97  shash::Any hash_src(shash::kMd5);
98  shash::Any hash_dst(shash::kMd5);
99  retval = shash::HashFile(dirtab_src, &hash_src);
100  if (!retval)
101  return true;
102  retval = shash::HashFile(dirtab_dst, &hash_dst);
103  if (!retval)
104  return true;
105  return hash_src != hash_dst;
106 }
107 
108 
109 int main(int argc, char *argv[]) {
110  int retval;
111 
112  // load some default arguments
114  args['n'].Reset(new string("4"));
115 
116  string option_string = "u:r:k:m:x:d:n:t:a:vh";
117  int c;
118  while ((c = getopt(argc, argv, option_string.c_str())) != -1) {
119  if ((c == 'v') || (c == 'h')) {
121  return 0;
122  }
123  args[c].Reset(new string(optarg));
124  }
125 
126  // check all mandatory parameters are included
127  string necessary_params = "ur";
128  char result;
129  if ((result = CheckParameters(necessary_params, &args)) != '\0') {
130  printf("Argument not included but necessary: -%c\n\n", result);
132  return 2;
133  }
134 
135  if (args.find('m') == args.end()) {
136  string fqrn = GetFileName(*args['u']);
137  LogCvmfs(kLogCvmfs, kLogStdout, "CernVM-FS: guessing fqrn from URL: %s",
138  fqrn.c_str());
139  args['m'].Reset(new string(fqrn));
140  }
141 
142  if (args.find('x') == args.end())
143  args['x'].Reset(new string(*args['r'] + "/txn"));
144 
145  const string cache_directory = *args['r'];
146  const string fqrn = *args['m'];
147  const string dirtab =
148  (args.find('d') == args.end()) ? "/dev/null" : *args['d'];
149  const string dirtab_in_cache = cache_directory + "/dirtab." + fqrn;
150 
151  // Default network parameters: 5 seconds timeout, 2 retries
152  if (args.find('t') == args.end())
153  args['t'].Reset(new string(StringifyInt(kDefaultPreloaderTimeout)));
154  if (args.find('a') == args.end())
155  args['a'].Reset(new string(StringifyInt(kDefaultPreloaderRetries)));
156 
157  // first create the alien cache
158  const string& alien_cache_dir = *(args['r']);
159  retval = MkdirDeep(alien_cache_dir, 0770);
160  if (!retval) {
161  LogCvmfs(kLogCvmfs, kLogStderr, "Failed to create %s",
162  alien_cache_dir.c_str());
163  return 1;
164  }
165  retval = MakeCacheDirectories(alien_cache_dir, 0770);
166  if (!retval) {
167  LogCvmfs(kLogCvmfs, kLogStderr, "Failed to create cache skeleton");
168  return 1;
169  }
170 
171  // if there is no specified public key file we dump the cern.ch public key in
172  // the temporary directory
173  string cern_pk_base_path = *args['x'];
174  string cern_pk_it1_path = cern_pk_base_path + "/cern-it1.cern.ch.pub";
175  string cern_pk_it4_path = cern_pk_base_path + "/cern-it4.cern.ch.pub";
176  string cern_pk_it5_path = cern_pk_base_path + "/cern-it5.cern.ch.pub";
177  bool keys_created = false;
178  if (args.find('k') == args.end()) {
179  keys_created = true;
181  reinterpret_cast<const unsigned char*>(gCernIt1PublicKey),
182  sizeof(gCernIt1PublicKey), cern_pk_it1_path));
184  reinterpret_cast<const unsigned char*>(gCernIt4PublicKey),
185  sizeof(gCernIt4PublicKey), cern_pk_it4_path));
187  reinterpret_cast<const unsigned char*>(gCernIt5PublicKey),
188  sizeof(gCernIt5PublicKey), cern_pk_it5_path));
189  char path_separator = ':';
190  args['k'].Reset(new string(cern_pk_it1_path + path_separator +
191  cern_pk_it4_path + path_separator +
192  cern_pk_it5_path));
193  }
194 
195  // now launch swissknife_pull
196  // load the command
197  if (HasDirtabChanged(dirtab, dirtab_in_cache)) {
198  LogCvmfs(kLogCvmfs, kLogStdout, "CernVM-FS: new dirtab, forced run");
199  args['z'].Reset(); // look into existing catalogs, too
200  }
201  args['c'].Reset();
202  retval = swissknife::CommandPull().Main(args);
203 
204  // Copy dirtab file
205  if (retval == 0) {
206  CopyPath2Path(dirtab, dirtab_in_cache);
207  }
208 
209  // Create cache uuid if not present
210  cvmfs::Uuid *uuid = cvmfs::Uuid::Create(cache_directory + "/uuid");
211  if (uuid == NULL) {
212  LogCvmfs(kLogCvmfs, kLogStderr, "Warning: failed to create %s/uuid",
213  cache_directory.c_str());
214  }
215  delete uuid;
216 
217  if (keys_created) {
218  unlink(cern_pk_it1_path.c_str());
219  unlink(cern_pk_it4_path.c_str());
220  unlink(cern_pk_it5_path.c_str());
221  }
222 
223  return retval;
224 }
bool MakeCacheDirectories(const std::string &path, const mode_t mode)
Definition: posix.cc:882
int Main(const ArgumentList &args)
NameString GetFileName(const PathString &path)
Definition: shortstring.cc:29
bool HashFile(const std::string &filename, Any *any_digest)
Definition: hash.cc:342
assert((mem||(size==0))&&"Out Of Memory")
bool CopyPath2Path(const string &src, const string &dest)
Definition: compression.cc:63
const char gCernIt1PublicKey[]
Definition: preload.cc:49
int main()
Definition: helper_allow.cc:16
bool CopyMem2Path(const unsigned char *buffer, const unsigned buffer_size, const string &path)
Definition: compression.cc:94
static char CheckParameters(const string &params, swissknife::ArgumentList *args)
Definition: preload.cc:83
const int kDefaultPreloaderTimeout
Definition: preload.cc:28
bool MkdirDeep(const std::string &path, const mode_t mode, bool verify_writable)
Definition: posix.cc:846
void Usage()
string StringifyInt(const int64_t value)
Definition: string.cc:78
const char gCernIt5PublicKey[]
Definition: preload.cc:71
static Uuid * Create(const std::string &store_path)
Definition: uuid.cc:23
static bool HasDirtabChanged(const string &dirtab_src, const string &dirtab_dst)
Definition: preload.cc:94
std::map< char, SharedPtr< std::string > > ArgumentList
Definition: swissknife.h:72
const int kDefaultPreloaderRetries
Definition: preload.cc:29
const char * kVersion
Definition: preload.cc:27
void Usage()
Definition: preload.cc:33
const char gCernIt4PublicKey[]
Definition: preload.cc:60
CVMFS_EXPORT void LogCvmfs(const LogSource source, const int mask, const char *format,...)
Definition: logging.cc:528