diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/buildtool/main/main.cpp | 50 | ||||
-rw-r--r-- | src/buildtool/storage/TARGETS | 1 | ||||
-rw-r--r-- | src/buildtool/storage/config.hpp | 107 | ||||
-rw-r--r-- | src/buildtool/storage/fs_utils.cpp | 8 | ||||
-rw-r--r-- | src/buildtool/storage/garbage_collector.cpp | 4 | ||||
-rw-r--r-- | src/buildtool/storage/uplinker.cpp | 4 | ||||
-rw-r--r-- | src/other_tools/just_mr/main.cpp | 32 |
7 files changed, 127 insertions, 79 deletions
diff --git a/src/buildtool/main/main.cpp b/src/buildtool/main/main.cpp index d0c36d93..e1f10904 100644 --- a/src/buildtool/main/main.cpp +++ b/src/buildtool/main/main.cpp @@ -102,17 +102,29 @@ void SetupLogging(LogArguments const& clargs) { } } +[[nodiscard]] auto CreateStorageConfig(EndpointArguments const& eargs) noexcept + -> std::optional<StorageConfig> { + StorageConfig::Builder builder; + if (eargs.local_root.has_value()) { + builder.SetBuildRoot(*eargs.local_root); + } + + auto config = builder.Build(); + if (config) { + return *std::move(config); + } + Logger::Log(LogLevel::Error, config.error()); + return std::nullopt; +} + #ifndef BOOTSTRAP_BUILD_TOOL void SetupExecutionConfig(EndpointArguments const& eargs, BuildArguments const& bargs, RebuildArguments const& rargs) { - using StorageConfig = StorageConfig; using LocalConfig = LocalExecutionConfig; using RemoteConfig = RemoteExecutionConfig; - if (not(not eargs.local_root or - (StorageConfig::Instance().SetBuildRoot(*eargs.local_root))) or - not(not bargs.local_launcher or - LocalConfig::SetLauncher(*bargs.local_launcher))) { + if (bargs.local_launcher and + not LocalConfig::SetLauncher(*bargs.local_launcher)) { Logger::Log(LogLevel::Error, "Failed to configure local execution."); std::exit(kExitFailure); } @@ -783,12 +795,17 @@ auto main(int argc, char* argv[]) -> int { if (not auth_config) { return kExitFailure; } +#endif + auto const storage_config = CreateStorageConfig(arguments.endpoint); + if (not storage_config) { + return kExitFailure; + } + auto const storage = Storage::Create(&*storage_config); - auto const storage = Storage::Create(&StorageConfig::Instance()); - +#ifndef BOOTSTRAP_BUILD_TOOL if (arguments.cmd == SubCommand::kGc) { if (GarbageCollector::TriggerGarbageCollection( - StorageConfig::Instance(), arguments.gc.no_rotate)) { + *storage_config, arguments.gc.no_rotate)) { return kExitSuccess; } return kExitFailure; @@ -796,13 +813,13 @@ auto main(int argc, char* argv[]) -> int { if (arguments.cmd == SubCommand::kExecute) { SetupExecutionServiceConfig(arguments.service); - ApiBundle const exec_apis{&StorageConfig::Instance(), + ApiBundle const exec_apis{&*storage_config, &storage, /*repo_config=*/nullptr, &*auth_config, RemoteExecutionConfig::RemoteAddress()}; if (not ServerImpl::Instance().Run( - StorageConfig::Instance(), storage, exec_apis)) { + *storage_config, storage, exec_apis)) { return kExitFailure; } return kExitSuccess; @@ -816,7 +833,7 @@ auto main(int argc, char* argv[]) -> int { arguments.service.pid_file); if (serve_server) { ApiBundle const serve_apis{ - &StorageConfig::Instance(), + &*storage_config, &storage, /*repo_config=*/nullptr, &*auth_config, @@ -825,7 +842,7 @@ auto main(int argc, char* argv[]) -> int { ServeApi::Create(*serve_config, &storage, &serve_apis); bool with_execute = not RemoteExecutionConfig::RemoteAddress(); return serve_server->Run(*serve_config, - StorageConfig::Instance(), + *storage_config, storage, serve, serve_apis, @@ -876,7 +893,7 @@ auto main(int argc, char* argv[]) -> int { if (not SetupRetryConfig(arguments.retry)) { std::exit(kExitFailure); } - ApiBundle const main_apis{&StorageConfig::Instance(), + ApiBundle const main_apis{&*storage_config, &storage, &repo_config, &*auth_config, @@ -895,11 +912,10 @@ auto main(int argc, char* argv[]) -> int { ProgressReporter::Reporter(&stats, &progress)}; if (arguments.cmd == SubCommand::kInstallCas) { - if (not repo_config.SetGitCAS( - StorageConfig::Instance().GitRoot())) { + if (not repo_config.SetGitCAS(storage_config->GitRoot())) { Logger::Log(LogLevel::Debug, "Failed set Git CAS {}.", - StorageConfig::Instance().GitRoot().string()); + storage_config->GitRoot().string()); } return FetchAndInstallArtifacts(main_apis, arguments.fetch) ? kExitSuccess @@ -923,7 +939,7 @@ auto main(int argc, char* argv[]) -> int { #endif // BOOTSTRAP_BUILD_TOOL #ifndef BOOTSTRAP_BUILD_TOOL - auto lock = GarbageCollector::SharedLock(StorageConfig::Instance()); + auto lock = GarbageCollector::SharedLock(*storage_config); if (not lock) { return kExitFailure; } diff --git a/src/buildtool/storage/TARGETS b/src/buildtool/storage/TARGETS index 00a5f2d2..2d624afb 100644 --- a/src/buildtool/storage/TARGETS +++ b/src/buildtool/storage/TARGETS @@ -11,6 +11,7 @@ , ["src/buildtool/logging", "log_level"] , ["src/utils/cpp", "gsl"] , ["src/utils/cpp", "tmp_dir"] + , ["src/utils/cpp", "expected"] ] , "stage": ["src", "buildtool", "storage"] } diff --git a/src/buildtool/storage/config.hpp b/src/buildtool/storage/config.hpp index 417d3e88..7c4be29d 100644 --- a/src/buildtool/storage/config.hpp +++ b/src/buildtool/storage/config.hpp @@ -24,6 +24,7 @@ #include "src/buildtool/file_system/file_system_manager.hpp" #include "src/buildtool/logging/log_level.hpp" #include "src/buildtool/logging/logger.hpp" +#include "src/utils/cpp/expected.hpp" #include "src/utils/cpp/gsl.hpp" #include "src/utils/cpp/tmp_dir.hpp" @@ -40,59 +41,35 @@ struct GenerationConfig final { std::filesystem::path const target_cache; }; -/// \brief Global storage configuration. -class StorageConfig { - public: +struct StorageConfig final { + class Builder; + static inline auto const kDefaultBuildRoot = FileSystemManager::GetUserHome() / ".cache" / "just"; - [[nodiscard]] static auto Instance() noexcept -> StorageConfig& { - static StorageConfig config; - return config; - } - - [[nodiscard]] auto SetBuildRoot(std::filesystem::path const& dir) noexcept - -> bool { - if (FileSystemManager::IsRelativePath(dir)) { - Logger::Log(LogLevel::Error, - "Build root must be absolute path but got '{}'.", - dir.string()); - return false; - } - build_root_ = dir; - return true; - } - - /// \brief Specifies the number of storage generations. - auto SetNumGenerations(std::size_t num_generations) noexcept -> void { - num_generations_ = num_generations; - } - - /// \brief Number of storage generations. - [[nodiscard]] auto NumGenerations() const noexcept -> std::size_t { - return num_generations_; - } + // Build root directory. All the storage dirs are subdirs of build_root. + // By default, build_root is set to $HOME/.cache/just. + // If the user uses --local-build-root PATH, + // then build_root will be set to PATH. + std::filesystem::path const build_root = kDefaultBuildRoot; - /// \brief Build directory, defaults to user directory if not set - [[nodiscard]] auto BuildRoot() const noexcept - -> std::filesystem::path const& { - return build_root_; - } + // Number of total storage generations (default: two generations). + std::size_t const num_generations = 2; /// \brief Root directory of all storage generations. [[nodiscard]] auto CacheRoot() const noexcept -> std::filesystem::path { - return BuildRoot() / "protocol-dependent"; + return build_root / "protocol-dependent"; } /// \brief Directory for the git repository storing various roots [[nodiscard]] auto GitRoot() const noexcept -> std::filesystem::path { - return BuildRoot() / "git"; + return build_root / "git"; } /// \brief Root directory of specific storage generation [[nodiscard]] auto GenerationCacheRoot(std::size_t index) const noexcept -> std::filesystem::path { - ExpectsAudit(index < num_generations_); + ExpectsAudit(index < num_generations); auto generation = std::string{"generation-"} + std::to_string(index); return CacheRoot() / generation; } @@ -138,21 +115,59 @@ class StorageConfig { }; private: - // Build root directory. All the storage dirs are subdirs of build_root. - // By default, build_root is set to $HOME/.cache/just. - // If the user uses --local-build-root PATH, - // then build_root will be set to PATH. - std::filesystem::path build_root_{kDefaultBuildRoot}; - - // Number of total storage generations (default: two generations). - std::size_t num_generations_{2}; - // different folder for different caching protocol [[nodiscard]] static auto UpdatePathForCompatibility( std::filesystem::path const& dir, bool is_compatible) -> std::filesystem::path { return dir / (is_compatible ? "compatible-sha256" : "git-sha1"); + }; +}; + +class StorageConfig::Builder final { + public: + auto SetBuildRoot(std::filesystem::path value) noexcept -> Builder& { + build_root_ = std::move(value); + return *this; } + + /// \brief Specifies the number of storage generations. + auto SetNumGenerations(std::size_t value) noexcept -> Builder& { + num_generations_ = value; + return *this; + } + + [[nodiscard]] auto Build() const noexcept + -> expected<StorageConfig, std::string> { + // To not duplicate default arguments of StorageConfig in builder, + // create a default config and copy default arguments from there. + StorageConfig const default_config; + + auto build_root = default_config.build_root; + if (build_root_.has_value()) { + build_root = *build_root_; + if (FileSystemManager::IsRelativePath(build_root)) { + return unexpected(fmt::format( + "Build root must be absolute path but got '{}'.", + build_root.string())); + } + } + + auto num_generations = default_config.num_generations; + if (num_generations_.has_value()) { + num_generations = *num_generations_; + if (num_generations == 0) { + return unexpected(std::string{ + "The number of generations must be greater than 0."}); + } + } + + return StorageConfig{.build_root = std::move(build_root), + .num_generations = num_generations}; + } + + private: + std::optional<std::filesystem::path> build_root_; + std::optional<std::size_t> num_generations_; }; #endif // INCLUDED_SRC_BUILDTOOL_STORAGE_CONFIG_HPP diff --git a/src/buildtool/storage/fs_utils.cpp b/src/buildtool/storage/fs_utils.cpp index e50e892e..3286c4ec 100644 --- a/src/buildtool/storage/fs_utils.cpp +++ b/src/buildtool/storage/fs_utils.cpp @@ -54,14 +54,14 @@ auto GetGitRoot(StorageConfig const& storage_config, auto GetCommitTreeIDFile(StorageConfig const& storage_config, std::string const& commit) noexcept -> std::filesystem::path { - return storage_config.BuildRoot() / "commit-tree-map" / commit; + return storage_config.build_root / "commit-tree-map" / commit; } auto GetArchiveTreeIDFile(StorageConfig const& storage_config, std::string const& repo_type, std::string const& content) noexcept -> std::filesystem::path { - return storage_config.BuildRoot() / "tree-map" / repo_type / content; + return storage_config.build_root / "tree-map" / repo_type / content; } auto GetForeignFileTreeIDFile(StorageConfig const& storage_config, @@ -82,14 +82,14 @@ auto GetForeignFileTreeIDFile(StorageConfig const& storage_config, auto GetDistdirTreeIDFile(StorageConfig const& storage_config, std::string const& content) noexcept -> std::filesystem::path { - return storage_config.BuildRoot() / "distfiles-tree-map" / content; + return storage_config.build_root / "distfiles-tree-map" / content; } auto GetResolvedTreeIDFile(StorageConfig const& storage_config, std::string const& tree_hash, PragmaSpecial const& pragma_special) noexcept -> std::filesystem::path { - return storage_config.BuildRoot() / "special-tree-map" / + return storage_config.build_root / "special-tree-map" / kPragmaSpecialInverseMap.at(pragma_special) / tree_hash; } diff --git a/src/buildtool/storage/garbage_collector.cpp b/src/buildtool/storage/garbage_collector.cpp index 3b3e5d28..25a78ddb 100644 --- a/src/buildtool/storage/garbage_collector.cpp +++ b/src/buildtool/storage/garbage_collector.cpp @@ -175,11 +175,11 @@ auto GarbageCollector::TriggerGarbageCollection( storage_config.CacheRoot() / fmt::format("{}{}", remove_me_prefix, remove_me_counter++); to_remove.emplace_back(remove_me_dir); - for (std::size_t i = storage_config.NumGenerations(); i > 0; --i) { + for (std::size_t i = storage_config.num_generations; i > 0; --i) { auto cache_root = storage_config.GenerationCacheRoot(i - 1); if (FileSystemManager::IsDirectory(cache_root)) { auto new_cache_root = - (i == storage_config.NumGenerations()) + (i == storage_config.num_generations) ? remove_me_dir : storage_config.GenerationCacheRoot(i); if (not FileSystemManager::Rename(cache_root, diff --git a/src/buildtool/storage/uplinker.cpp b/src/buildtool/storage/uplinker.cpp index de6cfb99..fee01af4 100644 --- a/src/buildtool/storage/uplinker.cpp +++ b/src/buildtool/storage/uplinker.cpp @@ -32,8 +32,8 @@ namespace { gsl::not_null<StorageConfig const*> const& storage_config) noexcept -> std::vector<Generation> { std::vector<Generation> generations; - generations.reserve(storage_config->NumGenerations()); - for (std::size_t i = 0; i < storage_config->NumGenerations(); ++i) { + generations.reserve(storage_config->num_generations); + for (std::size_t i = 0; i < storage_config->num_generations; ++i) { generations.emplace_back(Generation::Create(storage_config, /*generation=*/i)); } diff --git a/src/other_tools/just_mr/main.cpp b/src/other_tools/just_mr/main.cpp index 98e1de2c..92f07944 100644 --- a/src/other_tools/just_mr/main.cpp +++ b/src/other_tools/just_mr/main.cpp @@ -198,6 +198,22 @@ void SetupLogging(MultiRepoLogArguments const& clargs) { } } +[[nodiscard]] auto CreateStorageConfig( + MultiRepoCommonArguments const& args) noexcept + -> std::optional<StorageConfig> { + StorageConfig::Builder builder; + if (args.just_mr_paths->root.has_value()) { + builder.SetBuildRoot(*args.just_mr_paths->root); + } + + auto config = builder.Build(); + if (config) { + return *std::move(config); + } + Logger::Log(LogLevel::Error, config.error()); + return std::nullopt; +} + } // namespace auto main(int argc, char* argv[]) -> int { @@ -289,14 +305,14 @@ auto main(int argc, char* argv[]) -> int { // Setup LocalStorageConfig to store the local_build_root properly // and make the cas and git cache roots available - if (not StorageConfig::Instance().SetBuildRoot( - *arguments.common.just_mr_paths->root)) { + auto storage_config = CreateStorageConfig(arguments.common); + if (not storage_config) { Logger::Log(LogLevel::Error, "Failed to configure local build root."); return kExitGenericFailure; } - auto const storage = Storage::Create(&StorageConfig::Instance()); + auto const storage = Storage::Create(&*storage_config); // check for conflicts in main repo name if ((not arguments.setup.sub_all) and arguments.common.main and @@ -347,12 +363,12 @@ auto main(int argc, char* argv[]) -> int { arguments.auth, arguments.retry, arguments.launch_fwd, - StorageConfig::Instance(), + *storage_config, storage, forward_build_root, my_name); } - auto lock = GarbageCollector::SharedLock(StorageConfig::Instance()); + auto lock = GarbageCollector::SharedLock(*storage_config); if (not lock) { return kExitGenericFailure; } @@ -377,7 +393,7 @@ auto main(int argc, char* argv[]) -> int { arguments.setup, arguments.just_cmd, arguments.auth, - StorageConfig::Instance(), + *storage_config, storage, /*interactive=*/(arguments.cmd == SubCommand::kSetupEnv), my_name); @@ -397,7 +413,7 @@ auto main(int argc, char* argv[]) -> int { return MultiRepoUpdate(config, arguments.common, arguments.update, - StorageConfig::Instance(), + *storage_config, my_name); } @@ -425,7 +441,7 @@ auto main(int argc, char* argv[]) -> int { arguments.setup, arguments.fetch, arguments.auth, - StorageConfig::Instance(), + *storage_config, storage, my_name); } |