summaryrefslogtreecommitdiff
path: root/src/buildtool/execution_api/local/local_action.cpp
diff options
context:
space:
mode:
authorOliver Reiche <oliver.reiche@huawei.com>2025-06-23 14:56:04 +0200
committerOliver Reiche <oliver.reiche@huawei.com>2025-06-24 14:56:58 +0200
commitbbcc5977f49646941ac35060bb74a27eda5fbd76 (patch)
tree4e11ded4722ea740fbeea12510efd34fe698c04b /src/buildtool/execution_api/local/local_action.cpp
parentc498bf564fa5d781c176f65c7a9a2d43376a81f1 (diff)
downloadjustbuild-bbcc5977f49646941ac35060bb74a27eda5fbd76.tar.gz
ExecutionAPI: Support output_paths in requests
... and prepare local execution for clients using only RBEv2.1 (setting only output_paths).
Diffstat (limited to 'src/buildtool/execution_api/local/local_action.cpp')
-rw-r--r--src/buildtool/execution_api/local/local_action.cpp121
1 files changed, 119 insertions, 2 deletions
diff --git a/src/buildtool/execution_api/local/local_action.cpp b/src/buildtool/execution_api/local/local_action.cpp
index d9733f18..8050c3d7 100644
--- a/src/buildtool/execution_api/local/local_action.cpp
+++ b/src/buildtool/execution_api/local/local_action.cpp
@@ -134,8 +134,11 @@ auto LocalAction::Execute(Logger const* logger) noexcept
if (auto result =
local_context_.storage->ActionCache().CachedResult(*action)) {
if (result->exit_code() == 0 and
- ActionResultContainsExpectedOutputs(
- *result, output_files_, output_dirs_)) {
+ (mode_ == RequestMode::kV2_1
+ ? ActionResultContainsExpectedOutputs(*result,
+ output_paths_)
+ : ActionResultContainsExpectedOutputs(
+ *result, output_files_, output_dirs_))) {
return create_response(
logger,
action->hash(),
@@ -376,6 +379,16 @@ auto LocalAction::CreateDirectoryStructure(
}
return true;
};
+
+ if (mode_ == RequestMode::kV2_1) {
+ return std::all_of(
+ output_paths_.begin(),
+ output_paths_.end(),
+ [this, &exec_path, &create_dir](auto const& local_path) {
+ auto dir = (exec_path / cwd_ / local_path).parent_path();
+ return create_dir(dir);
+ });
+ }
return std::all_of(output_files_.begin(),
output_files_.end(),
[this, &exec_path, &create_dir](auto const& local_path) {
@@ -487,11 +500,109 @@ auto LocalAction::CollectOutputDirOrSymlink(
return std::nullopt;
}
+auto LocalAction::CollectOutputPath(
+ std::filesystem::path const& exec_path,
+ std::string const& local_path) const noexcept -> std::optional<OutputPath> {
+ auto out_path = exec_path / local_path;
+ auto type = FileSystemManager::Type(out_path, /*allow_upwards=*/true);
+ if (not type) {
+ logger_.Emit(LogLevel::Error, "expected known type at {}", local_path);
+ return std::nullopt;
+ }
+ if (IsSymlinkObject(*type)) {
+ if (auto content = FileSystemManager::ReadSymlink(out_path)) {
+ // in native mode: check validity of symlink
+ if (ProtocolTraits::IsNative(
+ local_context_.storage->GetHashFunction().GetType()) and
+ not PathIsNonUpwards(*content)) {
+ logger_.Emit(
+ LogLevel::Error, "found invalid symlink at {}", local_path);
+ return std::nullopt;
+ }
+ if (local_context_.storage->CAS().StoreBlob(*content)) {
+ auto out_symlink = bazel_re::OutputSymlink{};
+ out_symlink.set_path(local_path);
+ out_symlink.set_target(*content);
+ return out_symlink;
+ }
+ }
+ }
+ else if (IsFileObject(*type)) {
+ bool is_executable = IsExecutableObject(*type);
+ auto digest = local_context_.storage->CAS().StoreBlob</*kOwner=*/true>(
+ out_path, is_executable);
+ if (digest) {
+ auto out_file = bazel_re::OutputFile{};
+ out_file.set_path(local_path);
+ *out_file.mutable_digest() =
+ ArtifactDigestFactory::ToBazel(*digest);
+ out_file.set_is_executable(is_executable);
+ return out_file;
+ }
+ }
+ else if (IsTreeObject(*type)) {
+ if (auto digest = CreateDigestFromLocalOwnedTree(
+ *local_context_.storage, out_path)) {
+ auto out_dir = bazel_re::OutputDirectory{};
+ out_dir.set_path(local_path);
+ (*out_dir.mutable_tree_digest()) =
+ ArtifactDigestFactory::ToBazel(*digest);
+ return out_dir;
+ }
+ logger_.Emit(LogLevel::Error,
+ "found invalid entries in directory at {}",
+ local_path);
+ }
+ else {
+ logger_.Emit(LogLevel::Error,
+ "expected file, directory, or symlink at {}",
+ local_path);
+ }
+ return std::nullopt;
+}
+
auto LocalAction::CollectAndStoreOutputs(
bazel_re::ActionResult* result,
std::filesystem::path const& exec_path) const noexcept -> bool {
try {
logger_.Emit(LogLevel::Trace, "collecting outputs:");
+ if (mode_ == RequestMode::kV2_1) {
+ for (auto const& path : output_paths_) {
+ auto out = CollectOutputPath(exec_path, path);
+ if (not out) {
+ logger_.Emit(LogLevel::Error,
+ "could not collect output path {}",
+ path);
+ return false;
+ }
+ if (std::holds_alternative<bazel_re::OutputSymlink>(*out)) {
+ auto out_symlink = std::get<bazel_re::OutputSymlink>(*out);
+ logger_.Emit(LogLevel::Trace,
+ " - symlink {}: {}",
+ path,
+ out_symlink.target());
+ result->mutable_output_symlinks()->Add(
+ std::move(out_symlink));
+ }
+ else if (std::holds_alternative<bazel_re::OutputFile>(*out)) {
+ auto out_file = std::get<bazel_re::OutputFile>(*out);
+ auto const& digest = out_file.digest().hash();
+ logger_.Emit(
+ LogLevel::Trace, " - file {}: {}", path, digest);
+ result->mutable_output_files()->Add(std::move(out_file));
+ }
+ else {
+ auto out_dir = std::get<bazel_re::OutputDirectory>(*out);
+ auto const& digest = out_dir.tree_digest().hash();
+ logger_.Emit(
+ LogLevel::Trace, " - dir {}: {}", path, digest);
+ result->mutable_output_directories()->Add(
+ std::move(out_dir));
+ }
+ }
+ return true;
+ }
+ // if mode_ is RequestMode::kV2_0 or RequestMode::kBestEffort
for (auto const& path : output_files_) {
auto out = CollectOutputFileOrSymlink(exec_path, path);
if (not out) {
@@ -506,6 +617,9 @@ auto LocalAction::CollectAndStoreOutputs(
" - symlink {}: {}",
path,
out_symlink.target());
+ if (mode_ == RequestMode::kBestEffort) {
+ *result->mutable_output_symlinks()->Add() = out_symlink;
+ }
result->mutable_output_file_symlinks()->Add(
std::move(out_symlink));
}
@@ -530,6 +644,9 @@ auto LocalAction::CollectAndStoreOutputs(
" - symlink {}: {}",
path,
out_symlink.target());
+ if (mode_ == RequestMode::kBestEffort) {
+ *result->mutable_output_symlinks()->Add() = out_symlink;
+ }
result->mutable_output_directory_symlinks()->Add(
std::move(out_symlink));
}