GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/server_tool.cc
Date: 2026-08-23 02:40:52
Exec Total Coverage
Lines: 19 81 23.5%
Branches: 12 102 11.8%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4
5 #include "server_tool.h"
6
7 #include "util/posix.h"
8
9
1/2
✓ Branch 3 taken 685 times.
✗ Branch 4 not taken.
685 ServerTool::ServerTool() { }
10
11 1516 ServerTool::~ServerTool() {
12
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 684 times.
1368 if (signature_manager_.get() != nullptr) {
13 signature_manager_->Fini();
14 }
15 1516 }
16
17 685 bool ServerTool::InitDownloadManager(const bool follow_redirects,
18 const std::string &proxy,
19 const unsigned max_pool_handles) {
20
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 685 times.
685 if (download_manager_.get() != nullptr) {
21 return true;
22 }
23
24
1/2
✓ Branch 1 taken 685 times.
✗ Branch 2 not taken.
2055 download_manager_ = std::unique_ptr<download::DownloadManager>(
25 new download::DownloadManager(
26 max_pool_handles,
27
4/8
✓ Branch 3 taken 685 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 685 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 685 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 685 times.
✗ Branch 14 not taken.
2740 perf::StatisticsTemplate("download", statistics())));
28
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 685 times.
685 assert(download_manager_.get() != nullptr);
29
30 685 download_manager_->SetTimeout(kDownloadTimeout, kDownloadTimeout);
31 685 download_manager_->SetRetryParameters(kDownloadRetries, 2000, 5000);
32 685 download_manager_->UseSystemCertificatePath();
33
34
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 685 times.
685 if (proxy != "") {
35 download_manager_->SetProxyChain(proxy, "",
36 download::DownloadManager::kSetProxyBoth);
37 }
38
39
1/2
✓ Branch 0 taken 685 times.
✗ Branch 1 not taken.
685 if (follow_redirects) {
40 685 download_manager_->EnableRedirects();
41 }
42
43 685 return true;
44 }
45
46 bool ServerTool::InitSignatureManager(const std::string &pubkey_path,
47 const std::string &certificate_path,
48 const std::string &private_key_path) {
49 if (signature_manager_.get() != nullptr) {
50 return true;
51 }
52
53 signature_manager_ = std::unique_ptr<signature::SignatureManager>(
54 new signature::SignatureManager());
55 assert(signature_manager_.get() != nullptr);
56 signature_manager_->Init();
57
58 // We may not have a public key. In this case, the signature manager
59 // can only be used for signing, not for verification.
60 if (!pubkey_path.empty()) {
61 if (!signature_manager_->LoadPublicRsaKeys(pubkey_path)) {
62 LogCvmfs(kLogCvmfs, kLogStderr, "failed to load public repo key '%s'",
63 pubkey_path.c_str());
64 return false;
65 }
66 }
67
68 // We may not have a certificate and key. In this case, the signature manager
69 // can only be used for verification, not for signing.
70 if (certificate_path.empty())
71 return true;
72
73 if (!signature_manager_->LoadCertificatePath(certificate_path)) {
74 LogCvmfs(kLogCvmfs, kLogStderr, "failed to load certificate '%s'",
75 certificate_path.c_str());
76 return false;
77 }
78
79 // Load private key
80 if (!signature_manager_->LoadPrivateKeyPath(private_key_path, "")) {
81 LogCvmfs(kLogCvmfs, kLogStderr, "failed to load private key '%s' (%s)",
82 private_key_path.c_str(),
83 signature_manager_->GetCryptoError().c_str());
84 return false;
85 }
86
87 if (!signature_manager_->KeysMatch()) {
88 LogCvmfs(kLogCvmfs, kLogStderr,
89 "the private key '%s' doesn't seem to match certificate '%s' (%s)",
90 private_key_path.c_str(), certificate_path.c_str(),
91 signature_manager_->GetCryptoError().c_str());
92 signature_manager_->UnloadPrivateKey();
93 return false;
94 }
95
96 return true;
97 }
98
99 834 download::DownloadManager *ServerTool::download_manager() const {
100
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 834 times.
834 assert(download_manager_.get() != nullptr);
101 834 return download_manager_.get();
102 }
103
104 signature::SignatureManager *ServerTool::signature_manager() const {
105 assert(signature_manager_.get() != nullptr);
106 return signature_manager_.get();
107 }
108
109 manifest::Manifest *ServerTool::OpenLocalManifest(
110 const std::string path) const {
111 return manifest::Manifest::LoadFile(path);
112 }
113
114 manifest::Failures ServerTool::FetchRemoteManifestEnsemble(
115 const std::string &repository_url, const std::string &repository_name,
116 manifest::ManifestEnsemble *ensemble) const {
117 const uint64_t minimum_timestamp = 0;
118 const shash::Any *base_catalog = NULL;
119 return manifest::Fetch(repository_url, repository_name, minimum_timestamp,
120 base_catalog, signature_manager(), download_manager(),
121 ensemble);
122 }
123
124 manifest::Manifest *ServerTool::FetchRemoteManifest(
125 const std::string &repository_url, const std::string &repository_name,
126 const shash::Any &base_hash) const {
127 manifest::ManifestEnsemble manifest_ensemble;
128 std::unique_ptr<manifest::Manifest> manifest;
129
130 // fetch (and verify) the manifest
131 const manifest::Failures retval = FetchRemoteManifestEnsemble(
132 repository_url, repository_name, &manifest_ensemble);
133
134 if (retval != manifest::kFailOk) {
135 LogCvmfs(kLogCvmfs, kLogStderr,
136 "failed to fetch repository manifest "
137 "(%d - %s)",
138 retval, manifest::Code2Ascii(retval));
139 return NULL;
140 } else {
141 // copy-construct a fresh manifest object because ManifestEnsemble will
142 // free manifest_ensemble.manifest when it goes out of scope
143 manifest = std::unique_ptr<manifest::Manifest>(
144 new manifest::Manifest(*manifest_ensemble.manifest));
145 }
146
147 // check if manifest fetching was successful
148 if (manifest.get() == nullptr) {
149 LogCvmfs(kLogCvmfs, kLogStderr, "failed to load repository manifest");
150 return NULL;
151 }
152
153 // check the provided base hash of the repository if provided
154 if (!base_hash.IsNull() && manifest->catalog_hash() != base_hash) {
155 LogCvmfs(kLogCvmfs, kLogStderr,
156 "base hash does not match manifest "
157 "(found: %s expected: %s)",
158 manifest->catalog_hash().ToString().c_str(),
159 base_hash.ToString().c_str());
160 return NULL;
161 }
162
163 // return the fetched manifest (releasing pointer ownership)
164 return manifest.release();
165 }
166
167 manifest::Reflog *ServerTool::CreateEmptyReflog(
168 const std::string &temp_directory, const std::string &repo_name) {
169 // create a new Reflog if there was none found yet
170 const std::string tmp_path_prefix = temp_directory + "/new_reflog";
171 const std::string tmp_path = CreateTempPath(tmp_path_prefix, 0600);
172
173 LogCvmfs(kLogCvmfs, kLogDebug, "creating new reflog '%s' for %s",
174 tmp_path.c_str(), repo_name.c_str());
175 return manifest::Reflog::Create(tmp_path, repo_name);
176 }
177