GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/notify/cmd_pub.cc
Date: 2026-09-27 02:40:09
Exec Total Coverage
Lines: 0 51 0.0%
Branches: 0 44 0.0%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4
5 #include "cmd_pub.h"
6
7 #include <fcntl.h>
8
9 #include <memory>
10 #include <string>
11 #include <vector>
12
13 #include "manifest.h"
14 #include "network/download.h"
15 #include "network/sink_mem.h"
16 #include "notify/messages.h"
17 #include "notify/publisher_http.h"
18 #include "util/posix.h"
19 #include "util/string.h"
20
21 namespace {
22
23 const LogFacilities &kLogInfo = DefaultLogging::info;
24 const LogFacilities &kLogError = DefaultLogging::error;
25
26 const int kMaxPoolHandles = 1;
27 const unsigned kDownloadTimeout = 60; // 1 minute
28 const unsigned kDownloadRetries = 1; // 2 attempts in total
29
30 } // namespace
31
32 namespace notify {
33
34 ✗ int DoPublish(const std::string &server_url, const std::string &repository_url,
35 bool verbose) {
36 ✗ const std::string repo_url = MakeCanonicalPath(repository_url);
37
38 ✗ if (verbose) {
39 ✗ LogCvmfs(kLogCvmfs, kLogInfo, "Parameters: ");
40 ✗ LogCvmfs(kLogCvmfs, kLogInfo, " CVMFS repository URL: %s",
41 repo_url.c_str());
42 ✗ LogCvmfs(kLogCvmfs, kLogInfo, " Notification server URL: %s",
43 server_url.c_str());
44 }
45
46 // Download repository manifest
47 ✗ std::string manifest_contents;
48 ✗ const std::string manifest_url = repo_url + "/.cvmfspublished";
49 ✗ if (IsHttpUrl(repo_url)) {
50 ✗ perf::Statistics stats;
51 const std::unique_ptr<download::DownloadManager> download_manager(
52 new download::DownloadManager(
53 ✗ kMaxPoolHandles, perf::StatisticsTemplate("download", &stats)));
54 ✗ assert(download_manager.get() != nullptr);
55
56 ✗ download_manager->SetTimeout(kDownloadTimeout, kDownloadTimeout);
57 ✗ download_manager->SetRetryParameters(kDownloadRetries, 500, 2000);
58
59 ✗ cvmfs::MemSink manifest_memsink;
60 download::JobInfo download_manifest(&manifest_url, false, false, NULL,
61 ✗ &manifest_memsink);
62 ✗ const download::Failures retval = download_manager->Fetch(
63 &download_manifest);
64 ✗ if (retval != download::kFailOk) {
65 ✗ LogCvmfs(kLogCvmfs, kLogError, "Failed to download manifest (%d - %s)",
66 retval, download::Code2Ascii(retval));
67 ✗ return 6;
68 }
69 ✗ manifest_contents = std::string(
70 ✗ reinterpret_cast<char *>(manifest_memsink.data()),
71 ✗ manifest_memsink.pos());
72 ✗ } else {
73 ✗ const int fd = open(manifest_url.c_str(), O_RDONLY);
74 ✗ if (fd == -1) {
75 ✗ LogCvmfs(kLogCvmfs, kLogError, "Could not open manifest file");
76 ✗ return 7;
77 }
78 ✗ if (!SafeReadToString(fd, &manifest_contents)) {
79 ✗ LogCvmfs(kLogCvmfs, kLogError, "Could not read manifest file");
80 ✗ close(fd);
81 ✗ return 8;
82 }
83 ✗ close(fd);
84 }
85
86 const std::unique_ptr<manifest::Manifest> manifest(
87 manifest::Manifest::LoadMem(
88 ✗ reinterpret_cast<const unsigned char *>(manifest_contents.data()),
89 ✗ manifest_contents.size()));
90
91 ✗ if (verbose) {
92 ✗ LogCvmfs(kLogCvmfs, kLogInfo, "Current repository manifest:\n%s",
93 manifest->ExportString().c_str());
94 }
95
96 ✗ const std::string repository_name = manifest->repository_name();
97
98 // Publish message
99 const std::unique_ptr<notify::Publisher> publisher(
100 ✗ new notify::PublisherHTTP(server_url));
101
102 ✗ std::string msg_text;
103 ✗ notify::msg::Activity msg;
104 ✗ msg.version_ = 1;
105 ✗ msg.timestamp_ = StringifyTime(std::time(NULL), true);
106 ✗ msg.repository_ = repository_name;
107 ✗ msg.manifest_ = manifest_contents;
108 ✗ msg.ToJSONString(&msg_text);
109
110 ✗ if (!publisher->Publish(msg_text, repository_name)) {
111 ✗ LogCvmfs(kLogCvmfs, kLogError, "Could not publish notification");
112 ✗ return 9;
113 }
114
115 ✗ assert(publisher->Finalize());
116
117 ✗ return 0;
118 }
119
120 } // namespace notify
121