summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/other_tools/root_maps/TARGETS20
-rw-r--r--src/other_tools/root_maps/root_utils.cpp76
-rw-r--r--src/other_tools/root_maps/root_utils.hpp60
3 files changed, 156 insertions, 0 deletions
diff --git a/src/other_tools/root_maps/TARGETS b/src/other_tools/root_maps/TARGETS
index 5e7a40b7..4b0a62df 100644
--- a/src/other_tools/root_maps/TARGETS
+++ b/src/other_tools/root_maps/TARGETS
@@ -142,4 +142,24 @@
, ["src/buildtool/storage", "config"]
]
}
+, "root_utils":
+ { "type": ["@", "rules", "CC", "library"]
+ , "name": ["root_utils"]
+ , "hdrs": ["root_utils.hpp"]
+ , "srcs": ["root_utils.cpp"]
+ , "deps":
+ [ ["@", "gsl", "", "gsl"]
+ , ["src/buildtool/execution_api/common", "common"]
+ , ["src/buildtool/multithreading", "async_map_consumer"]
+ ]
+ , "stage": ["src", "other_tools", "root_maps"]
+ , "private-deps":
+ [ ["@", "fmt", "", "fmt"]
+ , ["src/buildtool/common", "common"]
+ , ["src/buildtool/common", "config"]
+ , ["src/buildtool/execution_api/git", "git"]
+ , ["src/buildtool/file_system", "object_type"]
+ , ["src/buildtool/serve_api/remote", "serve_api"]
+ ]
+ }
}
diff --git a/src/other_tools/root_maps/root_utils.cpp b/src/other_tools/root_maps/root_utils.cpp
new file mode 100644
index 00000000..f9815d88
--- /dev/null
+++ b/src/other_tools/root_maps/root_utils.cpp
@@ -0,0 +1,76 @@
+// 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/other_tools/root_maps/root_utils.hpp"
+
+#include "fmt/core.h"
+#include "src/buildtool/common/artifact.hpp"
+#include "src/buildtool/common/artifact_digest.hpp"
+#include "src/buildtool/common/repository_config.hpp"
+#include "src/buildtool/execution_api/git/git_api.hpp"
+#include "src/buildtool/file_system/object_type.hpp"
+#include "src/buildtool/serve_api/remote/serve_api.hpp"
+
+auto CheckServeHasAbsentRoot(std::string const& tree_id,
+ AsyncMapConsumerLoggerPtr const& logger)
+ -> std::optional<bool> {
+ if (auto has_tree = ServeApi::CheckRootTree(tree_id)) {
+ return *has_tree;
+ }
+ (*logger)(fmt::format("Checking that the serve endpoint knows tree "
+ "{} failed.",
+ tree_id),
+ /*fatal=*/true);
+ return std::nullopt;
+}
+
+auto EnsureAbsentRootOnServe(
+ std::string const& tree_id,
+ std::filesystem::path const& repo_path,
+ std::optional<gsl::not_null<IExecutionApi*>> const& remote_api,
+ AsyncMapConsumerLoggerPtr const& logger,
+ bool no_sync_is_fatal) -> bool {
+ if (remote_api) {
+ // upload tree to remote CAS
+ auto repo = RepositoryConfig{};
+ if (not repo.SetGitCAS(repo_path)) {
+ (*logger)(
+ fmt::format("Failed to SetGitCAS at {}", repo_path.string()),
+ /*fatal=*/true);
+ return false;
+ }
+ auto git_api = GitApi{&repo};
+ if (not git_api.RetrieveToCas(
+ {Artifact::ObjectInfo{
+ .digest = ArtifactDigest{tree_id, 0, /*is_tree=*/true},
+ .type = ObjectType::Tree}},
+ *remote_api)) {
+ (*logger)(fmt::format("Failed to sync tree {} from repository {}",
+ tree_id,
+ repo_path.string()),
+ /*fatal=*/true);
+ return false;
+ }
+ }
+ // ask serve endpoint to retrieve the uploaded tree
+ if (not ServeApi::GetTreeFromRemote(tree_id)) {
+ // respond based on no_sync_is_fatal flag
+ (*logger)(
+ fmt::format("Serve endpoint failed to sync root tree {}.", tree_id),
+ /*fatal=*/no_sync_is_fatal);
+ return not no_sync_is_fatal;
+ }
+ // done!
+ return true;
+}
diff --git a/src/other_tools/root_maps/root_utils.hpp b/src/other_tools/root_maps/root_utils.hpp
new file mode 100644
index 00000000..bf50e04d
--- /dev/null
+++ b/src/other_tools/root_maps/root_utils.hpp
@@ -0,0 +1,60 @@
+// 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_OTHER_TOOLS_ROOT_MAPS_ROOT_UTILS_HPP
+#define INCLUDED_SRC_OTHER_TOOLS_ROOT_MAPS_ROOT_UTILS_HPP
+
+#include <optional>
+#include <string>
+
+#include "gsl/gsl"
+#include "src/buildtool/execution_api/common/execution_api.hpp"
+#include "src/buildtool/multithreading/async_map_consumer.hpp"
+
+/// \brief Calls the ServeApi to check whether the serve endpoint has the given
+/// tree available to build against.
+/// \param tree_id The Git-tree identifier.
+/// \param logger An AsyncMapConsumer logger instance.
+/// \returns Nullopt if an error in the ServeApi call ocurred, or a flag stating
+/// whether the serve endpoint knows the tree on ServeApi call success. The
+/// logger is called with fatal ONLY if this method returns nullopt.
+[[nodiscard]] auto CheckServeHasAbsentRoot(
+ std::string const& tree_id,
+ AsyncMapConsumerLoggerPtr const& logger) -> std::optional<bool>;
+
+/// \brief Calls the ServeApi to instruct the serve endpoint to set up a root
+/// defined by a given tree by retrieving it from the remote CAS. This method
+/// ensures the respective tree is in the remote CAS prior to the ServeApi call
+/// by uploading it to the remote CAS if it is missing.
+/// \param tree_id The Git-tree identifier.
+/// \param repo_path Local witnessing Git repository for the tree.
+/// \param remote_api Optional API of the remote-execution endpoint. If nullopt,
+/// skip the upload to the remote CAS; this assumes prior knowledge which
+/// guarantees the tree given by tree_id exists in the remote CAS for the
+/// duration of the subsequent serve API call; this option should be used
+/// carefully, but does result in less remote communication.
+/// \param logger An AsyncMapConsumer logger instance.
+/// \param no_sync_is_fatal If true, report only as a warning the failure of the
+/// serve endpoint to set up the root for this tree; otherwise, this is reported
+/// as fatal.
+/// \returns Status flag, with false if state is deemed fatal, and true
+/// otherwise. Logger is only called with fatal if returning false.
+[[nodiscard]] auto EnsureAbsentRootOnServe(
+ std::string const& tree_id,
+ std::filesystem::path const& repo_path,
+ std::optional<gsl::not_null<IExecutionApi*>> const& remote_api,
+ AsyncMapConsumerLoggerPtr const& logger,
+ bool no_sync_is_fatal) -> bool;
+
+#endif // INCLUDED_SRC_OTHER_TOOLS_ROOT_MAPS_ROOT_UTILS_HPP