From c0a166070e843fb9be2979e8a5631e8c120ddd08 Mon Sep 17 00:00:00 2001 From: Maksim Denisov Date: Mon, 20 Jan 2025 12:58:00 +0100 Subject: Implement UploadToServe --- src/buildtool/computed_roots/evaluate.cpp | 82 +++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) (limited to 'src/buildtool/computed_roots/evaluate.cpp') diff --git a/src/buildtool/computed_roots/evaluate.cpp b/src/buildtool/computed_roots/evaluate.cpp index 466b2536..c046297f 100644 --- a/src/buildtool/computed_roots/evaluate.cpp +++ b/src/buildtool/computed_roots/evaluate.cpp @@ -46,6 +46,7 @@ #include "src/buildtool/crypto/hash_function.hpp" #include "src/buildtool/execution_api/common/api_bundle.hpp" #include "src/buildtool/execution_api/common/execution_api.hpp" +#include "src/buildtool/execution_api/serve/mr_git_api.hpp" #include "src/buildtool/execution_api/utils/rehash_utils.hpp" #include "src/buildtool/file_system/file_root.hpp" #include "src/buildtool/file_system/file_system_manager.hpp" @@ -87,6 +88,13 @@ void AddDescriptionIfPrecomputed( StorageConfig const& native_storage_config) -> expected; +[[nodiscard]] auto UploadToServe(ServeApi const& serve, + ApiBundle const& serve_apis, + StorageConfig const& serve_storage_config, + ArtifactDigest const& digest, + std::filesystem::path const& repo_path) + -> expected; + // Traverse, starting from a given repository, in order to find the // computed roots it depends on. void TraverseRepoForComputedRoots( @@ -770,4 +778,78 @@ namespace { return rehashed->front().digest; } +[[nodiscard]] auto UploadToServe(ServeApi const& serve, + ApiBundle const& serve_apis, + StorageConfig const& serve_storage_config, + ArtifactDigest const& digest, + std::filesystem::path const& repo_path) + -> expected { + RepositoryConfig repo; + if (not repo.SetGitCAS(repo_path)) { + return unexpected{ + fmt::format("Failed to SetGitCAS at {}", repo_path.string())}; + } + + bool const with_rehashing = not ProtocolTraits::IsNative( + serve_storage_config.hash_function.GetType()); + + // Create a native storage config if rehashing is needed: + std::optional native_storage_config; + if (with_rehashing) { + auto config = StorageConfig::Builder::Rebuild(serve_storage_config) + .SetHashType(HashFunction::Type::GitSHA1) + .Build(); + if (not config.has_value()) { + return unexpected{ + fmt::format("Failed to rebuild storage for rehashing: {}", + std::move(config).error())}; + } + native_storage_config.emplace(*config); + } + + std::shared_ptr git_api; + if (with_rehashing) { + git_api = std::make_shared(&repo, + &*native_storage_config, + &serve_storage_config, + &*serve_apis.local); + } + else { + git_api = std::make_shared(&repo, &serve_storage_config); + } + + if (not git_api->RetrieveToCas( + {Artifact::ObjectInfo{digest, ObjectType::Tree}}, + *serve_apis.remote)) { + return unexpected{ + fmt::format("Failed to sync tree {} from repository {}", + digest.hash(), + repo_path.string())}; + } + + ArtifactDigest result = digest; + if (with_rehashing) { + auto rehashed = RehashUtils::ReadRehashedDigest(digest, + *native_storage_config, + serve_storage_config, + /*from_git=*/true); + if (not rehashed.has_value()) { + return unexpected{fmt::format("Failed to rehash {}:\n{}", + digest.hash(), + std::move(rehashed).error())}; + } + if (not rehashed.value().has_value()) { + return unexpected{fmt::format( + "No digest provided to sync root tree {}.", digest.hash())}; + } + result = rehashed.value()->digest; + } + + if (not serve.GetTreeFromRemote(result)) { + return unexpected{fmt::format( + "Serve endpoint failed to sync root tree {}.", result.hash())}; + } + return result; +} + } // namespace -- cgit v1.2.3