summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/buildtool/common/cli.hpp19
-rw-r--r--src/buildtool/execution_api/remote/config.hpp118
-rw-r--r--src/buildtool/graph_traverser/graph_traverser.hpp39
-rw-r--r--src/buildtool/main/main.cpp37
4 files changed, 133 insertions, 80 deletions
diff --git a/src/buildtool/common/cli.hpp b/src/buildtool/common/cli.hpp
index ab4a7ff1..adfa3445 100644
--- a/src/buildtool/common/cli.hpp
+++ b/src/buildtool/common/cli.hpp
@@ -62,7 +62,7 @@ struct EndpointArguments {
/// \brief Arguments required for building.
struct BuildArguments {
std::optional<std::vector<std::string>> local_launcher{std::nullopt};
- std::map<std::string, std::string> platform_properties;
+ std::vector<std::string> platform_properties;
std::chrono::milliseconds timeout{kDefaultTimeout};
std::size_t build_jobs{};
std::optional<std::string> dump_artifacts{std::nullopt};
@@ -262,25 +262,14 @@ static inline auto SetupBuildArguments(
->type_name("JSON")
->default_val(nlohmann::json{"env", "--"}.dump());
- app->add_option_function<std::string>(
+ app->add_option(
"--remote-execution-property",
- [clargs](auto const& property) {
- std::istringstream pss(property);
- std::string key;
- std::string val;
- if (not std::getline(pss, key, ':') or
- not std::getline(pss, val, ':')) {
- throw CLI::ConversionError{property,
- "--remote-execution-property"};
- }
- clargs->platform_properties[std::move(key)] = std::move(val);
- },
+ clargs->platform_properties,
"Property for remote execution as key-value pair. Specifying this "
"option multiple times will accumulate pairs (latest wins).")
->type_name("KEY:VAL")
->allow_extra_args(false)
- ->expected(1, 1)
- ->trigger_on_parse(true); // call this everytime the option is parsed
+ ->expected(1, 1);
app->add_option_function<unsigned int>(
"--action-timeout",
diff --git a/src/buildtool/execution_api/remote/config.hpp b/src/buildtool/execution_api/remote/config.hpp
index e29b8aa7..14995b89 100644
--- a/src/buildtool/execution_api/remote/config.hpp
+++ b/src/buildtool/execution_api/remote/config.hpp
@@ -15,8 +15,72 @@
class RemoteExecutionConfig {
public:
+ struct ServerAddress {
+ std::string host{};
+ int port{};
+ };
+
+ // Obtain global instance
+ [[nodiscard]] static auto Instance() noexcept -> RemoteExecutionConfig& {
+ static RemoteExecutionConfig config;
+ return config;
+ }
+
+ // Set remote execution and cache address, unsets if parsing `address` fails
+ [[nodiscard]] static auto SetRemoteAddress(
+ std::string const& address) noexcept -> bool {
+ auto& inst = Instance();
+ return static_cast<bool>(inst.remote_address_ = inst.cache_address_ =
+ ParseAddress(address));
+ }
+
+ // Set specific cache address, unsets if parsing `address` fails
+ [[nodiscard]] static auto SetCacheAddress(
+ std::string const& address) noexcept -> bool {
+ return static_cast<bool>(Instance().cache_address_ =
+ ParseAddress(address));
+ }
+
+ // Add platform property from string of form "key:val"
+ [[nodiscard]] static auto AddPlatformProperty(
+ std::string const& property) noexcept -> bool {
+ if (auto pair = ParseProperty(property)) {
+ Instance().platform_properties_[std::move(pair->first)] =
+ std::move(pair->second);
+ return true;
+ }
+ return false;
+ }
+
+ // Remote execution address, if set
+ [[nodiscard]] static auto RemoteAddress() noexcept
+ -> std::optional<ServerAddress> {
+ return Instance().remote_address_;
+ }
+
+ // Cache address, if set
+ [[nodiscard]] static auto CacheAddress() noexcept
+ -> std::optional<ServerAddress> {
+ return Instance().cache_address_;
+ }
+
+ [[nodiscard]] static auto PlatformProperties() noexcept
+ -> std::map<std::string, std::string> {
+ return Instance().platform_properties_;
+ }
+
+ private:
+ // Server address of remote execution.
+ std::optional<ServerAddress> remote_address_{};
+
+ // Server address of cache endpoint for rebuild.
+ std::optional<ServerAddress> cache_address_{};
+
+ // Platform properies for execution.
+ std::map<std::string, std::string> platform_properties_{};
+
[[nodiscard]] static auto ParseAddress(std::string const& address) noexcept
- -> std::optional<std::pair<std::string, int>> {
+ -> std::optional<ServerAddress> {
std::istringstream iss(address);
std::string host;
std::string port;
@@ -25,48 +89,34 @@ class RemoteExecutionConfig {
return std::nullopt;
}
try {
- return std::make_pair(host, std::stoi(port));
+ static constexpr int kMaxPortNumber{
+ std::numeric_limits<uint16_t>::max()};
+ auto port_num = std::stoi(port);
+ if (not host.empty() and port_num >= 0 and
+ port_num <= kMaxPortNumber) {
+ return ServerAddress{std::move(host), port_num};
+ }
} catch (std::out_of_range const& e) {
Logger::Log(LogLevel::Error, "Port raised out_of_range exception.");
- return std::nullopt;
} catch (std::invalid_argument const& e) {
Logger::Log(LogLevel::Error,
"Port raised invalid_argument exception.");
- return std::nullopt;
}
+ return std::nullopt;
}
- // Obtain global instance
- [[nodiscard]] static auto Instance() noexcept -> RemoteExecutionConfig& {
- static RemoteExecutionConfig config;
- return config;
- }
-
- [[nodiscard]] auto IsValidAddress() const noexcept -> bool {
- return valid_;
- }
-
- [[nodiscard]] auto SetAddress(std::string const& address) noexcept -> bool {
- auto pair = ParseAddress(address);
- return pair and SetAddress(pair->first, pair->second);
- }
-
- [[nodiscard]] auto SetAddress(std::string const& host, int port) noexcept
- -> bool {
- host_ = host;
- port_ = port,
- valid_ = (not host.empty() and port >= 0 and port <= kMaxPortNumber);
- return valid_;
+ [[nodiscard]] static auto ParseProperty(
+ std::string const& property) noexcept
+ -> std::optional<std::pair<std::string, std::string>> {
+ std::istringstream pss(property);
+ std::string key;
+ std::string val;
+ if (not std::getline(pss, key, ':') or
+ not std::getline(pss, val, ':')) {
+ return std::nullopt;
+ }
+ return std::make_pair(key, val);
}
-
- [[nodiscard]] auto Host() const noexcept -> std::string { return host_; }
- [[nodiscard]] auto Port() const noexcept -> int { return port_; }
-
- private:
- static constexpr int kMaxPortNumber{std::numeric_limits<uint16_t>::max()};
- std::string host_{};
- int port_{};
- bool valid_{false};
};
#endif // INCLUDED_SRC_BUILDTOOL_EXECUTION_API_REMOTE_CONFIG_HPP
diff --git a/src/buildtool/graph_traverser/graph_traverser.hpp b/src/buildtool/graph_traverser/graph_traverser.hpp
index 5169e61e..53e5eb20 100644
--- a/src/buildtool/graph_traverser/graph_traverser.hpp
+++ b/src/buildtool/graph_traverser/graph_traverser.hpp
@@ -36,7 +36,6 @@ class GraphTraverser {
public:
struct CommandLineArguments {
std::size_t jobs;
- EndpointArguments endpoint;
BuildArguments build;
std::optional<StageArguments> stage;
std::optional<RebuildArguments> rebuild;
@@ -50,13 +49,13 @@ class GraphTraverser {
explicit GraphTraverser(CommandLineArguments clargs)
: clargs_{std::move(clargs)},
- api_{CreateExecutionApi(clargs_.endpoint)},
+ api_{CreateExecutionApi(RemoteExecutionConfig::RemoteAddress())},
reporter_{[](auto done, auto cv) {}} {}
explicit GraphTraverser(CommandLineArguments clargs,
progress_reporter_t reporter)
: clargs_{std::move(clargs)},
- api_{CreateExecutionApi(clargs_.endpoint)},
+ api_{CreateExecutionApi(RemoteExecutionConfig::RemoteAddress())},
reporter_{std::move(reporter)} {}
/// \brief Parses actions and blobs into graph, traverses it and retrieves
@@ -214,21 +213,14 @@ class GraphTraverser {
}
[[nodiscard]] static auto CreateExecutionApi(
- EndpointArguments const& clargs) -> gsl::not_null<IExecutionApi::Ptr> {
- if (clargs.remote_execution_address) {
- auto remote = RemoteExecutionConfig{};
- if (not remote.SetAddress(*clargs.remote_execution_address)) {
- Logger::Log(LogLevel::Error,
- "parsing remote execution address '{}' failed.",
- *clargs.remote_execution_address);
- std::exit(EXIT_FAILURE);
- }
-
+ std::optional<RemoteExecutionConfig::ServerAddress> const& address)
+ -> gsl::not_null<IExecutionApi::Ptr> {
+ if (address) {
ExecutionConfiguration config;
config.skip_cache_lookup = false;
return std::make_unique<BazelApi>(
- "remote-execution", remote.Host(), remote.Port(), config);
+ "remote-execution", address->host, address->port, config);
}
return std::make_unique<LocalApi>();
}
@@ -299,8 +291,9 @@ class GraphTraverser {
[[nodiscard]] auto Traverse(
DependencyGraph const& g,
std::vector<ArtifactIdentifier> const& artifact_ids) const -> bool {
- Executor executor{
- &(*api_), clargs_.build.platform_properties, clargs_.build.timeout};
+ Executor executor{&(*api_),
+ RemoteExecutionConfig::PlatformProperties(),
+ clargs_.build.timeout};
bool result{};
std::atomic<bool> done = false;
std::condition_variable cv{};
@@ -320,20 +313,12 @@ class GraphTraverser {
[[nodiscard]] auto TraverseRebuild(
DependencyGraph const& g,
std::vector<ArtifactIdentifier> const& artifact_ids) const -> bool {
- // create second configuration for cache endpoint
- auto cache_args = clargs_.endpoint;
- if (not clargs_.rebuild->cache_endpoint.value_or("").empty()) {
- cache_args.remote_execution_address =
- *clargs_.rebuild->cache_endpoint == "local"
- ? std::nullopt // disable
- : clargs_.rebuild->cache_endpoint; // set endpoint
- }
-
// setup rebuilder with api for cache endpoint
- auto api_cached = CreateExecutionApi(cache_args);
+ auto api_cached =
+ CreateExecutionApi(RemoteExecutionConfig::CacheAddress());
Rebuilder executor{&(*api_),
&(*api_cached),
- clargs_.build.platform_properties,
+ RemoteExecutionConfig::PlatformProperties(),
clargs_.build.timeout};
bool success{false};
{
diff --git a/src/buildtool/main/main.cpp b/src/buildtool/main/main.cpp
index b41d7a11..23ea7b8e 100644
--- a/src/buildtool/main/main.cpp
+++ b/src/buildtool/main/main.cpp
@@ -205,15 +205,44 @@ void SetupLogging(CommonArguments const& clargs) {
}
#ifndef BOOTSTRAP_BUILD_TOOL
-void SetupLocalExecution(EndpointArguments const& eargs,
- BuildArguments const& bargs) {
+void SetupExecutionConfig(EndpointArguments const& eargs,
+ BuildArguments const& bargs,
+ RebuildArguments const& rargs) {
using LocalConfig = LocalExecutionConfig;
+ using RemoteConfig = RemoteExecutionConfig;
if (not LocalConfig::SetKeepBuildDir(bargs.persistent_build_dir) or
not(not eargs.local_root or
(LocalConfig::SetBuildRoot(*eargs.local_root))) or
not(not bargs.local_launcher or
LocalConfig::SetLauncher(*bargs.local_launcher))) {
Logger::Log(LogLevel::Error, "failed to configure local execution.");
+ std::exit(kExitFailure);
+ }
+ for (auto const& property : bargs.platform_properties) {
+ if (not RemoteConfig::AddPlatformProperty(property)) {
+ Logger::Log(LogLevel::Error,
+ "addding platform property '{}' failed.",
+ property);
+ std::exit(kExitFailure);
+ }
+ }
+ if (eargs.remote_execution_address) {
+ if (not RemoteConfig::SetRemoteAddress(
+ *eargs.remote_execution_address)) {
+ Logger::Log(LogLevel::Error,
+ "setting remote execution address '{}' failed.",
+ *eargs.remote_execution_address);
+ std::exit(kExitFailure);
+ }
+ }
+ if (rargs.cache_endpoint) {
+ if (not(RemoteConfig::SetCacheAddress(*rargs.cache_endpoint) ==
+ (*rargs.cache_endpoint != "local"))) {
+ Logger::Log(LogLevel::Error,
+ "setting cache endpoint address '{}' failed.",
+ *rargs.cache_endpoint);
+ std::exit(kExitFailure);
+ }
}
}
@@ -1251,7 +1280,8 @@ auto main(int argc, char* argv[]) -> int {
SetupLogging(arguments.common);
#ifndef BOOTSTRAP_BUILD_TOOL
SetupHashGenerator();
- SetupLocalExecution(arguments.endpoint, arguments.build);
+ SetupExecutionConfig(
+ arguments.endpoint, arguments.build, arguments.rebuild);
#endif
auto jobs = arguments.build.build_jobs > 0 ? arguments.build.build_jobs
@@ -1270,7 +1300,6 @@ auto main(int argc, char* argv[]) -> int {
#ifndef BOOTSTRAP_BUILD_TOOL
GraphTraverser const traverser{{jobs,
- std::move(arguments.endpoint),
std::move(arguments.build),
std::move(stage_args),
std::move(rebuild_args)},