summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/buildtool/serve_api/remote/TARGETS2
-rw-r--r--src/buildtool/serve_api/remote/serve_api.cpp50
-rw-r--r--src/buildtool/serve_api/remote/serve_api.hpp8
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_;