diff options
-rw-r--r-- | src/buildtool/serve_api/remote/TARGETS | 2 | ||||
-rw-r--r-- | src/buildtool/serve_api/remote/serve_api.cpp | 50 | ||||
-rw-r--r-- | src/buildtool/serve_api/remote/serve_api.hpp | 8 |
3 files changed, 59 insertions, 1 deletions
diff --git a/src/buildtool/serve_api/remote/TARGETS b/src/buildtool/serve_api/remote/TARGETS index 102109ed..d8180c53 100644 --- a/src/buildtool/serve_api/remote/TARGETS +++ b/src/buildtool/serve_api/remote/TARGETS @@ -55,7 +55,6 @@ , ["src/buildtool/file_system", "git_types"] , ["src/buildtool/file_system/symlinks_map", "pragma_special"] , ["src/buildtool/storage", "config"] - , ["src/buildtool/storage", "storage"] , ["src/utils/cpp", "expected"] ] , "private-deps": @@ -67,6 +66,7 @@ , ["src/buildtool/execution_api/serve", "mr_git_api"] , ["src/buildtool/execution_api/utils", "rehash_utils"] , ["src/buildtool/file_system", "object_type"] + , ["src/buildtool/storage", "storage"] ] , "stage": ["src", "buildtool", "serve_api", "remote"] } diff --git a/src/buildtool/serve_api/remote/serve_api.cpp b/src/buildtool/serve_api/remote/serve_api.cpp index 37911e1d..cb0ea7ac 100644 --- a/src/buildtool/serve_api/remote/serve_api.cpp +++ b/src/buildtool/serve_api/remote/serve_api.cpp @@ -25,6 +25,7 @@ #include "src/buildtool/execution_api/serve/mr_git_api.hpp" #include "src/buildtool/execution_api/utils/rehash_utils.hpp" #include "src/buildtool/file_system/object_type.hpp" +#include "src/buildtool/storage/storage.hpp" auto ServeApi::UploadTree(ArtifactDigest const& tree, std::filesystem::path const& git_repo) const noexcept @@ -108,4 +109,53 @@ auto ServeApi::UploadTree(ArtifactDigest const& tree, return std::monostate{}; } +auto ServeApi::DownloadTree(ArtifactDigest const& tree) const noexcept + -> expected<std::monostate, std::string> { + if (not tree.IsTree() or not ProtocolTraits::IsNative(tree.GetHashType())) { + return unexpected{fmt::format("Not a git tree: {}", tree.hash())}; + } + + // Check the tree is already in native CAS: + auto native_config = StorageConfig::Builder::Rebuild(storage_config_) + .SetHashType(HashFunction::Type::GitSHA1) + .Build(); + if (not native_config.has_value()) { + return unexpected{fmt::format("Failed to create native storage: {}", + std::move(native_config).error())}; + } + if (Storage::Create(&*native_config).CAS().TreePath(tree).has_value()) { + return std::monostate{}; + } + + // Make tree available on the remote end point: + auto const on_remote = TreeInRemoteCAS(tree.hash()); + if (not on_remote.has_value()) { + return unexpected{ + fmt::format("Failed to upload {} from serve to the remote end " + "point.", + tree.hash())}; + } + + // Download tree from the remote end point: + Artifact::ObjectInfo const info{*on_remote, ObjectType::Tree}; + if (not apis_.remote->RetrieveToCas({info}, *apis_.local)) { + return unexpected{fmt::format( + "Failed to download {} from the remote end point.", tree.hash())}; + } + + // The remote end point may operate in the compatible mode. In such a case, + // an extra rehashing is needed: + if (not ProtocolTraits::IsNative(storage_config_.hash_function.GetType())) { + auto rehashed = RehashUtils::RehashDigest( + {info}, storage_config_, *native_config, &apis_); + if (not rehashed.has_value() or rehashed->size() != 1 or + rehashed->front().digest != tree) { + return unexpected{fmt::format("Failed to rehash downloaded {}:\n{}", + on_remote->hash(), + std::move(rehashed).error())}; + } + } + return std::monostate{}; +} + #endif diff --git a/src/buildtool/serve_api/remote/serve_api.hpp b/src/buildtool/serve_api/remote/serve_api.hpp index 975e7a17..6746fb57 100644 --- a/src/buildtool/serve_api/remote/serve_api.hpp +++ b/src/buildtool/serve_api/remote/serve_api.hpp @@ -174,6 +174,14 @@ class ServeApi final { std::filesystem::path const& git_repo) const noexcept -> expected<std::monostate, UploadError>; + /// \brief Download a git tree from serve. + /// \param tree Tree to download. + /// \return std::monostate if after the call the requested tree can be found + /// in the native CAS to which this serve instance is bound to, or an + /// unexpected error message on failure. + [[nodiscard]] auto DownloadTree(ArtifactDigest const& tree) const noexcept + -> expected<std::monostate, std::string>; + private: // source tree service client SourceTreeClient const stc_; |