GCC Code Coverage Report


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