// // Copyright (C) 2019 The Android Open Source Project // // 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. #pragma once #include #include #include #include #include #include #include #include #include #include "common/libs/utils/result.h" #include "host/libs/web/credential_source.h" #include "host/libs/web/http_client/http_client.h" namespace cuttlefish { class Artifact { public: Artifact(const Json::Value&); Artifact(std::string name) : name_(std::move(name)) {} const std::string& Name() const { return name_; } size_t Size() const { return size_; } unsigned long LastModifiedTime() const { return last_modified_time_; } const std::string& Md5() const { return md5_; } const std::string& ContentType() const { return content_type_; } const std::string& Revision() const { return revision_; } unsigned long CreationTime() const { return creation_time_; } unsigned int Crc32() const { return crc32_; } private: std::string name_; size_t size_; unsigned long last_modified_time_; std::string md5_; std::string content_type_; std::string revision_; unsigned long creation_time_; unsigned int crc32_; }; struct DeviceBuild { DeviceBuild(std::string id, std::string target) : id(std::move(id)), target(std::move(target)) {} std::string id; std::string target; std::string product; }; std::ostream& operator<<(std::ostream&, const DeviceBuild&); struct DirectoryBuild { // TODO(schuffelen): Support local builds other than "eng" DirectoryBuild(std::vector paths, std::string target); std::vector paths; std::string target; std::string id; std::string product; }; std::ostream& operator<<(std::ostream&, const DirectoryBuild&); using Build = std::variant; std::ostream& operator<<(std::ostream&, const Build&); class BuildApi { public: BuildApi(); BuildApi(std::unique_ptr, std::unique_ptr); BuildApi(std::unique_ptr, std::unique_ptr, std::unique_ptr, std::string api_key, const std::chrono::seconds retry_period); ~BuildApi() = default; Result LatestBuildId(const std::string& branch, const std::string& target); // download the artifact from the build and apply the callback Result ArtifactToCallback(const DeviceBuild& build, const std::string& artifact, HttpClient::DataCallback callback); // determine the format of the build source argument and parse for the // relevant build identifiers Result ArgumentToBuild(const std::string& arg, const std::string& default_build_target); Result DownloadFile(const Build& build, const std::string& target_directory, const std::string& artifact_name); Result DownloadFileWithBackup( const Build& build, const std::string& target_directory, const std::string& artifact_name, const std::string& backup_artifact_name); private: Result> Headers(); Result BuildStatus(const DeviceBuild&); Result ProductName(const DeviceBuild&); Result> Artifacts( const DeviceBuild& build, const std::vector& artifact_filenames); Result> Artifacts( const DirectoryBuild& build, const std::vector& artifact_filenames); Result> Artifacts( const Build& build, const std::vector& artifact_filenames) { auto res = std::visit( [this, &artifact_filenames](auto&& arg) { return Artifacts(arg, artifact_filenames); }, build); return CF_EXPECT(std::move(res)); } Result ArtifactToFile(const DeviceBuild& build, const std::string& artifact, const std::string& path); Result ArtifactToFile(const DirectoryBuild& build, const std::string& artifact, const std::string& path); Result ArtifactToFile(const Build& build, const std::string& artifact, const std::string& path) { auto res = std::visit( [this, &artifact, &path](auto&& arg) { return ArtifactToFile(arg, artifact, path); }, build); CF_EXPECT(std::move(res)); return {}; } Result DownloadTargetFile(const Build& build, const std::string& target_directory, const std::string& artifact_name); std::unique_ptr http_client; std::unique_ptr inner_http_client; std::unique_ptr credential_source; std::string api_key_; std::chrono::seconds retry_period_; }; std::string GetBuildZipName(const Build& build, const std::string& name); } // namespace cuttlefish