diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/buildtool/serve_api/serve_service/TARGETS | 1 | ||||
-rw-r--r-- | src/buildtool/serve_api/serve_service/target.cpp | 111 | ||||
-rw-r--r-- | src/buildtool/serve_api/serve_service/target.hpp | 14 |
3 files changed, 56 insertions, 70 deletions
diff --git a/src/buildtool/serve_api/serve_service/TARGETS b/src/buildtool/serve_api/serve_service/TARGETS index d68e5bac..1235d1ac 100644 --- a/src/buildtool/serve_api/serve_service/TARGETS +++ b/src/buildtool/serve_api/serve_service/TARGETS @@ -94,6 +94,7 @@ , ["src/buildtool/build_engine/target_map", "configured_target"] , ["src/buildtool/build_engine/target_map", "result_map"] , ["src/buildtool/common/remote", "remote_common"] + , ["src/buildtool/file_system", "file_system_manager"] , ["src/buildtool/graph_traverser", "graph_traverser"] , ["src/buildtool/logging", "log_level"] , ["src/buildtool/main", "analyse"] diff --git a/src/buildtool/serve_api/serve_service/target.cpp b/src/buildtool/serve_api/serve_service/target.cpp index 97d3914b..e358b79e 100644 --- a/src/buildtool/serve_api/serve_service/target.cpp +++ b/src/buildtool/serve_api/serve_service/target.cpp @@ -23,6 +23,7 @@ #include "src/buildtool/build_engine/target_map/configured_target.hpp" #include "src/buildtool/build_engine/target_map/result_map.hpp" #include "src/buildtool/common/artifact.hpp" +#include "src/buildtool/file_system/file_system_manager.hpp" #include "src/buildtool/file_system/object_type.hpp" #include "src/buildtool/graph_traverser/graph_traverser.hpp" #include "src/buildtool/logging/log_level.hpp" @@ -78,6 +79,44 @@ auto TargetService::GetDispatchList( } } +auto TargetService::HandleFailureLog( + std::filesystem::path const& logfile, + std::string const& failure_scope, + ::justbuild::just_serve::ServeTargetResponse* response) noexcept + -> ::grpc::Status { + logger_->Emit(LogLevel::Trace, [&logfile] { + if (auto s = FileSystemManager::ReadFile(logfile)) { + return *s; + } + return fmt::format("Failed to read failure log file {}", + logfile.string()); + }); + // ...but try to give the client the proper log + auto const& cas = Storage::Instance().CAS(); + auto digest = cas.StoreBlob(logfile, /*is_executable=*/false); + if (not digest) { + auto msg = fmt::format("Failed to store log of failed {} to local CAS", + failure_scope); + logger_->Emit(LogLevel::Error, msg); + return ::grpc::Status{::grpc::StatusCode::INTERNAL, msg}; + } + // upload log blob to remote + if (!local_api_->RetrieveToCas( + {Artifact::ObjectInfo{.digest = ArtifactDigest{*digest}, + .type = ObjectType::File}}, + &*remote_api_)) { + auto msg = + fmt::format("Failed to upload to remote CAS the failed {} log {}", + failure_scope, + digest->hash()); + logger_->Emit(LogLevel::Error, msg); + return ::grpc::Status{::grpc::StatusCode::UNAVAILABLE, msg}; + } + // set response with log digest + response->mutable_log()->CopyFrom(*digest); + return ::grpc::Status::OK; +} + auto TargetService::ServeTarget( ::grpc::ServerContext* /*context*/, const ::justbuild::just_serve::ServeTargetRequest* request, @@ -418,29 +457,7 @@ auto TargetService::ServeTarget( auto msg = fmt::format("Failed to analyse target {}", configured_target.target.ToString()); logger_->Emit(LogLevel::Warning, msg); - // ...but try to give the client the proper log - auto const& cas = Storage::Instance().CAS(); - auto digest = cas.StoreBlob(tmp_log, /*is_executable=*/false); - if (not digest) { - auto msg = std::string( - "Failed to store log of failed analysis to local CAS"); - logger_->Emit(LogLevel::Error, msg); - return ::grpc::Status{::grpc::StatusCode::INTERNAL, msg}; - } - // upload log blob to remote - if (!local_api_->RetrieveToCas( - {Artifact::ObjectInfo{.digest = ArtifactDigest{*digest}, - .type = ObjectType::File}}, - &*remote_api_)) { - auto msg = fmt::format( - "Failed to upload to remote CAS the failed analysis log {}", - digest->hash()); - logger_->Emit(LogLevel::Error, msg); - return ::grpc::Status{::grpc::StatusCode::UNAVAILABLE, msg}; - } - // set response with log digest - response->mutable_log()->CopyFrom(*digest); - return ::grpc::Status::OK; + return HandleFailureLog(tmp_log, "analysis", response); } logger_->Emit(LogLevel::Info, "Analysed target {}", result->id.ToString()); @@ -491,29 +508,7 @@ auto TargetService::ServeTarget( auto msg = fmt::format("Build for target {} failed", configured_target.target.ToString()); logger_->Emit(LogLevel::Warning, msg); - // ...but try to give the client the proper log - auto const& cas = Storage::Instance().CAS(); - auto digest = cas.StoreBlob(tmp_log, /*is_executable=*/false); - if (not digest) { - auto msg = - std::string("Failed to store log of failed build to local CAS"); - logger_->Emit(LogLevel::Error, msg); - return ::grpc::Status{::grpc::StatusCode::INTERNAL, msg}; - } - // upload log blob to remote - if (!local_api_->RetrieveToCas( - {Artifact::ObjectInfo{.digest = ArtifactDigest{*digest}, - .type = ObjectType::File}}, - &*remote_api_)) { - auto msg = fmt::format( - "Failed to upload to remote CAS the failed build log {}", - digest->hash()); - logger_->Emit(LogLevel::Error, msg); - return ::grpc::Status{::grpc::StatusCode::UNAVAILABLE, msg}; - } - // set response with log digest - response->mutable_log()->CopyFrom(*digest); - return ::grpc::Status::OK; + return HandleFailureLog(tmp_log, "build", response); } WriteTargetCacheEntries(cache_targets, @@ -532,29 +527,7 @@ auto TargetService::ServeTarget( fmt::format("Build result for target {} contains failed artifacts ", configured_target.target.ToString()); logger_->Emit(LogLevel::Warning, msg); - // ...but try to give the client the proper log - auto const& cas = Storage::Instance().CAS(); - auto digest = cas.StoreBlob(tmp_log, /*is_executable=*/false); - if (not digest) { - auto msg = std::string( - "Failed to store log of failed artifacts to local CAS"); - logger_->Emit(LogLevel::Error, msg); - return ::grpc::Status{::grpc::StatusCode::INTERNAL, msg}; - } - // upload log blob to remote - if (!local_api_->RetrieveToCas( - {Artifact::ObjectInfo{.digest = ArtifactDigest{*digest}, - .type = ObjectType::File}}, - &*remote_api_)) { - auto msg = fmt::format( - "Failed to upload to remote CAS the failed artifacts log {}", - digest->hash()); - logger_->Emit(LogLevel::Error, msg); - return ::grpc::Status{::grpc::StatusCode::UNAVAILABLE, msg}; - } - // set response with log digest - response->mutable_log()->CopyFrom(*digest); - return ::grpc::Status::OK; + return HandleFailureLog(tmp_log, "artifacts", response); } // now that the target cache key is in, make sure remote CAS has all diff --git a/src/buildtool/serve_api/serve_service/target.hpp b/src/buildtool/serve_api/serve_service/target.hpp index 09b8657b..45efdbb8 100644 --- a/src/buildtool/serve_api/serve_service/target.hpp +++ b/src/buildtool/serve_api/serve_service/target.hpp @@ -131,8 +131,20 @@ class TargetService final : public justbuild::just_serve::Target::Service { /// also ensures the content has the expected format. /// \returns An error + data union, with a pair of grpc status at index 0 /// and the dispatch list stored as a JSON object at index 1. - auto GetDispatchList(ArtifactDigest const& dispatch_digest) noexcept + [[nodiscard]] auto GetDispatchList( + ArtifactDigest const& dispatch_digest) noexcept -> std::variant<::grpc::Status, dispatch_t>; + + /// \brief Handles the processing of the log after a failed analysis or + /// build. Will populate the response as needed and set the status to be + /// returned to the client. + /// \param failure_scope String stating where the failure occurred, to be + /// included in the local error messaging. + [[nodiscard]] auto HandleFailureLog( + std::filesystem::path const& logfile, + std::string const& failure_scope, + ::justbuild::just_serve::ServeTargetResponse* response) noexcept + -> ::grpc::Status; }; #endif // INCLUDED_SRC_BUILD_SERVE_API_SERVE_SERVICE_TARGET_HPP |