summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/buildtool/main/main.cpp80
-rw-r--r--src/buildtool/serve_api/remote/TARGETS1
-rw-r--r--src/buildtool/serve_api/remote/config.hpp186
3 files changed, 196 insertions, 71 deletions
diff --git a/src/buildtool/main/main.cpp b/src/buildtool/main/main.cpp
index bdd1bed5..357bf7e9 100644
--- a/src/buildtool/main/main.cpp
+++ b/src/buildtool/main/main.cpp
@@ -23,6 +23,7 @@
#include <unordered_map>
#include <unordered_set>
#include <utility>
+#include <variant>
#include "gsl/gsl"
#include "nlohmann/json.hpp"
@@ -152,45 +153,38 @@ void SetupExecutionConfig(EndpointArguments const& eargs,
}
}
-void SetupServeConfig(ServeArguments const& srvargs,
- CommonArguments const& cargs,
- BuildArguments const& bargs,
- TCArguments const& tc) {
- if (srvargs.remote_serve_address) {
- if (not RemoteServeConfig::Instance().SetRemoteAddress(
- *srvargs.remote_serve_address)) {
- Logger::Log(LogLevel::Error,
- "Setting serve service address '{}' failed.",
- *srvargs.remote_serve_address);
- std::exit(kExitFailure);
- }
- }
- if (not srvargs.repositories.empty() and
- not RemoteServeConfig::Instance().SetKnownRepositories(
- srvargs.repositories)) {
- Logger::Log(LogLevel::Error,
- "Setting serve service repositories failed.");
- std::exit(kExitFailure);
- }
- // make parallelism and build options available for remote builds
- if (not RemoteServeConfig::Instance().SetJobs(cargs.jobs)) {
- Logger::Log(LogLevel::Error, "Setting jobs failed.");
- std::exit(kExitFailure);
- }
- if (bargs.build_jobs > 0 and
- not RemoteServeConfig::Instance().SetBuildJobs(bargs.build_jobs)) {
- Logger::Log(LogLevel::Error, "Setting build jobs failed.");
- std::exit(kExitFailure);
+[[nodiscard]] auto CreateServeConfig(ServeArguments const& srvargs,
+ CommonArguments const& cargs,
+ BuildArguments const& bargs,
+ TCArguments const& tc) noexcept
+ -> std::optional<RemoteServeConfig> {
+ RemoteServeConfig::Builder builder;
+ builder.SetRemoteAddress(srvargs.remote_serve_address)
+ .SetKnownRepositories(srvargs.repositories)
+ .SetJobs(cargs.jobs)
+ .SetActionTimeout(bargs.timeout)
+ .SetTCStrategy(tc.target_cache_write_strategy);
+
+ if (bargs.build_jobs > 0) {
+ builder.SetBuildJobs(bargs.build_jobs);
}
- if (not RemoteServeConfig::Instance().SetActionTimeout(bargs.timeout)) {
- Logger::Log(LogLevel::Error, "Setting action timeout failed.");
- std::exit(kExitFailure);
+
+ auto result = builder.Build();
+ if (auto* config = std::get_if<RemoteServeConfig>(&result)) {
+ if (config->TCStrategy() == TargetCacheWriteStrategy::Disable) {
+ Logger::Log(
+ LogLevel::Info,
+ "Target-level cache writing of serve service is disabled.");
+ }
+ return std::move(*config);
}
- RemoteServeConfig::Instance().SetTCStrategy(tc.target_cache_write_strategy);
- if (tc.target_cache_write_strategy == TargetCacheWriteStrategy::Disable) {
- Logger::Log(LogLevel::Info,
- "Target-level cache writing of serve service is disabled.");
+
+ if (auto* error = std::get_if<std::string>(&result)) {
+ Logger::Log(LogLevel::Error, *error);
+ return std::nullopt;
}
+ Logger::Log(LogLevel::Error, "Unknown error occured");
+ return std::nullopt;
}
void SetupAuthConfig(CommonAuthArguments const& authargs,
@@ -845,8 +839,13 @@ auto main(int argc, char* argv[]) -> int {
SetupFileChunker();
SetupExecutionConfig(
arguments.endpoint, arguments.build, arguments.rebuild);
- SetupServeConfig(
+
+ auto serve_config = CreateServeConfig(
arguments.serve, arguments.common, arguments.build, arguments.tc);
+ if (not serve_config) {
+ return kExitFailure;
+ }
+
SetupAuthConfig(arguments.auth, arguments.cauth, arguments.sauth);
if (arguments.cmd == SubCommand::kGc) {
@@ -867,9 +866,9 @@ auto main(int argc, char* argv[]) -> int {
if (arguments.cmd == SubCommand::kServe) {
SetupServeServiceConfig(arguments.service);
- auto serve = ServeApi::Create(RemoteServeConfig::Instance());
+ auto serve = ServeApi::Create(*serve_config);
if (!ServeServerImpl::Instance().Run(
- RemoteServeConfig::Instance(),
+ *serve_config,
serve,
!RemoteExecutionConfig::RemoteAddress())) {
return kExitFailure;
@@ -952,8 +951,7 @@ auto main(int argc, char* argv[]) -> int {
DetermineRoots(&repo_config, arguments.common, arguments.analysis);
#ifndef BOOTSTRAP_BUILD_TOOL
- std::optional<ServeApi> serve =
- ServeApi::Create(RemoteServeConfig::Instance());
+ std::optional<ServeApi> serve = ServeApi::Create(*serve_config);
#else
std::optional<ServeApi> serve;
#endif // BOOTSTRAP_BUILD_TOOL
diff --git a/src/buildtool/serve_api/remote/TARGETS b/src/buildtool/serve_api/remote/TARGETS
index e1a90e2e..1d2a0917 100644
--- a/src/buildtool/serve_api/remote/TARGETS
+++ b/src/buildtool/serve_api/remote/TARGETS
@@ -5,6 +5,7 @@
, "deps":
[ ["src/buildtool/common/remote", "remote_common"]
, ["src/buildtool/main", "build_utils"]
+ , ["@", "fmt", "", "fmt"]
]
, "stage": ["src", "buildtool", "serve_api", "remote"]
}
diff --git a/src/buildtool/serve_api/remote/config.hpp b/src/buildtool/serve_api/remote/config.hpp
index 30197b53..4e5c3c21 100644
--- a/src/buildtool/serve_api/remote/config.hpp
+++ b/src/buildtool/serve_api/remote/config.hpp
@@ -19,13 +19,19 @@
#include <cstddef>
#include <filesystem>
#include <iterator>
+#include <optional>
+#include <string>
+#include <utility>
+#include <variant>
#include <vector>
+#include "fmt/core.h"
#include "src/buildtool/common/remote/remote_common.hpp"
#include "src/buildtool/main/build_utils.hpp"
-class RemoteServeConfig {
- public:
+struct RemoteServeConfig final {
+ class Builder;
+
// Obtain global instance
[[nodiscard]] static auto Instance() noexcept -> RemoteServeConfig& {
static RemoteServeConfig config;
@@ -33,90 +39,210 @@ class RemoteServeConfig {
}
// Set remote execution and cache address, unsets if parsing `address` fails
- [[nodiscard]] auto SetRemoteAddress(std::string const& address) noexcept
+ [[nodiscard]] auto SetRemoteAddress(std::string const& value) noexcept
-> bool {
- return static_cast<bool>(remote_address_ = ParseAddress(address));
+ return static_cast<bool>(remote_address = ParseAddress(value));
}
// Set the list of known repositories
[[nodiscard]] auto SetKnownRepositories(
- std::vector<std::filesystem::path> const& repos) noexcept -> bool {
- repositories_ = std::vector<std::filesystem::path>(
- std::make_move_iterator(repos.begin()),
- std::make_move_iterator(repos.end()));
- return repos.size() == repositories_.size();
+ std::vector<std::filesystem::path> const& value) noexcept -> bool {
+ known_repositories = std::vector<std::filesystem::path>(
+ std::make_move_iterator(value.begin()),
+ std::make_move_iterator(value.end()));
+ return value.size() == known_repositories.size();
}
// Set the number of jobs
- [[nodiscard]] auto SetJobs(std::size_t jobs) noexcept -> bool {
- return static_cast<bool>(jobs_ = jobs);
+ [[nodiscard]] auto SetJobs(std::size_t value) noexcept -> bool {
+ return static_cast<bool>(jobs = value);
}
// Set the number of build jobs
- [[nodiscard]] auto SetBuildJobs(std::size_t build_jobs) noexcept -> bool {
- return static_cast<bool>(build_jobs_ = build_jobs);
+ [[nodiscard]] auto SetBuildJobs(std::size_t value) noexcept -> bool {
+ return static_cast<bool>(build_jobs = value);
}
// Set the action timeout
[[nodiscard]] auto SetActionTimeout(
- std::chrono::milliseconds const& timeout) noexcept -> bool {
- timeout_ = timeout;
- return timeout_ > std::chrono::seconds{0};
+ std::chrono::milliseconds const& value) noexcept -> bool {
+ action_timeout = value;
+ return action_timeout > std::chrono::seconds{0};
}
- void SetTCStrategy(TargetCacheWriteStrategy strategy) noexcept {
- tc_strategy_ = strategy;
+ void SetTCStrategy(TargetCacheWriteStrategy value) noexcept {
+ tc_strategy = value;
}
// Remote execution address, if set
[[nodiscard]] auto RemoteAddress() const noexcept
-> std::optional<ServerAddress> {
- return remote_address_;
+ return remote_address;
}
// Repositories known to 'just serve'
[[nodiscard]] auto KnownRepositories() const noexcept
-> const std::vector<std::filesystem::path>& {
- return repositories_;
+ return known_repositories;
}
// Get the number of jobs
- [[nodiscard]] auto Jobs() const noexcept -> std::size_t { return jobs_; }
+ [[nodiscard]] auto Jobs() const noexcept -> std::size_t { return jobs; }
// Get the number of build jobs
[[nodiscard]] auto BuildJobs() const noexcept -> std::size_t {
- return build_jobs_;
+ return build_jobs;
}
// Get the action timeout
[[nodiscard]] auto ActionTimeout() const noexcept
-> std::chrono::milliseconds {
- return timeout_;
+ return action_timeout;
}
// Get the target-level cache write strategy
[[nodiscard]] auto TCStrategy() const noexcept -> TargetCacheWriteStrategy {
- return tc_strategy_;
+ return tc_strategy;
+ }
+
+ // Server address of remote execution.
+ std::optional<ServerAddress> remote_address{};
+
+ // Known Git repositories to serve server.
+ std::vector<std::filesystem::path> known_repositories{};
+
+ // Number of jobs
+ std::size_t jobs = 0;
+
+ // Number of build jobs
+ std::size_t build_jobs = 0;
+
+ // Action timeout
+ std::chrono::milliseconds action_timeout{};
+
+ // Strategy for synchronizing target-level cache
+ TargetCacheWriteStrategy tc_strategy{TargetCacheWriteStrategy::Sync};
+};
+
+class RemoteServeConfig::Builder final {
+ public:
+ // Set remote execution and cache address, unsets if parsing `address` fails
+ auto SetRemoteAddress(std::optional<std::string> value) noexcept
+ -> Builder& {
+ remote_address_ = std::move(value);
+ return *this;
+ }
+
+ // Set the list of known repositories
+ auto SetKnownRepositories(std::vector<std::filesystem::path> value) noexcept
+ -> Builder& {
+ known_repositories_ = std::move(value);
+ return *this;
+ }
+
+ // Set the number of jobs
+ auto SetJobs(std::size_t value) noexcept -> Builder& {
+ jobs_ = value;
+ return *this;
+ }
+
+ // Set the number of build jobs
+ auto SetBuildJobs(std::size_t value) noexcept -> Builder& {
+ build_jobs_ = value;
+ return *this;
+ }
+
+ // Set the action timeout
+ auto SetActionTimeout(std::chrono::milliseconds const& value) noexcept
+ -> Builder& {
+ action_timeout_ = value;
+ return *this;
+ }
+
+ auto SetTCStrategy(TargetCacheWriteStrategy value) noexcept -> Builder& {
+ tc_strategy_ = value;
+ return *this;
+ }
+
+ /// \brief Finalize building and create RemoteServeConfig.
+ /// \return RemoteServeConfig on success or an error on failure.
+ [[nodiscard]] auto Build() noexcept
+ -> std::variant<RemoteServeConfig, std::string> {
+ // To not duplicate default arguments of RemoteServeConfig in builder,
+ // create a default config and copy default arguments from there.
+ RemoteServeConfig const default_config;
+
+ auto remote_address = default_config.remote_address;
+ if (remote_address_.has_value()) {
+ remote_address = ParseAddress(*remote_address_);
+ if (not remote_address) {
+ return fmt::format("Setting serve service address '{}' failed.",
+ *remote_address_);
+ }
+ }
+
+ auto known_repositories = default_config.known_repositories;
+ if (known_repositories_.has_value()) {
+ known_repositories = std::move(*known_repositories_);
+ }
+
+ auto jobs = default_config.jobs;
+ if (jobs_.has_value()) {
+ jobs = *jobs_;
+ if (jobs == 0) {
+ return "Setting jobs failed.";
+ }
+ }
+
+ auto build_jobs = default_config.jobs;
+ if (build_jobs_.has_value()) {
+ build_jobs = *build_jobs_;
+ if (build_jobs == 0) {
+ return "Setting build jobs failed.";
+ }
+ }
+
+ auto action_timeout = default_config.action_timeout;
+ if (action_timeout_.has_value()) {
+ action_timeout = *action_timeout_;
+ if (bool const valid = action_timeout > std::chrono::seconds{0};
+ not valid) {
+ return "Setting action timeout failed.";
+ }
+ }
+
+ auto tc_strategy = default_config.tc_strategy;
+ if (tc_strategy_.has_value()) {
+ tc_strategy = *tc_strategy_;
+ }
+
+ return RemoteServeConfig{
+ .remote_address = std::move(remote_address),
+ .known_repositories = std::move(known_repositories),
+ .jobs = jobs,
+ .build_jobs = build_jobs,
+ .action_timeout = action_timeout,
+ .tc_strategy = tc_strategy};
}
private:
// Server address of remote execution.
- std::optional<ServerAddress> remote_address_{};
+ std::optional<std::string> remote_address_;
// Known Git repositories to serve server.
- std::vector<std::filesystem::path> repositories_{};
+ std::optional<std::vector<std::filesystem::path>> known_repositories_;
// Number of jobs
- std::size_t jobs_{};
+ std::optional<std::size_t> jobs_;
// Number of build jobs
- std::size_t build_jobs_{};
+ std::optional<std::size_t> build_jobs_;
// Action timeout
- std::chrono::milliseconds timeout_{};
+ std::optional<std::chrono::milliseconds> action_timeout_;
// Strategy for synchronizing target-level cache
- TargetCacheWriteStrategy tc_strategy_{TargetCacheWriteStrategy::Sync};
+ std::optional<TargetCacheWriteStrategy> tc_strategy_;
};
#endif // INCLUDED_SRC_BUILDTOOL_SERVE_API_REMOTE_CONFIG_HPP