summaryrefslogtreecommitdiff
path: root/src/buildtool/serve_api/serve_service/source_tree.cpp
diff options
context:
space:
mode:
authorPaul Cristian Sarbu <paul.cristian.sarbu@huawei.com>2024-04-05 11:48:13 +0200
committerPaul Cristian Sarbu <paul.cristian.sarbu@huawei.com>2024-04-10 14:06:21 +0200
commit4fe5fc8aec6e391a5e300e234bdc41375bff1d9e (patch)
treed5eb3cb68f5d44fc89f885667cf6242b0d137a99 /src/buildtool/serve_api/serve_service/source_tree.cpp
parent43ac36b4cd2b6aa0b42219f5920a7b4e72832ae5 (diff)
downloadjustbuild-4fe5fc8aec6e391a5e300e234bdc41375bff1d9e.tar.gz
resolve_symlinks_map: Allow separate source and target repositories
In certain cases, e.g., on the serve endpoint, an unresolved tree might lie in a repository other than the Git cache, therefore we cannot create any new entries there, as it would violate our guarantee that we only write under our local build root. Therefore, the resolve_symlinks_map now receives pointers to both the source and target Git databases and ensures that: 1. any tree created on-the-fly is stored exclusively in the target repository, and 2. any other entry required for those trees is made available in the target repository by copying it from the source repository. Note that in our use case the target repository is always our Git cache and passing a pointer to that object database is done to avoid the overhead of otherwise opening the database very often.
Diffstat (limited to 'src/buildtool/serve_api/serve_service/source_tree.cpp')
-rw-r--r--src/buildtool/serve_api/serve_service/source_tree.cpp29
1 files changed, 27 insertions, 2 deletions
diff --git a/src/buildtool/serve_api/serve_service/source_tree.cpp b/src/buildtool/serve_api/serve_service/source_tree.cpp
index 7a4a8828..4eeadf3f 100644
--- a/src/buildtool/serve_api/serve_service/source_tree.cpp
+++ b/src/buildtool/serve_api/serve_service/source_tree.cpp
@@ -375,6 +375,7 @@ auto SourceTreeService::SyncArchive(std::string const& tree_id,
auto SourceTreeService::ResolveContentTree(
std::string const& tree_id,
std::filesystem::path const& repo_path,
+ bool repo_is_git_cache,
std::optional<PragmaSpecial> const& resolve_special,
bool sync_tree,
ServeArchiveTreeResponse* response) -> ::grpc::Status {
@@ -396,7 +397,26 @@ auto SourceTreeService::ResolveContentTree(
return SyncArchive(
*resolved_tree_id, repo_path, sync_tree, response);
}
- // resolve tree
+ // resolve tree; target repository is always the Git cache
+ auto target_cas = GitCAS::Open(StorageConfig::GitRoot());
+ if (not target_cas) {
+ auto str = fmt::format("Failed to open Git ODB at {}",
+ StorageConfig::GitRoot().string());
+ logger_->Emit(LogLevel::Error, str);
+ response->set_status(ServeArchiveTreeResponse::INTERNAL_ERROR);
+ return ::grpc::Status::OK;
+ }
+ auto source_cas = target_cas;
+ if (not repo_is_git_cache) {
+ source_cas = GitCAS::Open(repo_path);
+ if (not source_cas) {
+ auto str = fmt::format("Failed to open Git ODB at {}",
+ repo_path.string());
+ logger_->Emit(LogLevel::Error, str);
+ response->set_status(ServeArchiveTreeResponse::INTERNAL_ERROR);
+ return ::grpc::Status::OK;
+ }
+ }
ResolvedGitObject resolved_tree{};
bool failed{false};
{
@@ -406,7 +426,9 @@ auto SourceTreeService::ResolveContentTree(
{GitObjectToResolve{tree_id,
".",
*resolve_special,
- /*known_info=*/std::nullopt}},
+ /*known_info=*/std::nullopt,
+ source_cas,
+ target_cas}},
[&resolved_tree](auto hashes) { resolved_tree = *hashes[0]; },
[logger = logger_, tree_id, &failed](auto const& msg,
bool fatal) {
@@ -625,6 +647,7 @@ auto SourceTreeService::ArchiveImportToGit(
}
return ResolveContentTree(*subtree_id,
StorageConfig::GitRoot(),
+ /*repo_is_git_cache=*/true,
resolve_special,
sync_tree,
response);
@@ -689,6 +712,7 @@ auto SourceTreeService::ServeArchiveTree(
if (std::holds_alternative<std::string>(res)) {
return ResolveContentTree(std::get<std::string>(res), // tree_id
StorageConfig::GitRoot(),
+ /*repo_is_git_cache=*/true,
resolve_special,
request->sync_tree(),
response);
@@ -709,6 +733,7 @@ auto SourceTreeService::ServeArchiveTree(
return ResolveContentTree(
std::get<std::string>(res), // tree_id
path,
+ /*repo_is_git_cache=*/false,
resolve_special,
request->sync_tree(),
response);