diff options
author | Klaus Aehlig <klaus.aehlig@huawei.com> | 2024-03-18 12:56:24 +0100 |
---|---|---|
committer | Klaus Aehlig <klaus.aehlig@huawei.com> | 2024-03-20 12:55:30 +0100 |
commit | 9f07b2e98e9e8bfa8aeef2a4b292cd0e3bc57424 (patch) | |
tree | c8c2b5c499ad88709ebcd0993727d22b6b401909 /src | |
parent | e18e0bfe533f5f22a32aae28e6ddd486bdbd4d7d (diff) | |
download | justbuild-9f07b2e98e9e8bfa8aeef2a4b292cd0e3bc57424.tar.gz |
Add functionality to add local files to CAS
... and optionally upload them to a remote-execution endpoint.
Diffstat (limited to 'src')
-rw-r--r-- | src/buildtool/main/TARGETS | 21 | ||||
-rw-r--r-- | src/buildtool/main/add_to_cas.cpp | 113 | ||||
-rw-r--r-- | src/buildtool/main/add_to_cas.hpp | 28 |
3 files changed, 162 insertions, 0 deletions
diff --git a/src/buildtool/main/TARGETS b/src/buildtool/main/TARGETS index d2d3c1fa..7f293ee5 100644 --- a/src/buildtool/main/TARGETS +++ b/src/buildtool/main/TARGETS @@ -120,6 +120,27 @@ , ["src/buildtool/execution_api/utils", "subobject"] ] } +, "add_to_cas": + { "type": ["@", "rules", "CC", "library"] + , "name": ["add_to_cas"] + , "hdrs": ["add_to_cas.hpp"] + , "srcs": ["add_to_cas.cpp"] + , "deps": + [ ["@", "gsl", "", "gsl"] + , ["src/buildtool/common", "cli"] + , ["src/buildtool/execution_api/common", "common"] + ] + , "private-deps": + [ ["src/buildtool/compatibility", "compatibility"] + , ["src/buildtool/execution_api/bazel_msg", "bazel_msg_factory"] + , ["src/buildtool/execution_api/local", "local"] + , ["src/buildtool/file_system", "file_system_manager"] + , ["src/buildtool/logging", "log_level"] + , ["src/buildtool/logging", "logging"] + , ["src/buildtool/storage", "storage"] + ] + , "stage": ["src", "buildtool", "main"] + } , "analyse": { "type": ["@", "rules", "CC", "library"] , "name": ["analyse"] diff --git a/src/buildtool/main/add_to_cas.cpp b/src/buildtool/main/add_to_cas.cpp new file mode 100644 index 00000000..0d13f881 --- /dev/null +++ b/src/buildtool/main/add_to_cas.cpp @@ -0,0 +1,113 @@ +// Copyright 2024 Huawei Cloud Computing Technology Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "src/buildtool/main/add_to_cas.hpp" + +#ifndef BOOTSTRAP_BUILD_TOOL + +#include <iostream> + +#include "src/buildtool/compatibility/native_support.hpp" +#include "src/buildtool/execution_api/bazel_msg/bazel_msg_factory.hpp" +#include "src/buildtool/execution_api/local/local_api.hpp" +#include "src/buildtool/file_system/file_system_manager.hpp" +#include "src/buildtool/logging/log_level.hpp" +#include "src/buildtool/logging/logger.hpp" +#include "src/buildtool/storage/storage.hpp" + +auto AddArtifactsToCas(ToAddArguments const& clargs, + gsl::not_null<IExecutionApi*> const& remote_api) + -> bool { + + auto const& cas = Storage::Instance().CAS(); + std::optional<bazel_re::Digest> digest{}; + auto object_location = clargs.location; + + if (clargs.follow_symlinks) { + if (not FileSystemManager::ResolveSymlinks(&object_location)) { + Logger::Log(LogLevel::Error, + "Failed resolving {}", + clargs.location.string()); + return false; + } + } + + auto object_type = + FileSystemManager::Type(object_location, /*allow_upwards=*/true); + if (not object_type) { + Logger::Log(LogLevel::Error, + "Non existent or unsupported file-system entry at {}", + object_location.string()); + return false; + } + + switch (*object_type) { + case ObjectType::File: + digest = cas.StoreBlob(object_location, /*is_executable=*/false); + break; + case ObjectType::Executable: + digest = cas.StoreBlob(object_location, /*is_executable=*/true); + break; + case ObjectType::Symlink: { + auto content = FileSystemManager::ReadSymlink(object_location); + if (not content) { + Logger::Log(LogLevel::Error, + "Failed to read symlink at {}", + object_location.string()); + return false; + } + digest = cas.StoreBlob(*content, /*is_executable=*/false); + } break; + case ObjectType::Tree: { + if (Compatibility::IsCompatible()) { + Logger::Log(LogLevel::Error, + "Storing of trees only supported in native mode"); + return false; + } + auto store_blob = [&cas](auto path, auto is_exec) { + return cas.StoreBlob(path, is_exec); + }; + auto store_tree = [&cas](auto bytes, auto /*dir*/) { + return cas.StoreTree(bytes); + }; + auto store_symlink = [&cas](auto content) { + return cas.StoreBlob(content); + }; + digest = BazelMsgFactory::CreateGitTreeDigestFromLocalTree( + clargs.location, store_blob, store_tree, store_symlink); + } break; + } + + if (not digest) { + Logger::Log(LogLevel::Error, + "Failed to store {} in local CAS", + clargs.location.string()); + return false; + } + + std::cout << NativeSupport::Unprefix(digest->hash()) << std::endl; + + auto object = std::vector<Artifact::ObjectInfo>{ + Artifact::ObjectInfo{ArtifactDigest(*digest), *object_type, false}}; + + if (not LocalApi().RetrieveToCas(object, remote_api)) { + Logger::Log(LogLevel::Error, + "Failed to upload artifact to remote endpoint"); + return false; + } + + return true; +} + +#endif diff --git a/src/buildtool/main/add_to_cas.hpp b/src/buildtool/main/add_to_cas.hpp new file mode 100644 index 00000000..3a2cafce --- /dev/null +++ b/src/buildtool/main/add_to_cas.hpp @@ -0,0 +1,28 @@ +// Copyright 2024 Huawei Cloud Computing Technology Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDED_SRC_BUILDTOOL_MAIN_ADD_TO_CAS_HPP +#define INCLUDED_SRC_BUILDTOOL_MAIN_ADD_TO_CAS_HPP +#ifndef BOOTSTRAP_BUILD_TOOL + +#include "gsl/gsl" +#include "src/buildtool/common/cli.hpp" +#include "src/buildtool/execution_api/common/execution_api.hpp" + +[[nodiscard]] auto AddArtifactsToCas( + ToAddArguments const& clargs, + gsl::not_null<IExecutionApi*> const& remote_api) -> bool; + +#endif +#endif |