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>2023-11-20 14:15:32 +0100
committerPaul Cristian Sarbu <paul.cristian.sarbu@huawei.com>2023-11-21 10:21:29 +0100
commit5fee8034265676b903618d19a7d7d65bb8d4b023 (patch)
tree8e18072885a63871509e5c2e5460442673d407b3 /src/buildtool/serve_api/serve_service/source_tree.cpp
parent232686826d31e55e739643789b4b67aed8468016 (diff)
downloadjustbuild-5fee8034265676b903618d19a7d7d65bb8d4b023.tar.gz
just serve: Implement server-side ServeContent RPC
Diffstat (limited to 'src/buildtool/serve_api/serve_service/source_tree.cpp')
-rw-r--r--src/buildtool/serve_api/serve_service/source_tree.cpp73
1 files changed, 73 insertions, 0 deletions
diff --git a/src/buildtool/serve_api/serve_service/source_tree.cpp b/src/buildtool/serve_api/serve_service/source_tree.cpp
index 8351d8d9..4ce09983 100644
--- a/src/buildtool/serve_api/serve_service/source_tree.cpp
+++ b/src/buildtool/serve_api/serve_service/source_tree.cpp
@@ -684,3 +684,76 @@ auto SourceTreeService::ServeArchiveTree(
request->sync_tree(),
response);
}
+
+auto SourceTreeService::ServeContent(
+ ::grpc::ServerContext* /* context */,
+ const ::justbuild::just_serve::ServeContentRequest* request,
+ ServeContentResponse* response) -> ::grpc::Status {
+ auto const& content{request->content()};
+ // acquire lock for CAS
+ auto lock = GarbageCollector::SharedLock();
+ if (!lock) {
+ auto str = fmt::format("Could not acquire gc SharedLock");
+ logger_->Emit(LogLevel::Error, str);
+ response->set_status(ServeContentResponse::INTERNAL_ERROR);
+ return ::grpc::Status::OK;
+ }
+ // check if content blob is in Git cache
+ if (auto data =
+ GetBlobFromRepo(StorageConfig::GitRoot(), content, logger_)) {
+ // upload blob to remote CAS
+ auto digest = ArtifactDigest{content, 0, /*is_tree=*/false};
+ auto repo = RepositoryConfig{};
+ if (not repo.SetGitCAS(StorageConfig::GitRoot())) {
+ auto str = fmt::format("Failed to SetGitCAS at {}",
+ StorageConfig::GitRoot().string());
+ logger_->Emit(LogLevel::Error, str);
+ response->set_status(ServeContentResponse::INTERNAL_ERROR);
+ return ::grpc::Status::OK;
+ }
+ auto git_api = GitApi{&repo};
+ if (not git_api.RetrieveToCas(
+ {Artifact::ObjectInfo{.digest = digest,
+ .type = ObjectType::File}},
+ &(*remote_api_))) {
+ auto str = fmt::format("Failed to sync content {}", content);
+ logger_->Emit(LogLevel::Error, str);
+ response->set_status(ServeContentResponse::SYNC_ERROR);
+ return ::grpc::Status::OK;
+ }
+ // success!
+ response->set_status(ServeContentResponse::OK);
+ return ::grpc::Status::OK;
+ }
+ // check if content blob is in a known repository
+ for (auto const& path : RemoteServeConfig::KnownRepositories()) {
+ if (auto data = GetBlobFromRepo(path, content, logger_)) {
+ // upload blob to remote CAS
+ auto digest = ArtifactDigest{content, 0, /*is_tree=*/false};
+ auto repo = RepositoryConfig{};
+ if (not repo.SetGitCAS(path)) {
+ auto str = fmt::format("Failed to SetGitCAS at {}",
+ StorageConfig::GitRoot().string());
+ logger_->Emit(LogLevel::Error, str);
+ response->set_status(ServeContentResponse::INTERNAL_ERROR);
+ return ::grpc::Status::OK;
+ }
+ auto git_api = GitApi{&repo};
+ if (not git_api.RetrieveToCas(
+ {Artifact::ObjectInfo{.digest = digest,
+ .type = ObjectType::File}},
+ &(*remote_api_))) {
+ auto str = fmt::format("Failed to sync content {}", content);
+ logger_->Emit(LogLevel::Error, str);
+ response->set_status(ServeContentResponse::SYNC_ERROR);
+ return ::grpc::Status::OK;
+ }
+ // success!
+ response->set_status(ServeContentResponse::OK);
+ return ::grpc::Status::OK;
+ }
+ }
+ // content blob not known
+ response->set_status(ServeContentResponse::NOT_FOUND);
+ return ::grpc::Status::OK;
+}