1 |
|
|
/** |
2 |
|
|
* This file is part of the CernVM File System. |
3 |
|
|
*/ |
4 |
|
|
|
5 |
|
|
#define __STDC_FORMAT_MACROS |
6 |
|
|
|
7 |
|
|
#include "swissknife_diff.h" |
8 |
|
|
#include "cvmfs_config.h" |
9 |
|
|
|
10 |
|
|
#include <inttypes.h> |
11 |
|
|
#include <stdint.h> |
12 |
|
|
|
13 |
|
|
#include <algorithm> |
14 |
|
|
#include <cassert> |
15 |
|
|
#include <string> |
16 |
|
|
#include <vector> |
17 |
|
|
|
18 |
|
|
#include "catalog.h" |
19 |
|
|
#include "catalog_counters.h" |
20 |
|
|
#include "catalog_mgr_ro.h" |
21 |
|
|
#include "download.h" |
22 |
|
|
#include "statistics.h" |
23 |
|
|
#include "swissknife_assistant.h" |
24 |
|
|
#include "swissknife_diff_tool.h" |
25 |
|
|
#include "util/pointer.h" |
26 |
|
|
#include "util/posix.h" |
27 |
|
|
#include "util/string.h" |
28 |
|
|
|
29 |
|
|
using namespace std; // NOLINT |
30 |
|
|
|
31 |
|
|
namespace swissknife { |
32 |
|
|
CommandDiff::~CommandDiff() {} |
33 |
|
|
|
34 |
|
|
ParameterList CommandDiff::GetParams() const { |
35 |
|
|
swissknife::ParameterList r; |
36 |
|
|
r.push_back(Parameter::Mandatory('r', "repository url")); |
37 |
|
|
r.push_back(Parameter::Mandatory('n', "repository name")); |
38 |
|
|
r.push_back(Parameter::Mandatory('k', "public key of the repository / dir")); |
39 |
|
|
r.push_back(Parameter::Mandatory('t', "directory for temporary files")); |
40 |
|
|
r.push_back(Parameter::Optional('s', "'from' tag name")); |
41 |
|
|
r.push_back(Parameter::Optional('d', "'to' tag name")); |
42 |
|
|
r.push_back(Parameter::Switch('m', "machine readable output")); |
43 |
|
|
r.push_back(Parameter::Switch('h', "show header")); |
44 |
|
|
// Used for testing |
45 |
|
|
r.push_back(Parameter::Switch('i', "ignore time stamp differences")); |
46 |
|
|
r.push_back(Parameter::Switch('L', "follow HTTP redirects")); |
47 |
|
|
return r; |
48 |
|
|
} |
49 |
|
|
|
50 |
|
|
|
51 |
|
|
history::History::Tag CommandDiff::GetTag(const string &tag_name) { |
52 |
|
|
history::History::Tag tag; |
53 |
|
|
if (tag_name.empty()) |
54 |
|
|
return tag; |
55 |
|
|
|
56 |
|
|
if (tag_name[0] == kRawHashSymbol) { |
57 |
|
|
tag.name = tag_name.substr(1); |
58 |
|
|
tag.root_hash = |
59 |
|
|
shash::MkFromHexPtr(shash::HexPtr(tag.name), shash::kSuffixCatalog); |
60 |
|
|
} else { |
61 |
|
|
bool retval = history_->GetByName(tag_name, &tag); |
62 |
|
|
if (!retval) { |
63 |
|
|
LogCvmfs(kLogCvmfs, kLogStderr, "unknown tag: s", tag_name.c_str()); |
64 |
|
|
} |
65 |
|
|
} |
66 |
|
|
|
67 |
|
|
return tag; |
68 |
|
|
} |
69 |
|
|
|
70 |
|
|
|
71 |
|
|
int swissknife::CommandDiff::Main(const swissknife::ArgumentList &args) { |
72 |
|
|
const string fqrn = MakeCanonicalPath(*args.find('n')->second); |
73 |
|
|
const string tmp_dir = MakeCanonicalPath(*args.find('t')->second); |
74 |
|
|
const string repository = MakeCanonicalPath(*args.find('r')->second); |
75 |
|
|
const bool show_header = args.count('h') > 0; |
76 |
|
|
const bool machine_readable = args.count('m') > 0; |
77 |
|
|
const bool ignore_timediff = args.count('i') > 0; |
78 |
|
|
const bool follow_redirects = args.count('L') > 0; |
79 |
|
|
string pubkey_path = *args.find('k')->second; |
80 |
|
|
if (DirectoryExists(pubkey_path)) |
81 |
|
|
pubkey_path = JoinStrings(FindFilesBySuffix(pubkey_path, ".pub"), ":"); |
82 |
|
|
string tagname_from = "trunk-previous"; |
83 |
|
|
string tagname_to = "trunk"; |
84 |
|
|
if (args.count('s') > 0) tagname_from = *args.find('s')->second; |
85 |
|
|
if (args.count('d') > 0) tagname_to = *args.find('d')->second; |
86 |
|
|
|
87 |
|
|
bool retval = this->InitDownloadManager(follow_redirects); |
88 |
|
|
assert(retval); |
89 |
|
|
if (!InitVerifyingSignatureManager(pubkey_path)) { |
90 |
|
|
LogCvmfs(kLogCvmfs, kLogStderr, |
91 |
|
|
"Error calling InitVerifyingSignatureManager"); |
92 |
|
|
return 1; |
93 |
|
|
} |
94 |
|
|
UniquePtr<manifest::Manifest> manifest(FetchRemoteManifest(repository, fqrn)); |
95 |
|
|
assert(manifest.IsValid()); |
96 |
|
|
|
97 |
|
|
Assistant assistant(download_manager(), manifest, repository, tmp_dir); |
98 |
|
|
history_ = assistant.GetHistory(Assistant::kOpenReadOnly); |
99 |
|
|
assert(history_.IsValid()); |
100 |
|
|
history::History::Tag tag_from = GetTag(tagname_from); |
101 |
|
|
if (tag_from.root_hash.IsNull()) return 1; |
102 |
|
|
history::History::Tag tag_to = GetTag(tagname_to); |
103 |
|
|
if (tag_to.root_hash.IsNull()) return 1; |
104 |
|
|
|
105 |
|
|
DiffTool diff_tool(repository, tag_from, tag_to, tmp_dir, download_manager(), |
106 |
|
|
statistics(), machine_readable, ignore_timediff); |
107 |
|
|
if (!diff_tool.Init()) { |
108 |
|
|
return 1; |
109 |
|
|
} |
110 |
|
|
|
111 |
|
|
if (show_header) diff_tool.ReportHeader(); |
112 |
|
|
diff_tool.ReportStats(); |
113 |
|
|
diff_tool.Run(PathString("")); |
114 |
|
|
|
115 |
|
|
return 0; |
116 |
|
|
} |
117 |
|
|
|
118 |
|
|
} // namespace swissknife |