diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/other_tools/just_mr/fetch.cpp | 1 | ||||
-rw-r--r-- | src/other_tools/just_mr/setup.cpp | 2 | ||||
-rw-r--r-- | src/other_tools/ops_maps/TARGETS | 1 | ||||
-rw-r--r-- | src/other_tools/ops_maps/content_cas_map.cpp | 31 | ||||
-rw-r--r-- | src/other_tools/ops_maps/content_cas_map.hpp | 2 | ||||
-rw-r--r-- | src/other_tools/root_maps/TARGETS | 1 | ||||
-rw-r--r-- | src/other_tools/root_maps/content_git_map.cpp | 23 | ||||
-rw-r--r-- | src/other_tools/root_maps/content_git_map.hpp | 2 | ||||
-rw-r--r-- | src/other_tools/utils/TARGETS | 2 | ||||
-rw-r--r-- | src/other_tools/utils/content.hpp | 64 |
10 files changed, 97 insertions, 32 deletions
diff --git a/src/other_tools/just_mr/fetch.cpp b/src/other_tools/just_mr/fetch.cpp index bf9cf796..70322d98 100644 --- a/src/other_tools/just_mr/fetch.cpp +++ b/src/other_tools/just_mr/fetch.cpp @@ -277,6 +277,7 @@ auto MultiRepoFetch(std::shared_ptr<Configuration> const& config, // create async maps auto content_cas_map = CreateContentCASMap(common_args.just_mr_paths, + common_args.alternative_mirrors, common_args.ca_info, local_api ? &(*local_api) : nullptr, remote_api ? &(*remote_api) : nullptr, diff --git a/src/other_tools/just_mr/setup.cpp b/src/other_tools/just_mr/setup.cpp index 6d568bc8..5aab7095 100644 --- a/src/other_tools/just_mr/setup.cpp +++ b/src/other_tools/just_mr/setup.cpp @@ -104,6 +104,7 @@ auto MultiRepoSetup(std::shared_ptr<Configuration> const& config, auto critical_git_op_map = CreateCriticalGitOpMap(crit_git_op_ptr); auto content_cas_map = CreateContentCASMap(common_args.just_mr_paths, + common_args.alternative_mirrors, common_args.ca_info, local_api ? &(*local_api) : nullptr, remote_api ? &(*remote_api) : nullptr, @@ -131,6 +132,7 @@ auto MultiRepoSetup(std::shared_ptr<Configuration> const& config, CreateContentGitMap(&content_cas_map, &import_to_git_map, common_args.just_mr_paths, + common_args.alternative_mirrors, common_args.ca_info, &resolve_symlinks_map, &critical_git_op_map, diff --git a/src/other_tools/ops_maps/TARGETS b/src/other_tools/ops_maps/TARGETS index 1baf11e5..f30cdf22 100644 --- a/src/other_tools/ops_maps/TARGETS +++ b/src/other_tools/ops_maps/TARGETS @@ -61,6 +61,7 @@ , ["src/buildtool/file_system/symlinks_map", "pragma_special"] , ["src/buildtool/execution_api/common", "common"] , ["src/buildtool/multithreading", "async_map_consumer"] + , ["src/other_tools/just_mr", "mirrors"] , ["src/utils/cpp", "hash_combine"] , ["@", "json", "", "json"] ] diff --git a/src/other_tools/ops_maps/content_cas_map.cpp b/src/other_tools/ops_maps/content_cas_map.cpp index b6b8712e..2deb8060 100644 --- a/src/other_tools/ops_maps/content_cas_map.cpp +++ b/src/other_tools/ops_maps/content_cas_map.cpp @@ -20,18 +20,23 @@ #include "src/other_tools/just_mr/progress_reporting/progress.hpp" #include "src/other_tools/just_mr/progress_reporting/statistics.hpp" #include "src/other_tools/utils/content.hpp" +#include "src/other_tools/utils/curl_url_handle.hpp" auto CreateContentCASMap(LocalPathsPtr const& just_mr_paths, + MirrorsPtr const& additional_mirrors, CAInfoPtr const& ca_info, IExecutionApi* local_api, IExecutionApi* remote_api, std::size_t jobs) -> ContentCASMap { - auto ensure_in_cas = [just_mr_paths, ca_info, local_api, remote_api]( - auto /*unused*/, - auto setter, - auto logger, - auto /*unused*/, - auto const& key) { + auto ensure_in_cas = [just_mr_paths, + additional_mirrors, + ca_info, + local_api, + remote_api](auto /*unused*/, + auto setter, + auto logger, + auto /*unused*/, + auto const& key) { // check if content already in CAS auto const& cas = Storage::Instance().CAS(); auto digest = ArtifactDigest(key.content, 0, false); @@ -69,17 +74,9 @@ auto CreateContentCASMap(LocalPathsPtr const& just_mr_paths, /*fatal=*/true); return; } - // now do the actual fetch; first, try the main fetch URL - auto data = NetworkFetch(key.fetch_url, ca_info); - if (not data) { - // try the mirrors, in order, if given - for (auto const& mirror : key.mirrors) { - data = NetworkFetch(mirror, ca_info); - if (data) { - break; - } - } - } + // now do the actual fetch + auto data = NetworkFetchWithMirrors( + key.fetch_url, key.mirrors, ca_info, additional_mirrors); if (not data) { (*logger)(fmt::format("Failed to fetch a file with id {} from " "provided remotes", diff --git a/src/other_tools/ops_maps/content_cas_map.hpp b/src/other_tools/ops_maps/content_cas_map.hpp index 16b790d0..810727cd 100644 --- a/src/other_tools/ops_maps/content_cas_map.hpp +++ b/src/other_tools/ops_maps/content_cas_map.hpp @@ -24,6 +24,7 @@ #include "src/buildtool/execution_api/common/execution_api.hpp" #include "src/buildtool/file_system/symlinks_map/pragma_special.hpp" #include "src/buildtool/multithreading/async_map_consumer.hpp" +#include "src/other_tools/just_mr/mirrors.hpp" #include "src/utils/cpp/hash_combine.hpp" struct ArchiveContent { @@ -65,6 +66,7 @@ struct ArchiveRepoInfo { using ContentCASMap = AsyncMapConsumer<ArchiveContent, bool>; [[nodiscard]] auto CreateContentCASMap(LocalPathsPtr const& just_mr_paths, + MirrorsPtr const& additional_mirrors, CAInfoPtr const& ca_info, IExecutionApi* local_api, IExecutionApi* remote_api, diff --git a/src/other_tools/root_maps/TARGETS b/src/other_tools/root_maps/TARGETS index fff48505..9340cd14 100644 --- a/src/other_tools/root_maps/TARGETS +++ b/src/other_tools/root_maps/TARGETS @@ -86,6 +86,7 @@ [ ["src/buildtool/serve_api/remote", "serve_api"] , ["src/buildtool/execution_api/common", "common"] , ["src/buildtool/common", "user_structs"] + , ["src/other_tools/just_mr", "mirrors"] , ["src/other_tools/ops_maps", "content_cas_map"] , ["src/other_tools/ops_maps", "import_to_git_map"] , ["src/buildtool/file_system/symlinks_map", "resolve_symlinks_map"] diff --git a/src/other_tools/root_maps/content_git_map.cpp b/src/other_tools/root_maps/content_git_map.cpp index a39b6cde..79500f5d 100644 --- a/src/other_tools/root_maps/content_git_map.cpp +++ b/src/other_tools/root_maps/content_git_map.cpp @@ -302,6 +302,7 @@ auto CreateContentGitMap( gsl::not_null<ContentCASMap*> const& content_cas_map, gsl::not_null<ImportToGitMap*> const& import_to_git_map, LocalPathsPtr const& just_mr_paths, + MirrorsPtr const& additional_mirrors, CAInfoPtr const& ca_info, gsl::not_null<ResolveSymlinksMap*> const& resolve_symlinks_map, gsl::not_null<CriticalGitOpMap*> const& critical_git_op_map, @@ -315,6 +316,7 @@ auto CreateContentGitMap( resolve_symlinks_map, critical_git_op_map, just_mr_paths, + additional_mirrors, ca_info, serve_api, local_api, @@ -505,6 +507,7 @@ auto CreateContentGitMap( sha256 = key.archive.sha256, sha512 = key.archive.sha512, pragma_special = key.pragma_special, + additional_mirrors, ca_info, origin = key.archive.origin, absent = key.absent, @@ -708,20 +711,12 @@ auto CreateContentGitMap( /*fatal=*/true); return; } - // now do the actual fetch; first, try the - // main fetch URL - auto data = - NetworkFetch(fetch_url, ca_info); - if (not data) { - // try the mirrors, in order, if given - for (auto const& mirror : mirrors) { - data = - NetworkFetch(mirror, ca_info); - if (data) { - break; - } - } - } + // now do the actual fetch + auto data = NetworkFetchWithMirrors( + fetch_url, + mirrors, + ca_info, + additional_mirrors); if (not data) { (*logger)( fmt::format("Failed to fetch a " diff --git a/src/other_tools/root_maps/content_git_map.hpp b/src/other_tools/root_maps/content_git_map.hpp index e0a564f5..986a0531 100644 --- a/src/other_tools/root_maps/content_git_map.hpp +++ b/src/other_tools/root_maps/content_git_map.hpp @@ -21,6 +21,7 @@ #include "src/buildtool/execution_api/common/execution_api.hpp" #include "src/buildtool/file_system/symlinks_map/resolve_symlinks_map.hpp" #include "src/buildtool/serve_api/remote/serve_api.hpp" +#include "src/other_tools/just_mr/mirrors.hpp" #include "src/other_tools/ops_maps/content_cas_map.hpp" #include "src/other_tools/ops_maps/import_to_git_map.hpp" @@ -33,6 +34,7 @@ using ContentGitMap = gsl::not_null<ContentCASMap*> const& content_cas_map, gsl::not_null<ImportToGitMap*> const& import_to_git_map, LocalPathsPtr const& just_mr_paths, + MirrorsPtr const& additional_mirrors, CAInfoPtr const& ca_info, gsl::not_null<ResolveSymlinksMap*> const& resolve_symlinks_map, gsl::not_null<CriticalGitOpMap*> const& critical_git_op_map, diff --git a/src/other_tools/utils/TARGETS b/src/other_tools/utils/TARGETS index 2bbf1b9f..aad0fec6 100644 --- a/src/other_tools/utils/TARGETS +++ b/src/other_tools/utils/TARGETS @@ -38,9 +38,11 @@ , "hdrs": ["content.hpp"] , "deps": [ "curl_easy_handle" + , "curl_url_handle" , ["src/buildtool/common", "user_structs"] , ["src/buildtool/crypto", "hasher"] , ["src/buildtool/logging", "log_level"] + , ["src/other_tools/just_mr", "mirrors"] ] , "stage": ["src", "other_tools", "utils"] } diff --git a/src/other_tools/utils/content.hpp b/src/other_tools/utils/content.hpp index 907af852..19877263 100644 --- a/src/other_tools/utils/content.hpp +++ b/src/other_tools/utils/content.hpp @@ -21,12 +21,14 @@ #include "src/buildtool/common/user_structs.hpp" #include "src/buildtool/crypto/hasher.hpp" #include "src/buildtool/logging/log_level.hpp" +#include "src/other_tools/just_mr/mirrors.hpp" #include "src/other_tools/utils/curl_easy_handle.hpp" +#include "src/other_tools/utils/curl_url_handle.hpp" // Utilities related to the content of an archive /// \brief Fetches a file from the internet and stores its content in memory. -/// Returns the content. +/// \returns the content. [[nodiscard]] static auto NetworkFetch(std::string const& fetch_url, CAInfoPtr const& ca_info) noexcept -> std::optional<std::string> { @@ -38,6 +40,66 @@ return curl_handle->DownloadToString(fetch_url); } +/// \brief Fetches a file from the internet and stores its content in memory. +/// Tries not only a given remote, but also all associated remote locations. +/// \returns the content. +[[nodiscard]] static auto NetworkFetchWithMirrors( + std::string const& fetch_url, + std::vector<std::string> const& mirrors, + CAInfoPtr const& ca_info, + MirrorsPtr const& additional_mirrors) noexcept + -> std::optional<std::string> { + // first, try the local mirrors + std::optional<std::string> data{std::nullopt}; + auto local_mirrors = + MirrorsUtils::GetLocalMirrors(additional_mirrors, fetch_url); + for (auto const& mirror : local_mirrors) { + if (data = NetworkFetch(mirror, ca_info); data) { + break; + } + } + if (not data) { + // get preferred hostnames list + auto preferred_hostnames = + MirrorsUtils::GetPreferredHostnames(additional_mirrors); + // try the main fetch URL, but with each of the preferred hostnames + for (auto const& hostname : preferred_hostnames) { + if (auto preferred_url = + CurlURLHandle::ReplaceHostname(fetch_url, hostname)) { + if (data = NetworkFetch(*preferred_url, ca_info); data) { + break; + } + } + } + if (not data) { + // now try the main fetch URL + if (data = NetworkFetch(fetch_url, ca_info); not data) { + // try the mirrors, in order, if given + for (auto const& mirror : mirrors) { + // first use with preferred hostnames... + for (auto const& hostname : preferred_hostnames) { + if (auto preferred_mirror = + CurlURLHandle::ReplaceHostname(mirror, + hostname)) { + if (data = NetworkFetch(*preferred_mirror, ca_info); + data) { + break; + } + } + } + // ...then the original mirror + if (not data) { + if (data = NetworkFetch(mirror, ca_info); data) { + break; + } + } + } + } + } + } + return data; +} + template <Hasher::HashType type> [[nodiscard]] static auto GetContentHash(std::string const& data) noexcept -> std::string { |