summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaksim Denisov <denisov.maksim@huawei.com>2024-09-10 11:37:27 +0200
committerMaksim Denisov <denisov.maksim@huawei.com>2024-09-11 14:52:07 +0200
commit4249d4758cb50238d24e5631af50b0e363e9e789 (patch)
tree25947ea93c5b519dc2fae23a7af3257f510d471c /src
parent9718018d3650c43075334b5eaf9ba91fbbfb88b4 (diff)
downloadjustbuild-4249d4758cb50238d24e5631af50b0e363e9e789.tar.gz
Use ArtifactDigestFactory in SourceTreeService
...to create ArtifactDigests.
Diffstat (limited to 'src')
-rw-r--r--src/buildtool/serve_api/serve_service/TARGETS2
-rw-r--r--src/buildtool/serve_api/serve_service/source_tree.cpp94
2 files changed, 59 insertions, 37 deletions
diff --git a/src/buildtool/serve_api/serve_service/TARGETS b/src/buildtool/serve_api/serve_service/TARGETS
index 7bcb583e..ed67bcdf 100644
--- a/src/buildtool/serve_api/serve_service/TARGETS
+++ b/src/buildtool/serve_api/serve_service/TARGETS
@@ -33,6 +33,7 @@
, "private-deps":
[ ["@", "fmt", "", "fmt"]
, ["src/buildtool/common", "common"]
+ , ["src/buildtool/common", "artifact_digest_factory"]
, ["src/buildtool/compatibility", "compatibility"]
, ["src/buildtool/file_system", "git_repo"]
, ["src/buildtool/logging", "log_level"]
@@ -41,6 +42,7 @@
, ["src/utils/archive", "archive_ops"]
, ["src/buildtool/execution_api/git", "git"]
, ["src/buildtool/crypto", "hash_function"]
+ , ["src/utils/cpp", "expected"]
]
}
, "serve_server_implementation":
diff --git a/src/buildtool/serve_api/serve_service/source_tree.cpp b/src/buildtool/serve_api/serve_service/source_tree.cpp
index d2ba33f6..acc29ba9 100644
--- a/src/buildtool/serve_api/serve_service/source_tree.cpp
+++ b/src/buildtool/serve_api/serve_service/source_tree.cpp
@@ -23,6 +23,7 @@
#include "fmt/core.h"
#include "src/buildtool/common/artifact.hpp"
#include "src/buildtool/common/artifact_digest.hpp"
+#include "src/buildtool/common/artifact_digest_factory.hpp"
#include "src/buildtool/compatibility/compatibility.hpp"
#include "src/buildtool/crypto/hash_function.hpp"
#include "src/buildtool/execution_api/git/git_api.hpp"
@@ -34,6 +35,7 @@
#include "src/buildtool/storage/garbage_collector.hpp"
#include "src/buildtool/storage/repository_garbage_collector.hpp"
#include "src/utils/archive/archive_ops.hpp"
+#include "src/utils/cpp/expected.hpp"
namespace {
@@ -294,17 +296,25 @@ auto SourceTreeService::SyncGitEntryToCas(
return TResponse::SYNC_ERROR;
}
- auto digest = ArtifactDigest{object_hash, 0, IsTreeObject(kType)};
auto repo = RepositoryConfig{};
if (not repo.SetGitCAS(repo_path)) {
logger_->Emit(
LogLevel::Error, "Failed to SetGitCAS at {}", repo_path.string());
return TResponse::INTERNAL_ERROR;
}
+ auto const digest =
+ ArtifactDigestFactory::Create(storage_config_.hash_function.GetType(),
+ object_hash,
+ 0,
+ IsTreeObject(kType));
+ if (not digest) {
+ logger_->Emit(LogLevel::Error, "{}", digest.error());
+ return TResponse::INTERNAL_ERROR;
+ }
auto git_api = GitApi{&repo};
if (not git_api.RetrieveToCas(
- {Artifact::ObjectInfo{.digest = digest, .type = kType}},
+ {Artifact::ObjectInfo{.digest = *digest, .type = kType}},
*apis_.remote)) {
logger_->Emit(LogLevel::Error,
"Failed to sync object {} from repository {}",
@@ -754,9 +764,11 @@ auto SourceTreeService::ServeArchiveTree(
return ::grpc::Status::OK;
}
// check if content is in local CAS already
- auto digest = ArtifactDigest(content, 0, false);
+ auto const digest = ArtifactDigestFactory::Create(
+ storage_config_.hash_function.GetType(), content, 0, /*is_tree=*/false);
auto const& cas = storage_.CAS();
- auto content_cas_path = cas.BlobPath(digest, /*is_executable=*/false);
+ auto content_cas_path =
+ digest ? cas.BlobPath(*digest, /*is_executable=*/false) : std::nullopt;
if (not content_cas_path) {
// check if content blob is in Git cache
auto res = GetBlobFromRepo(storage_config_.GitRoot(), content, logger_);
@@ -796,11 +808,11 @@ auto SourceTreeService::ServeArchiveTree(
}
}
}
- if (not content_cas_path) {
+ if (digest and not content_cas_path) {
// try to retrieve it from remote CAS
- if (not(apis_.remote->IsAvailable(digest) and
+ if (not(apis_.remote->IsAvailable(*digest) and
apis_.remote->RetrieveToCas(
- {Artifact::ObjectInfo{.digest = digest,
+ {Artifact::ObjectInfo{.digest = *digest,
.type = ObjectType::File}},
*apis_.local))) {
// content could not be found
@@ -808,7 +820,7 @@ auto SourceTreeService::ServeArchiveTree(
return ::grpc::Status::OK;
}
// content should now be in CAS
- content_cas_path = cas.BlobPath(digest, /*is_executable=*/false);
+ content_cas_path = cas.BlobPath(*digest, /*is_executable=*/false);
if (not content_cas_path) {
logger_->Emit(LogLevel::Error,
"Retrieving content {} from CAS failed unexpectedly",
@@ -879,9 +891,15 @@ auto SourceTreeService::DistdirImportToGit(
content_list.begin(),
content_list.end(),
[&cas, tmp_path](auto const& kv) {
- auto content_path = cas.BlobPath(
- ArtifactDigest(kv.second.first, 0, /*is_tree=*/false),
- kv.second.second);
+ auto const digest = ArtifactDigestFactory::Create(
+ cas.GetHashFunction().GetType(),
+ kv.second.first,
+ 0,
+ /*is_tree=*/false);
+ if (not digest) {
+ return false;
+ }
+ auto content_path = cas.BlobPath(*digest, kv.second.second);
if (content_path) {
return FileSystemManager::CreateFileHardlink(
*content_path, // from: cas_path/content_id
@@ -960,10 +978,14 @@ auto SourceTreeService::ServeDistdirTree(
// check content blob is known
// first check the local CAS itself, provided it uses the same type
// of identifier
+ auto const digest = ArtifactDigestFactory::Create(
+ storage_config_.hash_function.GetType(),
+ content,
+ 0,
+ /*is_tree=*/false);
+
if (not Compatibility::IsCompatible()) {
- auto digest = ArtifactDigest(content, 0, /*is_tree=*/false);
- blob_found =
- static_cast<bool>(cas.BlobPath(digest, kv.executable()));
+ blob_found = digest and cas.BlobPath(*digest, kv.executable());
}
if (blob_found) {
blob_digest = content;
@@ -1031,19 +1053,13 @@ auto SourceTreeService::ServeDistdirTree(
}
}
if (not blob_found) {
- // Explanation: clang-tidy gets confused by the break in the
- // for-loop above into falsely believing that it can reach
- // this point with the variable "digest" already moved, so
- // we work around this by creating a new variable here
- auto digest_clone =
- ArtifactDigest(content, 0, /*is_tree=*/false);
// check remote CAS
- if ((not Compatibility::IsCompatible()) and
- apis_.remote->IsAvailable(digest_clone)) {
+ if (not Compatibility::IsCompatible() and digest and
+ apis_.remote->IsAvailable(*digest)) {
// retrieve content to local CAS
if (not apis_.remote->RetrieveToCas(
{Artifact::ObjectInfo{
- .digest = digest_clone,
+ .digest = *digest,
.type = kv.executable()
? ObjectType::Executable
: ObjectType::File}},
@@ -1221,10 +1237,11 @@ auto SourceTreeService::ServeContent(
}
// check also in the local CAS
- auto const digest = ArtifactDigest{content, 0, /*is_tree=*/false};
- if (apis_.local->IsAvailable(digest)) {
+ auto const digest = ArtifactDigestFactory::Create(
+ storage_config_.hash_function.GetType(), content, 0, /*is_tree=*/false);
+ if (digest and apis_.local->IsAvailable(*digest)) {
if (not apis_.local->RetrieveToCas(
- {Artifact::ObjectInfo{.digest = digest,
+ {Artifact::ObjectInfo{.digest = *digest,
.type = ObjectType::File}},
*apis_.remote)) {
logger_->Emit(LogLevel::Error,
@@ -1299,8 +1316,9 @@ auto SourceTreeService::ServeTree(
}
}
// check also in the local CAS
- auto digest = ArtifactDigest{tree_id, 0, /*is_tree=*/true};
- if (apis_.local->IsAvailable(digest)) {
+ auto const digest = ArtifactDigestFactory::Create(
+ storage_config_.hash_function.GetType(), tree_id, 0, /*is_tree=*/true);
+ if (digest and apis_.local->IsAvailable(*digest)) {
// upload tree to remote CAS; only possible in native mode
if (Compatibility::IsCompatible()) {
logger_->Emit(LogLevel::Error,
@@ -1311,7 +1329,7 @@ auto SourceTreeService::ServeTree(
return ::grpc::Status::OK;
}
if (not apis_.local->RetrieveToCas(
- {Artifact::ObjectInfo{.digest = digest,
+ {Artifact::ObjectInfo{.digest = *digest,
.type = ObjectType::Tree}},
*apis_.remote)) {
logger_->Emit(LogLevel::Error,
@@ -1381,8 +1399,9 @@ auto SourceTreeService::CheckRootTree(
}
}
// now check in the local CAS
- auto digest = ArtifactDigest{tree_id, 0, /*is_tree=*/true};
- if (auto path = storage_.CAS().TreePath(digest)) {
+ auto const digest = ArtifactDigestFactory::Create(
+ storage_config_.hash_function.GetType(), tree_id, 0, /*is_tree=*/true);
+ if (digest and storage_.CAS().TreePath(*digest)) {
// As we currently build only against roots in Git repositories, we need
// to move the tree from CAS to local Git storage
auto tmp_dir =
@@ -1391,12 +1410,12 @@ auto SourceTreeService::CheckRootTree(
logger_->Emit(LogLevel::Error,
"Failed to create tmp directory for copying git-tree "
"{} from remote CAS",
- digest.hash());
+ digest->hash());
response->set_status(CheckRootTreeResponse::INTERNAL_ERROR);
return ::grpc::Status::OK;
}
if (not apis_.local->RetrieveToPaths(
- {Artifact::ObjectInfo{.digest = digest,
+ {Artifact::ObjectInfo{.digest = *digest,
.type = ObjectType::Tree}},
{tmp_dir->GetPath()})) {
logger_->Emit(LogLevel::Error,
@@ -1451,8 +1470,9 @@ auto SourceTreeService::GetRemoteTree(
}
// get tree from remote CAS into tmp dir
- auto digest = ArtifactDigest{tree_id, 0, /*is_tree=*/true};
- if (not apis_.remote->IsAvailable(digest)) {
+ auto const digest = ArtifactDigestFactory::Create(
+ storage_config_.hash_function.GetType(), tree_id, 0, /*is_tree=*/true);
+ if (not digest or not apis_.remote->IsAvailable(*digest)) {
logger_->Emit(LogLevel::Error,
"Remote CAS does not contain expected tree {}",
tree_id);
@@ -1465,12 +1485,12 @@ auto SourceTreeService::GetRemoteTree(
logger_->Emit(LogLevel::Error,
"Failed to create tmp directory for copying git-tree {} "
"from remote CAS",
- digest.hash());
+ digest->hash());
response->set_status(GetRemoteTreeResponse::INTERNAL_ERROR);
return ::grpc::Status::OK;
}
if (not apis_.remote->RetrieveToPaths(
- {Artifact::ObjectInfo{.digest = digest, .type = ObjectType::Tree}},
+ {Artifact::ObjectInfo{.digest = *digest, .type = ObjectType::Tree}},
{tmp_dir->GetPath()},
&(*apis_.local))) {
logger_->Emit(LogLevel::Error,