summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/buildtool/serve_api/serve_service/TARGETS1
-rw-r--r--src/buildtool/serve_api/serve_service/serve_server_implementation.cpp1
-rw-r--r--src/buildtool/serve_api/serve_service/target.cpp59
-rw-r--r--src/buildtool/serve_api/serve_service/target.hpp4
4 files changed, 65 insertions, 0 deletions
diff --git a/src/buildtool/serve_api/serve_service/TARGETS b/src/buildtool/serve_api/serve_service/TARGETS
index 673553f8..e38be94b 100644
--- a/src/buildtool/serve_api/serve_service/TARGETS
+++ b/src/buildtool/serve_api/serve_service/TARGETS
@@ -141,6 +141,7 @@
, ["src/buildtool/execution_api/common", "common"]
, ["src/buildtool/execution_engine/executor", "context"]
, ["src/buildtool/file_system", "file_system_manager"]
+ , ["src/buildtool/file_system", "git_repo"]
, ["src/buildtool/file_system", "object_type"]
, ["src/buildtool/graph_traverser", "graph_traverser"]
, ["src/buildtool/logging", "log_level"]
diff --git a/src/buildtool/serve_api/serve_service/serve_server_implementation.cpp b/src/buildtool/serve_api/serve_service/serve_server_implementation.cpp
index 54bb0c76..f9823538 100644
--- a/src/buildtool/serve_api/serve_service/serve_server_implementation.cpp
+++ b/src/buildtool/serve_api/serve_service/serve_server_implementation.cpp
@@ -136,6 +136,7 @@ auto ServeServerImpl::Run(
local_context,
remote_context,
&apis,
+ lock_,
serve ? &*serve : nullptr};
ConfigurationService cs{hash_type, remote_context->exec_config};
diff --git a/src/buildtool/serve_api/serve_service/target.cpp b/src/buildtool/serve_api/serve_service/target.cpp
index 1154bc9c..4ce3491d 100644
--- a/src/buildtool/serve_api/serve_service/target.cpp
+++ b/src/buildtool/serve_api/serve_service/target.cpp
@@ -29,6 +29,7 @@
#include "src/buildtool/build_engine/expression/configuration.hpp"
#include "src/buildtool/build_engine/expression/expression.hpp"
#include "src/buildtool/build_engine/expression/expression_ptr.hpp"
+#include "src/buildtool/build_engine/expression/target_result.hpp"
#include "src/buildtool/build_engine/target_map/configured_target.hpp"
#include "src/buildtool/build_engine/target_map/result_map.hpp"
#include "src/buildtool/common/artifact.hpp"
@@ -42,6 +43,7 @@
#include "src/buildtool/execution_api/common/execution_api.hpp"
#include "src/buildtool/execution_engine/executor/context.hpp"
#include "src/buildtool/file_system/file_system_manager.hpp"
+#include "src/buildtool/file_system/git_repo.hpp"
#include "src/buildtool/file_system/object_type.hpp"
#include "src/buildtool/graph_traverser/graph_traverser.hpp"
#include "src/buildtool/logging/log_level.hpp"
@@ -63,6 +65,46 @@
#include "src/buildtool/storage/target_cache_key.hpp"
#include "src/utils/cpp/tmp_dir.hpp"
+namespace {
+// Store the artifact root given by the target-cache entry. Return std::nullopt
+// on success and an error message on failure.
+auto KeepRoot(TargetCacheEntry const& target_entry,
+ LocalContext const& local_context,
+ gsl::not_null<IExecutionApi::Ptr> const& api,
+ gsl::not_null<std::mutex*> const& tagging_lock)
+ -> std::optional<std::string> {
+ auto cache_result = target_entry.ToResult();
+ if (not cache_result) {
+ return "Failed to get analysis result for target cache entry.";
+ }
+ auto tmp_dir =
+ local_context.storage_config->CreateTypedTmpDir("keep-artifacts-stage");
+ if (not tmp_dir) {
+ return "Failed to create a temporary directory for keeping stage.";
+ }
+ std::vector<std::filesystem::path> paths{};
+ std::vector<Artifact::ObjectInfo> object_infos{};
+ for (auto const& [rel_path, artifact] :
+ cache_result->artifact_stage->Map()) {
+ paths.push_back(tmp_dir->GetPath() / rel_path);
+ object_infos.push_back(*artifact->Artifact().ToArtifact().Info());
+ }
+ if (not api->RetrieveToPaths(object_infos, paths)) {
+ return fmt::format("Failed installing {} to temp dir {}.",
+ cache_result->artifact_stage->ToString(),
+ tmp_dir->GetPath().string());
+ }
+ auto import_result = GitRepo::ImportToGit(*local_context.storage_config,
+ tmp_dir->GetPath(),
+ "Keep artifact stage",
+ tagging_lock);
+ if (not import_result) {
+ return import_result.error();
+ }
+ return std::nullopt; // No errors
+}
+} // namespace
+
auto TargetService::GetDispatchList(
ArtifactDigest const& dispatch_digest) noexcept
-> expected<std::vector<DispatchEndpoint>, ::grpc::Status> {
@@ -241,6 +283,14 @@ auto TargetService::ServeTarget(
logger_->Emit(LogLevel::Error, "{}", msg);
return ::grpc::Status{::grpc::StatusCode::UNAVAILABLE, msg};
}
+ if (request->keep_artifact_root()) {
+ auto keep = KeepRoot(
+ target_entry->first, local_context_, apis_.local, lock_);
+ if (keep) {
+ logger_->Emit(LogLevel::Error, "{}", *keep);
+ return ::grpc::Status{::grpc::StatusCode::INTERNAL, *keep};
+ }
+ }
// populate response with the target cache value
(*response->mutable_target_value()) =
ArtifactDigestFactory::ToBazel(target_entry->second.digest);
@@ -591,6 +641,15 @@ auto TargetService::ServeTarget(
logger_->Emit(LogLevel::Error, "{}", msg);
return ::grpc::Status{::grpc::StatusCode::UNAVAILABLE, msg};
}
+ if (request->keep_artifact_root()) {
+ auto keep_error = KeepRoot(
+ target_entry->first, local_context_, apis_.local, lock_);
+ if (keep_error) {
+ logger_->Emit(LogLevel::Error, "{}", *keep_error);
+ return ::grpc::Status{::grpc::StatusCode::INTERNAL,
+ *keep_error};
+ }
+ }
// populate response with the target cache value
(*response->mutable_target_value()) =
ArtifactDigestFactory::ToBazel(target_entry->second.digest);
diff --git a/src/buildtool/serve_api/serve_service/target.hpp b/src/buildtool/serve_api/serve_service/target.hpp
index bc5dfd2c..ec1e9785 100644
--- a/src/buildtool/serve_api/serve_service/target.hpp
+++ b/src/buildtool/serve_api/serve_service/target.hpp
@@ -17,6 +17,7 @@
#include <filesystem>
#include <memory>
+#include <mutex>
#include <string>
#include <vector>
@@ -44,11 +45,13 @@ class TargetService final : public justbuild::just_serve::Target::Service {
gsl::not_null<LocalContext const*> const& local_context,
gsl::not_null<RemoteContext const*> const& remote_context,
gsl::not_null<ApiBundle const*> const& apis,
+ gsl::not_null<std::mutex*> const& lock,
ServeApi const* serve = nullptr) noexcept
: serve_config_{*serve_config},
local_context_{*local_context},
remote_context_{*remote_context},
apis_{*apis},
+ lock_{lock},
serve_{serve} {}
// Given a target-level caching key, returns the computed value. In doing
@@ -131,6 +134,7 @@ class TargetService final : public justbuild::just_serve::Target::Service {
LocalContext const& local_context_;
RemoteContext const& remote_context_;
ApiBundle const& apis_;
+ gsl::not_null<std::mutex*> lock_;
ServeApi const* const serve_ = nullptr;
std::shared_ptr<Logger> logger_{std::make_shared<Logger>("target-service")};