diff options
-rw-r--r-- | src/buildtool/main/main.cpp | 9 | ||||
-rw-r--r-- | src/buildtool/serve_api/serve_service/target.cpp | 9 | ||||
-rw-r--r-- | src/buildtool/storage/TARGETS | 11 | ||||
-rw-r--r-- | src/buildtool/storage/backend_description.cpp | 41 | ||||
-rw-r--r-- | src/buildtool/storage/backend_description.hpp | 41 | ||||
-rw-r--r-- | src/buildtool/storage/config.hpp | 15 |
6 files changed, 94 insertions, 32 deletions
diff --git a/src/buildtool/main/main.cpp b/src/buildtool/main/main.cpp index 42a36391..bc159f6c 100644 --- a/src/buildtool/main/main.cpp +++ b/src/buildtool/main/main.cpp @@ -248,14 +248,15 @@ void StoreTargetCacheShard( Storage const& storage, RemoteExecutionConfig const& remote_exec_config) noexcept { auto backend_description = - DescribeBackend(remote_exec_config.remote_address, - remote_exec_config.platform_properties, - remote_exec_config.dispatch); + BackendDescription::Describe(remote_exec_config.remote_address, + remote_exec_config.platform_properties, + remote_exec_config.dispatch); if (not backend_description) { Logger::Log(LogLevel::Error, backend_description.error()); std::exit(kExitFailure); } - std::ignore = storage.CAS().StoreBlob(*backend_description); + std::ignore = + storage.CAS().StoreBlob(backend_description->GetDescription()); } #endif // BOOTSTRAP_BUILD_TOOL diff --git a/src/buildtool/serve_api/serve_service/target.cpp b/src/buildtool/serve_api/serve_service/target.cpp index ff0acfa5..9ced4b02 100644 --- a/src/buildtool/serve_api/serve_service/target.cpp +++ b/src/buildtool/serve_api/serve_service/target.cpp @@ -202,9 +202,10 @@ auto TargetService::ServeTarget( } // get backend description - auto description = DescribeBackend(remote_config->remote_address, - remote_config->platform_properties, - remote_config->dispatch); + auto description = + BackendDescription::Describe(remote_config->remote_address, + remote_config->platform_properties, + remote_config->dispatch); if (not description) { auto err = fmt::format("Failed to create backend description:\n{}", description.error()); @@ -214,7 +215,7 @@ auto TargetService::ServeTarget( // add backend description to CAS auto execution_backend_dgst = - local_context_.storage->CAS().StoreBlob(*description); + local_context_.storage->CAS().StoreBlob(description->GetDescription()); if (not execution_backend_dgst) { std::string err{ "Failed to store execution backend description in local CAS"}; diff --git a/src/buildtool/storage/TARGETS b/src/buildtool/storage/TARGETS index 11f9ac0c..81a8ae26 100644 --- a/src/buildtool/storage/TARGETS +++ b/src/buildtool/storage/TARGETS @@ -162,10 +162,17 @@ , "hdrs": ["backend_description.hpp"] , "srcs": ["backend_description.cpp"] , "deps": - [ ["src/buildtool/common/remote", "remote_common"] + [ ["src/buildtool/common", "common"] + , ["src/buildtool/common/remote", "remote_common"] + , ["src/buildtool/crypto", "hash_function"] , ["src/utils/cpp", "expected"] ] , "stage": ["src", "buildtool", "storage"] - , "private-deps": [["@", "fmt", "", "fmt"], ["@", "json", "", "json"]] + , "private-deps": + [ ["@", "fmt", "", "fmt"] + , ["@", "json", "", "json"] + , ["src/buildtool/common", "artifact_digest_factory"] + , ["src/buildtool/file_system", "object_type"] + ] } } diff --git a/src/buildtool/storage/backend_description.cpp b/src/buildtool/storage/backend_description.cpp index a290dc22..0f1a3401 100644 --- a/src/buildtool/storage/backend_description.cpp +++ b/src/buildtool/storage/backend_description.cpp @@ -19,11 +19,24 @@ #include "fmt/core.h" #include "nlohmann/json.hpp" +#include "src/buildtool/common/artifact_digest_factory.hpp" +#include "src/buildtool/file_system/object_type.hpp" -auto DescribeBackend(std::optional<ServerAddress> const& address, - ExecutionProperties const& properties, - std::vector<DispatchEndpoint> const& dispatch) noexcept - -> expected<std::string, std::string> { +BackendDescription::BackendDescription() noexcept { + if (auto dummy = Describe( + /*address=*/std::nullopt, /*properties=*/{}, /*dispatch=*/{})) { + description_ = dummy->description_; + } + else { + description_ = std::make_shared<std::string>(); + } +} + +auto BackendDescription::Describe( + std::optional<ServerAddress> const& address, + ExecutionProperties const& properties, + std::vector<DispatchEndpoint> const& dispatch) noexcept + -> expected<BackendDescription, std::string> { nlohmann::json description; try { description["remote_address"] = @@ -54,16 +67,32 @@ auto DescribeBackend(std::optional<ServerAddress> const& address, "Failed to serialize endpoint dispatch list:\n{}", e.what())}; } } + + std::shared_ptr<std::string> result; + std::shared_ptr<std::string> sha256; try { // json::dump with json::error_handler_t::replace will not throw an // exception if invalid UTF-8 sequences are detected in the input. // Instead, it will replace them with the UTF-8 replacement // character, but still it needs to be inside a try-catch clause to // ensure the noexcept modifier of the enclosing function. - return description.dump( - 2, ' ', false, nlohmann::json::error_handler_t::replace); + result = std::make_shared<std::string>(description.dump( + 2, ' ', false, nlohmann::json::error_handler_t::replace)); + + std::string hash = + ArtifactDigestFactory::HashDataAs<ObjectType::File>( + HashFunction(HashFunction::Type::PlainSHA256), *result) + .hash(); + sha256 = std::make_shared<std::string>(std::move(hash)); } catch (std::exception const& e) { return unexpected{fmt::format( "Failed to dump backend description to JSON:\n{}", e.what())}; } + return BackendDescription(std::move(result), std::move(sha256)); +} + +auto BackendDescription::HashContent(HashFunction hash_function) const noexcept + -> ArtifactDigest { + return ArtifactDigestFactory::HashDataAs<ObjectType::File>( + hash_function, GetDescription()); } diff --git a/src/buildtool/storage/backend_description.hpp b/src/buildtool/storage/backend_description.hpp index c1ef17d7..9d912930 100644 --- a/src/buildtool/storage/backend_description.hpp +++ b/src/buildtool/storage/backend_description.hpp @@ -15,18 +15,47 @@ #ifndef INCLUDED_SRC_BUILDTOOL_STORAGE_BACKEND_DESCRIPTION_HPP #define INCLUDED_SRC_BUILDTOOL_STORAGE_BACKEND_DESCRIPTION_HPP +#include <memory> #include <optional> #include <string> +#include <utility> #include <vector> +#include "src/buildtool/common/artifact_digest.hpp" #include "src/buildtool/common/remote/remote_common.hpp" +#include "src/buildtool/crypto/hash_function.hpp" #include "src/utils/cpp/expected.hpp" -/// \brief String representation of the used execution backend. -[[nodiscard]] auto DescribeBackend( - std::optional<ServerAddress> const& address, - ExecutionProperties const& properties, - std::vector<DispatchEndpoint> const& dispatch) noexcept - -> expected<std::string, std::string>; +class BackendDescription final { + public: + explicit BackendDescription() noexcept; + + /// \brief String representation of the used execution backend. + [[nodiscard]] static auto Describe( + std::optional<ServerAddress> const& address, + ExecutionProperties const& properties, + std::vector<DispatchEndpoint> const& dispatch) noexcept + -> expected<BackendDescription, std::string>; + + [[nodiscard]] auto GetDescription() const noexcept -> std::string const& { + return *description_; + } + + [[nodiscard]] auto HashContent(HashFunction hash_function) const noexcept + -> ArtifactDigest; + + [[nodiscard]] auto operator==( + BackendDescription const& other) const noexcept -> bool { + return sha256_ == other.sha256_ or *sha256_ == *other.sha256_; + } + + private: + explicit BackendDescription(std::shared_ptr<std::string> description, + std::shared_ptr<std::string> sha256) noexcept + : description_{std::move(description)}, sha256_{std::move(sha256)} {} + + std::shared_ptr<std::string> description_; + std::shared_ptr<std::string> sha256_; +}; #endif // INCLUDED_SRC_BUILDTOOL_STORAGE_BACKEND_DESCRIPTION_HPP diff --git a/src/buildtool/storage/config.hpp b/src/buildtool/storage/config.hpp index 55f79339..fdfcfbb7 100644 --- a/src/buildtool/storage/config.hpp +++ b/src/buildtool/storage/config.hpp @@ -154,14 +154,9 @@ struct StorageConfig final { }; [[nodiscard]] auto DefaultBackendDescriptionId() noexcept -> std::string { - try { - return ArtifactDigestFactory::HashDataAs<ObjectType::File>( - hash_function, - DescribeBackend(std::nullopt, {}, {}).value()) - .hash(); - } catch (...) { - return std::string(); - } + return ArtifactDigestFactory::HashDataAs<ObjectType::File>( + hash_function, BackendDescription{}.GetDescription()) + .hash(); } }; @@ -225,12 +220,12 @@ class StorageConfig::Builder final { // Hash the execution backend description auto backend_description_id = default_config.backend_description_id; - auto desc = DescribeBackend( + auto desc = BackendDescription::Describe( remote_address_, remote_platform_properties_, remote_dispatch_); if (desc) { backend_description_id = ArtifactDigestFactory::HashDataAs<ObjectType::File>( - hash_function, *desc) + hash_function, desc->GetDescription()) .hash(); } else { |