diff options
Diffstat (limited to 'src')
10 files changed, 56 insertions, 35 deletions
diff --git a/src/buildtool/execution_api/bazel_msg/bazel_blob.hpp b/src/buildtool/execution_api/bazel_msg/bazel_blob.hpp index 5e92a393..15845c08 100644 --- a/src/buildtool/execution_api/bazel_msg/bazel_blob.hpp +++ b/src/buildtool/execution_api/bazel_msg/bazel_blob.hpp @@ -25,22 +25,30 @@ #include "src/buildtool/file_system/file_system_manager.hpp" struct BazelBlob { - BazelBlob(bazel_re::Digest mydigest, std::string mydata) - : digest{std::move(mydigest)}, data{std::move(mydata)} {} + BazelBlob(bazel_re::Digest mydigest, std::string mydata, bool is_exec) + : digest{std::move(mydigest)}, + data{std::move(mydata)}, + is_exec{is_exec} {} bazel_re::Digest digest{}; std::string data{}; + bool is_exec{}; // optional: hint to put the blob in executable CAS }; [[nodiscard]] static inline auto CreateBlobFromFile( std::filesystem::path const& file_path) noexcept -> std::optional<BazelBlob> { - auto const content = FileSystemManager::ReadFile(file_path); + auto const type = FileSystemManager::Type(file_path); + if (not type) { + return std::nullopt; + } + auto const content = FileSystemManager::ReadFile(file_path, *type); if (not content.has_value()) { return std::nullopt; } return BazelBlob{ArtifactDigest::Create<ObjectType::File>(*content), - *content}; + *content, + IsExecutableObject(*type)}; } #endif // INCLUDED_SRC_BUILDTOOL_EXECUTION_API_BAZEL_MSG_BAZEL_BLOB_HPP diff --git a/src/buildtool/execution_api/bazel_msg/bazel_blob_container.hpp b/src/buildtool/execution_api/bazel_msg/bazel_blob_container.hpp index 54d10331..5ebc72bd 100644 --- a/src/buildtool/execution_api/bazel_msg/bazel_blob_container.hpp +++ b/src/buildtool/execution_api/bazel_msg/bazel_blob_container.hpp @@ -189,7 +189,8 @@ class BlobContainer { private: static inline BazelBlob const kEmpty{bazel_re::Digest{}, - std::string{}}; + std::string{}, + /*is_exec=*/false}; gsl::not_null<underlaying_map_t const*> blobs_; }; diff --git a/src/buildtool/execution_api/bazel_msg/bazel_msg_factory.cpp b/src/buildtool/execution_api/bazel_msg/bazel_msg_factory.cpp index 1ca23c34..ef8b2f5d 100644 --- a/src/buildtool/execution_api/bazel_msg/bazel_msg_factory.cpp +++ b/src/buildtool/execution_api/bazel_msg/bazel_msg_factory.cpp @@ -53,8 +53,8 @@ class IBundle { -> std::string const& = 0; [[nodiscard]] virtual auto Digest() const& noexcept -> bazel_re::Digest const& = 0; - [[nodiscard]] auto MakeBlob() const noexcept -> BazelBlob { - return BazelBlob{Digest(), Content()}; + [[nodiscard]] auto MakeBlob(bool is_exec) const noexcept -> BazelBlob { + return BazelBlob{Digest(), Content(), is_exec}; } }; @@ -382,7 +382,7 @@ template <class T> } dir_nodes.push_back(dir_bundle->Message()); if (store_blob) { - (*store_blob)(dir_bundle->MakeBlob()); + (*store_blob)(dir_bundle->MakeBlob(/*is_exec=*/false)); } } else { @@ -472,7 +472,7 @@ auto BazelMsgFactory::CreateDirectoryDigestFromTree( if (auto bundle = DirectoryTreeToBundle("", tree, store_blob, store_info)) { if (store_blob) { try { - (*store_blob)(bundle->MakeBlob()); + (*store_blob)(bundle->MakeBlob(/*is_exec=*/false)); } catch (...) { return std::nullopt; } @@ -627,8 +627,8 @@ auto BazelMsgFactory::CreateActionDigestFromCommandLine( cmd->Digest(), exec_dir, output_node_properties, do_not_cache, timeout); if (store_blob) { - (*store_blob)(cmd->MakeBlob()); - (*store_blob)(action->MakeBlob()); + (*store_blob)(cmd->MakeBlob(/*is_exec=*/false)); + (*store_blob)(action->MakeBlob(/*is_exec=*/false)); } return action->Digest(); diff --git a/src/buildtool/execution_api/bazel_msg/blob_tree.cpp b/src/buildtool/execution_api/bazel_msg/blob_tree.cpp index 3e5e2fa6..88797970 100644 --- a/src/buildtool/execution_api/bazel_msg/blob_tree.cpp +++ b/src/buildtool/execution_api/bazel_msg/blob_tree.cpp @@ -69,8 +69,10 @@ auto BlobTree::FromDirectoryTree(DirectoryTreePtr const& tree, /*is_tree=*/true)); digest.set_size_bytes( gsl::narrow<google::protobuf::int64>(git_tree->second.size())); - return std::make_shared<BlobTree>( - BazelBlob{digest, git_tree->second}, nodes); + return std::make_shared<BlobTree>(BazelBlob{digest, + git_tree->second, + /*is_exec=*/false}, + nodes); } } catch (...) { return std::nullopt; diff --git a/src/buildtool/execution_api/local/local_api.hpp b/src/buildtool/execution_api/local/local_api.hpp index 02fa4fa6..1528ff23 100644 --- a/src/buildtool/execution_api/local/local_api.hpp +++ b/src/buildtool/execution_api/local/local_api.hpp @@ -194,7 +194,8 @@ class LocalApi final : public IExecutionApi { // Collect blob. try { - container.Emplace(BazelBlob{digest, *content}); + container.Emplace( + BazelBlob{digest, *content, IsExecutableObject(info.type)}); } catch (std::exception const& ex) { Logger::Log( LogLevel::Error, "failed to emplace blob: ", ex.what()); @@ -211,8 +212,9 @@ class LocalApi final : public IExecutionApi { -> bool final { for (auto const& blob : blobs) { auto const is_tree = NativeSupport::IsTree(blob.digest.hash()); - auto cas_digest = is_tree ? storage_->StoreTree(blob.data) - : storage_->StoreBlob(blob.data); + auto cas_digest = + is_tree ? storage_->StoreTree(blob.data) + : storage_->StoreBlob(blob.data, blob.is_exec); if (not cas_digest or not std::equal_to<bazel_re::Digest>{}( *cas_digest, blob.digest)) { return false; diff --git a/src/buildtool/execution_api/remote/bazel/bazel_api.cpp b/src/buildtool/execution_api/remote/bazel/bazel_api.cpp index a192737f..ce25c51c 100644 --- a/src/buildtool/execution_api/remote/bazel/bazel_api.cpp +++ b/src/buildtool/execution_api/remote/bazel/bazel_api.cpp @@ -219,7 +219,9 @@ auto BazelApi::CreateAction( } for (auto& blob : blobs) { try { - container.Emplace(std::move(blob)); + auto exec = IsExecutableObject( + info_map[ArtifactDigest{blob.digest}].type); + container.Emplace(BazelBlob{blob.digest, blob.data, exec}); } catch (std::exception const& ex) { Logger::Log( LogLevel::Error, "failed to emplace blob: ", ex.what()); diff --git a/src/buildtool/execution_api/remote/bazel/bazel_cas_client.cpp b/src/buildtool/execution_api/remote/bazel/bazel_cas_client.cpp index 232c5c08..6dd2e9e3 100644 --- a/src/buildtool/execution_api/remote/bazel/bazel_cas_client.cpp +++ b/src/buildtool/execution_api/remote/bazel/bazel_cas_client.cpp @@ -95,7 +95,7 @@ auto BazelCasClient::BatchReadBlobs( response, [](std::vector<BazelBlob>* v, bazel_re::BatchReadBlobsResponse_Response const& r) { - v->emplace_back(r.digest(), r.data()); + v->emplace_back(r.digest(), r.data(), /*is_exec=*/false); }); } else { @@ -189,7 +189,8 @@ auto BazelCasClient::ReadSingleBlob(std::string const& instance_name, digest.hash(), real_digest.hash()); } - return BazelBlob{std::move(real_digest), std::move(*data)}; + return BazelBlob{ + std::move(real_digest), std::move(*data), /*is_exec=*/false}; } return std::nullopt; } diff --git a/src/buildtool/execution_api/remote/bazel/bazel_response.cpp b/src/buildtool/execution_api/remote/bazel/bazel_response.cpp index 615c0177..ddebd648 100644 --- a/src/buildtool/execution_api/remote/bazel/bazel_response.cpp +++ b/src/buildtool/execution_api/remote/bazel/bazel_response.cpp @@ -25,7 +25,7 @@ auto ProcessDirectoryMessage(bazel_re::Directory const& dir) noexcept -> std::optional<BazelBlob> { auto data = dir.SerializeAsString(); auto digest = ArtifactDigest::Create<ObjectType::File>(data); - return BazelBlob{std::move(digest), std::move(data)}; + return BazelBlob{std::move(digest), std::move(data), /*is_exec=*/false}; } } // namespace diff --git a/src/buildtool/execution_engine/executor/executor.hpp b/src/buildtool/execution_engine/executor/executor.hpp index e5dcc5a9..cd9246ba 100644 --- a/src/buildtool/execution_engine/executor/executor.hpp +++ b/src/buildtool/execution_engine/executor/executor.hpp @@ -155,7 +155,7 @@ class ExecutorImpl { if (not VerifyOrUploadKnownArtifact( remote_api, artifact->Content().Repository(), - object_info_opt->digest)) { + *object_info_opt)) { Logger::Log( LogLevel::Error, "artifact {} should be present in CAS but is missing.", @@ -256,8 +256,10 @@ class ExecutorImpl { return false; } try { - container.Emplace( - std::move(BazelBlob{digest, std::move(*content)})); + container.Emplace(std::move( + BazelBlob{digest, + std::move(*content), + IsExecutableObject(entry->Type())})); } catch (std::exception const& ex) { Logger::Log(LogLevel::Error, "failed to create blob with: ", @@ -273,17 +275,17 @@ class ExecutorImpl { /// \brief Lookup blob via digest in local git repositories and upload. /// \param api The endpoint used for uploading /// \param repo The global repository name, the artifact belongs to - /// \param digest The digest of the object + /// \param info The info of the object /// \param hash The git-sha1 hash of the object /// \returns true on success [[nodiscard]] static auto VerifyOrUploadGitArtifact( gsl::not_null<IExecutionApi*> const& api, std::string const& repo, - ArtifactDigest const& digest, + Artifact::ObjectInfo const& info, std::string const& hash) noexcept -> bool { std::optional<std::string> content; if (NativeSupport::IsTree( - static_cast<bazel_re::Digest>(digest).hash())) { + static_cast<bazel_re::Digest>(info.digest).hash())) { // if known tree is not available, recursively upload its content auto tree = ReadGitTree(repo, hash); if (not tree) { @@ -303,8 +305,8 @@ class ExecutorImpl { } // upload artifact content - auto container = - BlobContainer{{BazelBlob{digest, std::move(*content)}}}; + auto container = BlobContainer{{BazelBlob{ + info.digest, std::move(*content), IsExecutableObject(info.type)}}}; return api->Upload(container, /*skip_find_missing=*/true); } @@ -343,22 +345,22 @@ class ExecutorImpl { /// \brief Lookup blob via digest in local git repositories and upload. /// \param api The endpoint used for uploading /// \param repo The global repository name, the artifact belongs to - /// \param digest The digest of the object + /// \param info The info of the object /// \returns true on success [[nodiscard]] static auto VerifyOrUploadKnownArtifact( gsl::not_null<IExecutionApi*> const& api, std::string const& repo, - ArtifactDigest const& digest) noexcept -> bool { + Artifact::ObjectInfo const& info) noexcept -> bool { if (Compatibility::IsCompatible()) { - auto opt = Compatibility::GetGitEntry(digest.hash()); + auto opt = Compatibility::GetGitEntry(info.digest.hash()); if (opt) { auto const& [git_sha1_hash, comp_repo] = *opt; return VerifyOrUploadGitArtifact( - api, comp_repo, digest, git_sha1_hash); + api, comp_repo, info, git_sha1_hash); } return false; } - return VerifyOrUploadGitArtifact(api, repo, digest, digest.hash()); + return VerifyOrUploadGitArtifact(api, repo, info, info.digest.hash()); } /// \brief Lookup file via path in local workspace root and upload. @@ -385,7 +387,9 @@ class ExecutorImpl { } auto digest = ArtifactDigest::Create<ObjectType::File>(*content); if (not api->Upload( - BlobContainer{{BazelBlob{digest, std::move(*content)}}})) { + BlobContainer{{BazelBlob{digest, + std::move(*content), + IsExecutableObject(*object_type)}}})) { return std::nullopt; } return Artifact::ObjectInfo{std::move(digest), *object_type}; diff --git a/src/buildtool/graph_traverser/graph_traverser.hpp b/src/buildtool/graph_traverser/graph_traverser.hpp index 063c1b85..d5e155fa 100644 --- a/src/buildtool/graph_traverser/graph_traverser.hpp +++ b/src/buildtool/graph_traverser/graph_traverser.hpp @@ -293,7 +293,8 @@ class GraphTraverser { digest.size()); }); try { - container.Emplace(BazelBlob{std::move(digest), blob}); + container.Emplace( + BazelBlob{std::move(digest), blob, /*is_exec=*/false}); } catch (std::exception const& ex) { Logger::Log( LogLevel::Error, "failed to create blob with: ", ex.what()); |