mirror of https://github.com/mamba-org/mamba.git
Remove Context from downloaders (#3928)
This commit is contained in:
parent
562f64e8a6
commit
8254680fd7
|
@ -16,6 +16,7 @@
|
|||
#include "mamba/core/palette.hpp"
|
||||
#include "mamba/core/tasksync.hpp"
|
||||
#include "mamba/download/mirror_map.hpp"
|
||||
#include "mamba/download/parameters.hpp"
|
||||
#include "mamba/fs/filesystem.hpp"
|
||||
#include "mamba/solver/libsolv/parameters.hpp"
|
||||
#include "mamba/solver/request.hpp"
|
||||
|
@ -77,26 +78,6 @@ namespace mamba
|
|||
|
||||
static void use_default_signal_handler(bool val);
|
||||
|
||||
struct RemoteFetchParams
|
||||
{
|
||||
// ssl_verify can be either an empty string (regular SSL verification),
|
||||
// the string "<false>" to indicate no SSL verification, or a path to
|
||||
// a directory with cert files, or a cert file.
|
||||
std::string ssl_verify{ "" };
|
||||
bool ssl_no_revoke{ false };
|
||||
bool curl_initialized{ false }; // non configurable, used in fetch only
|
||||
|
||||
std::string user_agent{ "mamba/" LIBMAMBA_VERSION_STRING };
|
||||
|
||||
double connect_timeout_secs{ 10. };
|
||||
// int read_timeout_secs { 60 };
|
||||
int retry_timeout{ 2 }; // seconds
|
||||
int retry_backoff{ 3 }; // retry_timeout * retry_backoff
|
||||
int max_retries{ 3 }; // max number of retries
|
||||
|
||||
std::map<std::string, std::string> proxy_servers;
|
||||
};
|
||||
|
||||
struct OutputParams
|
||||
{
|
||||
int verbosity{ 0 };
|
||||
|
@ -193,7 +174,28 @@ namespace mamba
|
|||
// micromamba only
|
||||
bool shell_completion = true;
|
||||
|
||||
RemoteFetchParams remote_fetch_params;
|
||||
download::RemoteFetchParams remote_fetch_params = {
|
||||
/* .ssl_verify */ { "" },
|
||||
/* .ssl_no_revoke */ false,
|
||||
/* .curl_initialized */ false,
|
||||
/* .user_agent */ { "mamba/" LIBMAMBA_VERSION_STRING },
|
||||
/* .connect_timeout_secs */ 10.,
|
||||
/* .retry_timeout */ 2,
|
||||
/* .retry_backoff */ 3,
|
||||
/* .max_retries */ 3,
|
||||
/* .proxy_servers */ {},
|
||||
};
|
||||
|
||||
download::Options download_options() const
|
||||
{
|
||||
return {
|
||||
/* .download_threads */ this->threads_params.download_threads,
|
||||
/* .fail_fast */ false,
|
||||
/* .sort */ true,
|
||||
/* .verbose */ this->output_params.verbosity >= 2,
|
||||
};
|
||||
}
|
||||
|
||||
OutputParams output_params;
|
||||
GraphicsParams graphics_params;
|
||||
SrcParams src_params;
|
||||
|
|
|
@ -7,29 +7,17 @@
|
|||
#ifndef MAMBA_DOWNLOAD_DOWNLOADER_HPP
|
||||
#define MAMBA_DOWNLOAD_DOWNLOADER_HPP
|
||||
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
|
||||
#include <tl/expected.hpp>
|
||||
|
||||
#include "mamba/core/context.hpp"
|
||||
#include "mamba/core/error_handling.hpp"
|
||||
#include "mamba/download/mirror_map.hpp"
|
||||
#include "mamba/download/parameters.hpp"
|
||||
#include "mamba/download/request.hpp"
|
||||
#include "mamba/specs/authentication_info.hpp"
|
||||
|
||||
namespace mamba::download
|
||||
{
|
||||
struct Options
|
||||
{
|
||||
using termination_function = std::optional<std::function<void()>>;
|
||||
|
||||
bool fail_fast = false;
|
||||
bool sort = true;
|
||||
termination_function on_unexpected_termination = std::nullopt;
|
||||
};
|
||||
|
||||
class Monitor
|
||||
{
|
||||
public:
|
||||
|
@ -59,7 +47,8 @@ namespace mamba::download
|
|||
MultiResult download(
|
||||
MultiRequest requests,
|
||||
const mirror_map& mirrors,
|
||||
const Context& context,
|
||||
const RemoteFetchParams& params,
|
||||
const specs::AuthenticationDataBase& auth_info,
|
||||
Options options = {},
|
||||
Monitor* monitor = nullptr
|
||||
);
|
||||
|
@ -67,12 +56,13 @@ namespace mamba::download
|
|||
Result download(
|
||||
Request request,
|
||||
const mirror_map& mirrors,
|
||||
const Context& context,
|
||||
const RemoteFetchParams& params,
|
||||
const specs::AuthenticationDataBase& auth_info,
|
||||
Options options = {},
|
||||
Monitor* monitor = nullptr
|
||||
);
|
||||
|
||||
bool check_resource_exists(const std::string& url, const Context& context);
|
||||
bool check_resource_exists(const std::string& url, const RemoteFetchParams& params);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
// Copyright (c) 2019, QuantStack and Mamba Contributors
|
||||
//
|
||||
// Distributed under the terms of the BSD 3-Clause License.
|
||||
//
|
||||
// The full license is in the file LICENSE, distributed with this software.
|
||||
|
||||
#ifndef MAMBA_DOWNLOAD_PARAMETERS_HPP
|
||||
#define MAMBA_DOWNLOAD_PARAMETERS_HPP
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
namespace mamba::download
|
||||
{
|
||||
struct RemoteFetchParams
|
||||
{
|
||||
// ssl_verify can be either an empty string (regular SSL verification),
|
||||
// the string "<false>" to indicate no SSL verification, or a path to
|
||||
// a directory with cert files, or a cert file.
|
||||
std::string ssl_verify = "";
|
||||
bool ssl_no_revoke = false;
|
||||
bool curl_initialized = false; // non configurable, used in fetch only
|
||||
|
||||
std::string user_agent = "";
|
||||
|
||||
double connect_timeout_secs = 10.;
|
||||
// int read_timeout_secs { 60 };
|
||||
int retry_timeout = 2; // seconds
|
||||
int retry_backoff = 3; // retry_timeout * retry_backoff
|
||||
int max_retries = 3; // max number of retries
|
||||
|
||||
std::map<std::string, std::string> proxy_servers;
|
||||
};
|
||||
|
||||
struct Options
|
||||
{
|
||||
using termination_function = std::optional<std::function<void()>>;
|
||||
|
||||
std::size_t download_threads = 1;
|
||||
bool fail_fast = false;
|
||||
bool sort = true;
|
||||
bool verbose = false;
|
||||
termination_function on_unexpected_termination = std::nullopt;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
|
@ -97,7 +97,13 @@ namespace mamba
|
|||
url_str,
|
||||
tmp_file->path()
|
||||
);
|
||||
const download::Result res = download::download(std::move(request), ctx.mirrors, ctx);
|
||||
const download::Result res = download::download(
|
||||
std::move(request),
|
||||
ctx.mirrors,
|
||||
ctx.remote_fetch_params,
|
||||
ctx.authentication_info(),
|
||||
ctx.download_options()
|
||||
);
|
||||
|
||||
if (!res || res.value().transfer.http_status != 200)
|
||||
{
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
// The full license is in the file LICENSE, distributed with this software.
|
||||
|
||||
#include "mamba/core/invoke.hpp"
|
||||
#include "mamba/core/output.hpp"
|
||||
#include "mamba/core/package_fetcher.hpp"
|
||||
#include "mamba/core/util.hpp"
|
||||
#include "mamba/specs/archive.hpp"
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <stdexcept>
|
||||
|
||||
#include "mamba/core/channel_context.hpp"
|
||||
#include "mamba/core/context.hpp"
|
||||
#include "mamba/core/output.hpp"
|
||||
#include "mamba/core/package_cache.hpp"
|
||||
#include "mamba/core/subdirdata.hpp"
|
||||
|
@ -517,7 +518,14 @@ namespace mamba
|
|||
std::move(check_list.begin(), check_list.end(), std::back_inserter(check_requests));
|
||||
}
|
||||
}
|
||||
download::download(std::move(check_requests), context.mirrors, context, {}, check_monitor);
|
||||
download::download(
|
||||
std::move(check_requests),
|
||||
context.mirrors,
|
||||
context.remote_fetch_params,
|
||||
context.authentication_info(),
|
||||
context.download_options(),
|
||||
check_monitor
|
||||
);
|
||||
|
||||
if (is_sig_interrupted())
|
||||
{
|
||||
|
@ -541,8 +549,9 @@ namespace mamba
|
|||
download::download(
|
||||
std::move(index_requests),
|
||||
context.mirrors,
|
||||
context,
|
||||
{ /*fail_fast=*/true },
|
||||
context.remote_fetch_params,
|
||||
context.authentication_info(),
|
||||
context.download_options(),
|
||||
download_monitor
|
||||
);
|
||||
}
|
||||
|
|
|
@ -715,7 +715,14 @@ namespace mamba
|
|||
PackageDownloadMonitor* monitor
|
||||
)
|
||||
{
|
||||
auto result = download::download(std::move(requests), context.mirrors, context, options, monitor);
|
||||
auto result = download::download(
|
||||
std::move(requests),
|
||||
context.mirrors,
|
||||
context.remote_fetch_params,
|
||||
context.authentication_info(),
|
||||
options,
|
||||
monitor
|
||||
);
|
||||
bool all_downloaded = std::all_of(
|
||||
result.begin(),
|
||||
result.end(),
|
||||
|
@ -779,7 +786,8 @@ namespace mamba
|
|||
);
|
||||
|
||||
std::unique_ptr<PackageDownloadMonitor> monitor = nullptr;
|
||||
download::Options download_options{ true, true };
|
||||
auto download_options = ctx.download_options();
|
||||
download_options.fail_fast = true;
|
||||
if (PackageDownloadMonitor::can_monitor(ctx))
|
||||
{
|
||||
monitor = std::make_unique<PackageDownloadMonitor>();
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace mamba::download
|
|||
"/usr/local/share/certs/ca-root.crt",
|
||||
};
|
||||
|
||||
void init_remote_fetch_params(Context::RemoteFetchParams& remote_fetch_params)
|
||||
void init_remote_fetch_params(RemoteFetchParams& remote_fetch_params)
|
||||
{
|
||||
if (!remote_fetch_params.curl_initialized)
|
||||
{
|
||||
|
@ -145,7 +145,7 @@ namespace mamba::download
|
|||
bool set_ssl_no_revoke = false;
|
||||
};
|
||||
|
||||
EnvRemoteParams get_env_remote_params(const Context& context)
|
||||
EnvRemoteParams get_env_remote_params(const RemoteFetchParams& params)
|
||||
{
|
||||
// TODO: we should probably store set_low_speed_limit and set_ssl_no_revoke in
|
||||
// RemoteFetchParams if the request is slower than 30b/s for 60 seconds, cancel.
|
||||
|
@ -154,8 +154,7 @@ namespace mamba::download
|
|||
const bool set_low_speed_opt = (no_low_speed_limit == "0");
|
||||
|
||||
const std::string ssl_no_revoke_env = util::get_env("MAMBA_SSL_NO_REVOKE").value_or("0");
|
||||
const bool set_ssl_no_revoke = context.remote_fetch_params.ssl_no_revoke
|
||||
|| (ssl_no_revoke_env != "0");
|
||||
const bool set_ssl_no_revoke = params.ssl_no_revoke || (ssl_no_revoke_env != "0");
|
||||
|
||||
return { set_low_speed_opt, set_ssl_no_revoke };
|
||||
}
|
||||
|
@ -169,12 +168,22 @@ namespace mamba::download
|
|||
CURLHandle& handle,
|
||||
const MirrorRequest& request,
|
||||
CURLMultiHandle& downloader,
|
||||
const Context& context,
|
||||
const RemoteFetchParams& params,
|
||||
const specs::AuthenticationDataBase& auth_info,
|
||||
bool verbose,
|
||||
on_success_callback success,
|
||||
on_failure_callback error
|
||||
)
|
||||
: p_impl(std::make_unique<
|
||||
Impl>(handle, request, downloader, context, std::move(success), std::move(error)))
|
||||
: p_impl(std::make_unique<Impl>(
|
||||
handle,
|
||||
request,
|
||||
downloader,
|
||||
params,
|
||||
auth_info,
|
||||
verbose,
|
||||
std::move(success),
|
||||
std::move(error)
|
||||
))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -188,7 +197,9 @@ namespace mamba::download
|
|||
CURLHandle& handle,
|
||||
const MirrorRequest& request,
|
||||
CURLMultiHandle& downloader,
|
||||
const Context& context,
|
||||
const RemoteFetchParams& params,
|
||||
const specs::AuthenticationDataBase& auth_info,
|
||||
bool verbose,
|
||||
on_success_callback success,
|
||||
on_failure_callback error
|
||||
)
|
||||
|
@ -196,14 +207,14 @@ namespace mamba::download
|
|||
, p_request(&request)
|
||||
, m_success_callback(std::move(success))
|
||||
, m_failure_callback(std::move(error))
|
||||
, m_retry_wait_seconds(static_cast<std::size_t>(context.remote_fetch_params.retry_timeout))
|
||||
, m_retry_wait_seconds(static_cast<std::size_t>(params.retry_timeout))
|
||||
{
|
||||
p_stream = make_compression_stream(
|
||||
p_request->url,
|
||||
p_request->is_repodata_zst,
|
||||
[this](char* in, std::size_t size) { return this->write_data(in, size); }
|
||||
);
|
||||
configure_handle(context);
|
||||
configure_handle(params, auth_info, verbose);
|
||||
downloader.add_handle(*p_handle);
|
||||
}
|
||||
|
||||
|
@ -313,17 +324,21 @@ namespace mamba::download
|
|||
}
|
||||
}
|
||||
|
||||
void DownloadAttempt::Impl::configure_handle(const Context& context)
|
||||
void DownloadAttempt::Impl::configure_handle(
|
||||
const RemoteFetchParams& params,
|
||||
const specs::AuthenticationDataBase& auth_info,
|
||||
bool verbose
|
||||
)
|
||||
{
|
||||
const auto [set_low_speed_opt, set_ssl_no_revoke] = get_env_remote_params(context);
|
||||
const auto [set_low_speed_opt, set_ssl_no_revoke] = get_env_remote_params(params);
|
||||
|
||||
p_handle->configure_handle(
|
||||
util::file_uri_unc2_to_unc4(p_request->url),
|
||||
set_low_speed_opt,
|
||||
context.remote_fetch_params.connect_timeout_secs,
|
||||
params.connect_timeout_secs,
|
||||
set_ssl_no_revoke,
|
||||
proxy_match(p_request->url, context.remote_fetch_params.proxy_servers),
|
||||
context.remote_fetch_params.ssl_verify
|
||||
proxy_match(p_request->url, params.proxy_servers),
|
||||
params.ssl_verify
|
||||
);
|
||||
|
||||
if (!p_request->username.empty())
|
||||
|
@ -358,24 +373,23 @@ namespace mamba::download
|
|||
p_handle->add_header("Content-Type: application/json");
|
||||
}
|
||||
|
||||
p_handle->set_opt(CURLOPT_VERBOSE, context.output_params.verbosity >= 2);
|
||||
p_handle->set_opt(CURLOPT_VERBOSE, verbose);
|
||||
|
||||
configure_handle_headers(context);
|
||||
configure_handle_headers(params, auth_info);
|
||||
|
||||
auto logger = spdlog::get("libcurl");
|
||||
p_handle->set_opt(CURLOPT_DEBUGFUNCTION, curl_debug_callback);
|
||||
p_handle->set_opt(CURLOPT_DEBUGDATA, logger.get());
|
||||
}
|
||||
|
||||
void DownloadAttempt::Impl::configure_handle_headers(const Context& context)
|
||||
void DownloadAttempt::Impl::configure_handle_headers(
|
||||
const RemoteFetchParams& params,
|
||||
const specs::AuthenticationDataBase& auth_info
|
||||
)
|
||||
{
|
||||
p_handle->reset_headers();
|
||||
|
||||
std::string user_agent = fmt::format(
|
||||
"User-Agent: {} {}",
|
||||
context.remote_fetch_params.user_agent,
|
||||
curl_version()
|
||||
);
|
||||
std::string user_agent = fmt::format("User-Agent: {} {}", params.user_agent, curl_version());
|
||||
p_handle->add_header(user_agent);
|
||||
|
||||
// get url host
|
||||
|
@ -389,7 +403,6 @@ namespace mamba::download
|
|||
|
||||
// TODO How should this be handled if not empty?
|
||||
// (think about precedence with request token auth header added below)
|
||||
const auto& auth_info = context.authentication_info();
|
||||
if (auto it = auth_info.find_weaken(host); it != auth_info.end())
|
||||
{
|
||||
if (const auto& auth = it->second; std::holds_alternative<specs::BearerToken>(auth))
|
||||
|
@ -671,7 +684,9 @@ namespace mamba::download
|
|||
auto MirrorAttempt::prepare_attempt(
|
||||
CURLHandle& handle,
|
||||
CURLMultiHandle& downloader,
|
||||
const Context& context,
|
||||
const RemoteFetchParams& params,
|
||||
const specs::AuthenticationDataBase& auth_info,
|
||||
bool verbose,
|
||||
on_success_callback success,
|
||||
on_failure_callback error
|
||||
) -> completion_function
|
||||
|
@ -682,7 +697,9 @@ namespace mamba::download
|
|||
handle,
|
||||
m_request.value(),
|
||||
downloader,
|
||||
context,
|
||||
params,
|
||||
auth_info,
|
||||
verbose,
|
||||
std::move(success),
|
||||
std::move(error)
|
||||
);
|
||||
|
@ -798,8 +815,13 @@ namespace mamba::download
|
|||
}
|
||||
}
|
||||
|
||||
auto DownloadTracker::prepare_new_attempt(CURLMultiHandle& handle, const Context& context)
|
||||
-> completion_map_entry
|
||||
auto DownloadTracker::prepare_new_attempt(
|
||||
CURLMultiHandle& handle,
|
||||
const RemoteFetchParams& params,
|
||||
const specs::AuthenticationDataBase& auth_info,
|
||||
bool verbose
|
||||
|
||||
) -> completion_map_entry
|
||||
{
|
||||
m_state = State::PREPARING;
|
||||
|
||||
|
@ -807,7 +829,9 @@ namespace mamba::download
|
|||
auto completion_func = m_mirror_attempt.prepare_attempt(
|
||||
m_handle,
|
||||
handle,
|
||||
context,
|
||||
params,
|
||||
auth_info,
|
||||
verbose,
|
||||
[this](Success res)
|
||||
{
|
||||
expected_t<void> finalize_res = invoke_on_success(res);
|
||||
|
@ -1031,14 +1055,16 @@ namespace mamba::download
|
|||
MultiRequest requests,
|
||||
const mirror_map& mirrors,
|
||||
Options options,
|
||||
const Context& context
|
||||
const RemoteFetchParams& params,
|
||||
const specs::AuthenticationDataBase& auth_info
|
||||
)
|
||||
: m_requests(std::move(requests))
|
||||
, p_mirrors(&mirrors)
|
||||
, m_options(std::move(options))
|
||||
, p_context(&context)
|
||||
, m_curl_handle(context.threads_params.download_threads)
|
||||
, m_trackers()
|
||||
, m_curl_handle(options.download_threads)
|
||||
, m_options(std::move(options))
|
||||
, p_mirrors(&mirrors)
|
||||
, p_params(¶ms)
|
||||
, p_auth_info(&auth_info)
|
||||
{
|
||||
if (m_options.sort)
|
||||
{
|
||||
|
@ -1051,7 +1077,7 @@ namespace mamba::download
|
|||
}
|
||||
|
||||
m_trackers.reserve(m_requests.size());
|
||||
std::size_t max_retries = static_cast<std::size_t>(context.remote_fetch_params.max_retries);
|
||||
std::size_t max_retries = static_cast<std::size_t>(params.max_retries);
|
||||
DownloadTrackerOptions tracker_options{ max_retries, options.fail_fast };
|
||||
std::transform(
|
||||
m_requests.begin(),
|
||||
|
@ -1089,7 +1115,7 @@ namespace mamba::download
|
|||
void Downloader::prepare_next_downloads()
|
||||
{
|
||||
size_t running_attempts = m_completion_map.size();
|
||||
const size_t max_parallel_downloads = p_context->threads_params.download_threads;
|
||||
const size_t max_parallel_downloads = m_options.download_threads;
|
||||
auto start_filter = mamba::util::filter(
|
||||
m_trackers,
|
||||
[&](DownloadTracker& tracker)
|
||||
|
@ -1100,7 +1126,7 @@ namespace mamba::download
|
|||
for (auto& tracker : start_filter)
|
||||
{
|
||||
auto [iter, success] = m_completion_map.insert(
|
||||
tracker.prepare_new_attempt(m_curl_handle, *p_context)
|
||||
tracker.prepare_new_attempt(m_curl_handle, *p_params, *p_auth_info, m_options.verbose)
|
||||
);
|
||||
if (success)
|
||||
{
|
||||
|
@ -1196,30 +1222,31 @@ namespace mamba::download
|
|||
MultiResult download(
|
||||
MultiRequest requests,
|
||||
const mirror_map& mirrors,
|
||||
const Context& context,
|
||||
const RemoteFetchParams& params,
|
||||
const specs::AuthenticationDataBase& auth_info,
|
||||
Options options,
|
||||
Monitor* monitor
|
||||
)
|
||||
{
|
||||
if (!context.remote_fetch_params.curl_initialized)
|
||||
if (!params.curl_initialized)
|
||||
{
|
||||
// TODO: Move this into an object that would be automatically initialized
|
||||
// upon construction, and passed by const reference to this function instead
|
||||
// of context.
|
||||
Context& ctx = const_cast<Context&>(context);
|
||||
init_remote_fetch_params(ctx.remote_fetch_params);
|
||||
auto& params_ = const_cast<RemoteFetchParams&>(params);
|
||||
init_remote_fetch_params(params_);
|
||||
}
|
||||
|
||||
if (monitor)
|
||||
{
|
||||
monitor->observe(requests, options);
|
||||
on_scope_exit guard([monitor]() { monitor->on_done(); });
|
||||
Downloader dl(std::move(requests), mirrors, std::move(options), context);
|
||||
Downloader dl(std::move(requests), mirrors, std::move(options), params, auth_info);
|
||||
return dl.download();
|
||||
}
|
||||
else
|
||||
{
|
||||
Downloader dl(std::move(requests), mirrors, std::move(options), context);
|
||||
Downloader dl(std::move(requests), mirrors, std::move(options), params, auth_info);
|
||||
return dl.download();
|
||||
}
|
||||
}
|
||||
|
@ -1227,36 +1254,37 @@ namespace mamba::download
|
|||
Result download(
|
||||
Request request,
|
||||
const mirror_map& mirrors,
|
||||
const Context& context,
|
||||
const RemoteFetchParams& params,
|
||||
const specs::AuthenticationDataBase& auth_info,
|
||||
Options options,
|
||||
Monitor* monitor
|
||||
)
|
||||
{
|
||||
MultiRequest req(1u, std::move(request));
|
||||
auto res = download(std::move(req), mirrors, context, std::move(options), monitor);
|
||||
auto res = download(std::move(req), mirrors, params, auth_info, std::move(options), monitor);
|
||||
return std::move(res.front());
|
||||
}
|
||||
|
||||
bool check_resource_exists(const std::string& url, const Context& context)
|
||||
bool check_resource_exists(const std::string& url, const RemoteFetchParams& params)
|
||||
{
|
||||
if (!context.remote_fetch_params.curl_initialized)
|
||||
if (!params.curl_initialized)
|
||||
{
|
||||
// TODO: Move this into an object that would be automatically initialized
|
||||
// upon construction, and passed by const reference to this function instead
|
||||
// of context.
|
||||
Context& ctx = const_cast<Context&>(context);
|
||||
init_remote_fetch_params(ctx.remote_fetch_params);
|
||||
auto& params_ = const_cast<RemoteFetchParams&>(params);
|
||||
init_remote_fetch_params(params_);
|
||||
}
|
||||
|
||||
const auto [set_low_speed_opt, set_ssl_no_revoke] = get_env_remote_params(context);
|
||||
const auto [set_low_speed_opt, set_ssl_no_revoke] = get_env_remote_params(params);
|
||||
|
||||
return curl::check_resource_exists(
|
||||
util::file_uri_unc2_to_unc4(url),
|
||||
set_low_speed_opt,
|
||||
context.remote_fetch_params.connect_timeout_secs,
|
||||
params.connect_timeout_secs,
|
||||
set_ssl_no_revoke,
|
||||
proxy_match(url, context.remote_fetch_params.proxy_servers),
|
||||
context.remote_fetch_params.ssl_verify
|
||||
proxy_match(url, params.proxy_servers),
|
||||
params.ssl_verify
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,11 +8,14 @@
|
|||
#define MAMBA_DL_DOWNLOADER_IMPL_HPP
|
||||
|
||||
#include <chrono>
|
||||
#include <fstream>
|
||||
#include <optional>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "mamba/download/downloader.hpp"
|
||||
#include "mamba/download/mirror_map.hpp"
|
||||
#include "mamba/download/parameters.hpp"
|
||||
#include "mamba/specs/authentication_info.hpp"
|
||||
#include "mamba/util/flat_set.hpp"
|
||||
|
||||
#include "compression.hpp"
|
||||
|
@ -37,7 +40,9 @@ namespace mamba::download
|
|||
CURLHandle& handle,
|
||||
const MirrorRequest& request,
|
||||
CURLMultiHandle& downloader,
|
||||
const Context& context,
|
||||
const RemoteFetchParams& params,
|
||||
const specs::AuthenticationDataBase& auth_info,
|
||||
bool verbose,
|
||||
on_success_callback success,
|
||||
on_failure_callback error
|
||||
);
|
||||
|
@ -55,7 +60,9 @@ namespace mamba::download
|
|||
CURLHandle& handle,
|
||||
const MirrorRequest& request,
|
||||
CURLMultiHandle& downloader,
|
||||
const Context& context,
|
||||
const RemoteFetchParams& params,
|
||||
const specs::AuthenticationDataBase& auth_info,
|
||||
bool verbose,
|
||||
on_success_callback success,
|
||||
on_failure_callback error
|
||||
);
|
||||
|
@ -64,8 +71,15 @@ namespace mamba::download
|
|||
void clean_attempt(CURLMultiHandle& downloader, bool erase_downloaded);
|
||||
void invoke_progress_callback(const Event&) const;
|
||||
|
||||
void configure_handle(const Context& context);
|
||||
void configure_handle_headers(const Context& context);
|
||||
void configure_handle(
|
||||
const RemoteFetchParams& params,
|
||||
const specs::AuthenticationDataBase& auth_info,
|
||||
bool verbose
|
||||
);
|
||||
void configure_handle_headers(
|
||||
const RemoteFetchParams& params,
|
||||
const specs::AuthenticationDataBase& auth_info
|
||||
);
|
||||
|
||||
size_t write_data(char* buffer, size_t data);
|
||||
|
||||
|
@ -128,7 +142,9 @@ namespace mamba::download
|
|||
auto prepare_attempt(
|
||||
CURLHandle& handle,
|
||||
CURLMultiHandle& downloader,
|
||||
const Context& context,
|
||||
const RemoteFetchParams& params,
|
||||
const specs::AuthenticationDataBase& auth_info,
|
||||
bool verbose,
|
||||
on_success_callback success,
|
||||
on_failure_callback error
|
||||
) -> completion_function;
|
||||
|
@ -193,8 +209,12 @@ namespace mamba::download
|
|||
DownloadTrackerOptions options
|
||||
);
|
||||
|
||||
auto prepare_new_attempt(CURLMultiHandle& handle, const Context& context)
|
||||
-> completion_map_entry;
|
||||
auto prepare_new_attempt(
|
||||
CURLMultiHandle& handle,
|
||||
const RemoteFetchParams& params,
|
||||
const specs::AuthenticationDataBase& auth_info,
|
||||
bool verbose
|
||||
) -> completion_map_entry;
|
||||
|
||||
bool has_failed() const;
|
||||
bool can_start_transfer() const;
|
||||
|
@ -261,7 +281,8 @@ namespace mamba::download
|
|||
MultiRequest requests,
|
||||
const mirror_map& mirrors,
|
||||
Options options,
|
||||
const Context& context
|
||||
const RemoteFetchParams& params,
|
||||
const specs::AuthenticationDataBase& auth_info
|
||||
);
|
||||
|
||||
MultiResult download();
|
||||
|
@ -275,12 +296,13 @@ namespace mamba::download
|
|||
void invoke_unexpected_termination() const;
|
||||
|
||||
MultiRequest m_requests;
|
||||
const mirror_map* p_mirrors;
|
||||
Options m_options;
|
||||
const Context* p_context;
|
||||
CURLMultiHandle m_curl_handle;
|
||||
std::vector<DownloadTracker> m_trackers;
|
||||
size_t m_waiting_count;
|
||||
CURLMultiHandle m_curl_handle;
|
||||
Options m_options;
|
||||
const mirror_map* p_mirrors;
|
||||
const RemoteFetchParams* p_params;
|
||||
const specs::AuthenticationDataBase* p_auth_info;
|
||||
std::size_t m_waiting_count;
|
||||
|
||||
using completion_function = DownloadTracker::completion_function;
|
||||
std::unordered_map<CURLId, completion_function> m_completion_map;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include "mamba/core/context.hpp"
|
||||
#include "mamba/core/output.hpp"
|
||||
#include "mamba/core/timeref.hpp"
|
||||
#include "mamba/core/util.hpp"
|
||||
|
@ -224,14 +225,16 @@ namespace mamba::validation
|
|||
auto url = util::concat(m_base_url, "/", f.string());
|
||||
tmp_file_path = tmp_dir_path / f;
|
||||
|
||||
if (download::check_resource_exists(url, m_context))
|
||||
if (download::check_resource_exists(url, m_context.get().remote_fetch_params))
|
||||
{
|
||||
download::Request
|
||||
request(f.string(), download::MirrorName(""), url, tmp_file_path.string());
|
||||
download::Result res = download::download(
|
||||
std::move(request),
|
||||
m_context.get().mirrors,
|
||||
m_context
|
||||
m_context.get().remote_fetch_params,
|
||||
m_context.get().authentication_info(),
|
||||
m_context.get().download_options()
|
||||
);
|
||||
|
||||
if (res)
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <fstream>
|
||||
#include <utility>
|
||||
|
||||
#include "mamba/core/context.hpp"
|
||||
#include "mamba/core/output.hpp"
|
||||
#include "mamba/core/util.hpp"
|
||||
#include "mamba/download/downloader.hpp"
|
||||
|
@ -204,7 +205,7 @@ namespace mamba::validation::v0_6
|
|||
.value()
|
||||
/ "key_mgr.json";
|
||||
|
||||
if (download::check_resource_exists(url.pretty_str(), context))
|
||||
if (download::check_resource_exists(url.pretty_str(), context.remote_fetch_params))
|
||||
{
|
||||
download::Request request(
|
||||
"key_mgr.json",
|
||||
|
@ -212,7 +213,18 @@ namespace mamba::validation::v0_6
|
|||
url.str(util::URL::Credentials::Show),
|
||||
tmp_metadata_path.string()
|
||||
);
|
||||
download::Result res = download::download(std::move(request), context.mirrors, context);
|
||||
download::Result res = download::download(
|
||||
std::move(request),
|
||||
context.mirrors,
|
||||
context.remote_fetch_params,
|
||||
context.authentication_info(),
|
||||
download::Options{
|
||||
/* .download_threads */ context.threads_params.download_threads,
|
||||
/* .fail_fast */ false,
|
||||
/* .sort */ true,
|
||||
/* .verbose */ context.output_params.verbosity >= 2,
|
||||
}
|
||||
);
|
||||
if (res)
|
||||
{
|
||||
KeyMgrRole key_mgr = create_key_mgr(tmp_metadata_path);
|
||||
|
@ -365,7 +377,7 @@ namespace mamba::validation::v0_6
|
|||
|
||||
const auto url = mamba::util::URL::parse(base_url + "/pkg_mgr.json").value();
|
||||
|
||||
if (download::check_resource_exists(url.pretty_str(), context))
|
||||
if (download::check_resource_exists(url.pretty_str(), context.remote_fetch_params))
|
||||
{
|
||||
download::Request request(
|
||||
"pkg_mgr.json",
|
||||
|
@ -373,7 +385,13 @@ namespace mamba::validation::v0_6
|
|||
url.pretty_str(),
|
||||
tmp_metadata_path.string()
|
||||
);
|
||||
download::Result res = download::download(std::move(request), context.mirrors, context);
|
||||
download::Result res = download::download(
|
||||
std::move(request),
|
||||
context.mirrors,
|
||||
context.remote_fetch_params,
|
||||
context.authentication_info(),
|
||||
context.download_options()
|
||||
);
|
||||
|
||||
if (res)
|
||||
{
|
||||
|
|
|
@ -7,79 +7,68 @@
|
|||
#include <catch2/catch_all.hpp>
|
||||
|
||||
#include "mamba/api/configuration.hpp"
|
||||
#include "mamba/core/util.hpp"
|
||||
#include "mamba/download/downloader.hpp"
|
||||
|
||||
#include "mambatests.hpp"
|
||||
#include "mamba/util/string.hpp"
|
||||
|
||||
namespace mamba
|
||||
{
|
||||
namespace
|
||||
{
|
||||
TEST_CASE("file_does_not_exist")
|
||||
TEST_CASE("file_does_not_exist", "[mamba::download]")
|
||||
{
|
||||
download::Request request(
|
||||
"test",
|
||||
download::MirrorName(""),
|
||||
"file:///nonexistent/repodata.json",
|
||||
"test_download_repodata.json",
|
||||
"test_download_repodata_1.json",
|
||||
false,
|
||||
true
|
||||
);
|
||||
auto& context = mambatests::singletons().context;
|
||||
const auto previous_quiet = context.output_params.quiet;
|
||||
auto _ = on_scope_exit([&] { context.output_params.quiet = previous_quiet; });
|
||||
|
||||
download::MultiRequest dl_request{ std::vector{ std::move(request) } };
|
||||
context.output_params.quiet = true;
|
||||
download::MultiResult res = download::download(dl_request, context.mirrors, context);
|
||||
download::MultiResult res = download::download(dl_request, {}, {}, {});
|
||||
REQUIRE(res.size() == std::size_t(1));
|
||||
REQUIRE(!res[0]);
|
||||
REQUIRE(res[0].error().attempt_number == std::size_t(1));
|
||||
}
|
||||
|
||||
TEST_CASE("file_does_not_exist_throw")
|
||||
TEST_CASE("file_does_not_exist_throw", "[mamba::download]")
|
||||
{
|
||||
download::Request request(
|
||||
"test",
|
||||
download::MirrorName(""),
|
||||
"file:///nonexistent/repodata.json",
|
||||
"test_download_repodata.json"
|
||||
"test_download_repodata_2.json"
|
||||
);
|
||||
download::MultiRequest dl_request{ std::vector{ std::move(request) } };
|
||||
auto& context = mambatests::singletons().context;
|
||||
const auto previous_quiet = context.output_params.quiet;
|
||||
auto _ = on_scope_exit([&] { context.output_params.quiet = previous_quiet; });
|
||||
context.output_params.quiet = true;
|
||||
REQUIRE_THROWS_AS(
|
||||
download::download(dl_request, context.mirrors, context),
|
||||
std::runtime_error
|
||||
);
|
||||
REQUIRE_THROWS_AS(download::download(dl_request, {}, {}, {}), std::runtime_error);
|
||||
}
|
||||
|
||||
TEST_CASE("Use CA certificate from the root prefix")
|
||||
TEST_CASE("Use CA certificate from the root prefix", "[mamba::download]")
|
||||
{
|
||||
// Create a context, make a request and check that ssl_verify is set to the correct path
|
||||
auto& context = mambatests::singletons().context;
|
||||
const auto tmp_dir = TemporaryDirectory();
|
||||
|
||||
// Set the context values to the default ones
|
||||
context.remote_fetch_params.curl_initialized = false;
|
||||
context.remote_fetch_params.ssl_verify = "<system>";
|
||||
auto params = download::RemoteFetchParams{};
|
||||
params.curl_initialized = false;
|
||||
params.ssl_verify = "<system>";
|
||||
|
||||
download::Request request(
|
||||
"test",
|
||||
download::MirrorName(""),
|
||||
"https://conda.anaconda.org/conda-forge/linux-64/repodata.json",
|
||||
"test_download_repodata.json"
|
||||
tmp_dir.path() / "test_download_repodata_3.json"
|
||||
);
|
||||
download::MultiRequest dl_request{ std::vector{ std::move(request) } };
|
||||
|
||||
// Downloading must initialize curl and set `ssl_verify` to the path of the CA
|
||||
// certificate
|
||||
REQUIRE(!context.remote_fetch_params.curl_initialized);
|
||||
download::MultiResult res = download::download(dl_request, context.mirrors, context);
|
||||
REQUIRE(context.remote_fetch_params.curl_initialized);
|
||||
REQUIRE(!params.curl_initialized);
|
||||
download::MultiResult res = download::download(dl_request, {}, params, {});
|
||||
REQUIRE(params.curl_initialized);
|
||||
|
||||
auto certificates = context.remote_fetch_params.ssl_verify;
|
||||
auto certificates = params.ssl_verify;
|
||||
const fs::u8path root_prefix = detail::get_root_prefix();
|
||||
const fs::u8path expected_certificates = root_prefix / "ssl" / "cert.pem";
|
||||
|
||||
|
|
|
@ -18,35 +18,35 @@ namespace mamba::download
|
|||
|
||||
namespace
|
||||
{
|
||||
TEST_CASE("tar_bz2_extension")
|
||||
TEST_CASE("tar_bz2_extension", "[mamba::download]")
|
||||
{
|
||||
auto [split_path, split_tag] = split_path_tag("xtensor-0.23.10-h2acdbc0_0.tar.bz2");
|
||||
REQUIRE(split_path == "xtensor");
|
||||
REQUIRE(split_tag == "0.23.10-h2acdbc0-0");
|
||||
}
|
||||
|
||||
TEST_CASE("multiple_parts")
|
||||
TEST_CASE("multiple_parts", "[mamba::download]")
|
||||
{
|
||||
auto [split_path, split_tag] = split_path_tag("x-tensor-10.23.10-h2acdbc0_0.tar.bz2");
|
||||
REQUIRE(split_path == "x-tensor");
|
||||
REQUIRE(split_tag == "10.23.10-h2acdbc0-0");
|
||||
}
|
||||
|
||||
TEST_CASE("more_multiple_parts")
|
||||
TEST_CASE("more_multiple_parts", "[mamba::download]")
|
||||
{
|
||||
auto [split_path, split_tag] = split_path_tag("x-tens-or-10.23.10-h2acdbc0_0.tar.bz2");
|
||||
REQUIRE(split_path == "x-tens-or");
|
||||
REQUIRE(split_tag == "10.23.10-h2acdbc0-0");
|
||||
}
|
||||
|
||||
TEST_CASE("json_extension")
|
||||
TEST_CASE("json_extension", "[mamba::download]")
|
||||
{
|
||||
auto [split_path, split_tag] = split_path_tag("xtensor-0.23.10-h2acdbc0_0.json");
|
||||
REQUIRE(split_path == "xtensor-0.23.10-h2acdbc0_0.json");
|
||||
REQUIRE(split_tag == "latest");
|
||||
}
|
||||
|
||||
TEST_CASE("not_enough_parts")
|
||||
TEST_CASE("not_enough_parts", "[mamba::download]")
|
||||
{
|
||||
REQUIRE_THROWS_AS(split_path_tag("xtensor.tar.bz2"), std::runtime_error);
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ namespace mamba::download
|
|||
|
||||
namespace
|
||||
{
|
||||
TEST_CASE("PassThroughMirror")
|
||||
TEST_CASE("PassThroughMirror", "[mamba::download]")
|
||||
{
|
||||
std::unique_ptr<Mirror> mir = make_mirror("");
|
||||
// `mir_ref` is used here to provide an explicit expression to `typeid`
|
||||
|
@ -73,7 +73,7 @@ namespace mamba::download
|
|||
REQUIRE(mir_req.url == "linux-64/repodata.json");
|
||||
}
|
||||
|
||||
TEST_CASE("HTTPMirror")
|
||||
TEST_CASE("HTTPMirror", "[mamba::download]")
|
||||
{
|
||||
SECTION("https")
|
||||
{
|
||||
|
@ -142,7 +142,7 @@ namespace mamba::download
|
|||
}
|
||||
}
|
||||
|
||||
TEST_CASE("OCIMirror")
|
||||
TEST_CASE("OCIMirror", "[mamba::download]")
|
||||
{
|
||||
SECTION("Request repodata.json")
|
||||
{
|
||||
|
@ -208,7 +208,7 @@ namespace mamba::download
|
|||
}
|
||||
}
|
||||
|
||||
TEST_CASE("nullptr")
|
||||
TEST_CASE("nullptr", "[mamba::download]")
|
||||
{
|
||||
std::unique_ptr<Mirror> mir = make_mirror("ghcr.io/channel-mirrors/conda-forge");
|
||||
REQUIRE(mir == nullptr);
|
||||
|
|
|
@ -741,16 +741,16 @@ bind_submodule_impl(pybind11::module_ m)
|
|||
.def("set_verbosity", &Context::set_verbosity)
|
||||
.def("set_log_level", &Context::set_log_level);
|
||||
|
||||
py::class_<Context::RemoteFetchParams>(ctx, "RemoteFetchParams")
|
||||
py::class_<download::RemoteFetchParams>(ctx, "RemoteFetchParams")
|
||||
.def(py::init<>())
|
||||
.def_readwrite("ssl_verify", &Context::RemoteFetchParams::ssl_verify)
|
||||
.def_readwrite("max_retries", &Context::RemoteFetchParams::max_retries)
|
||||
.def_readwrite("retry_timeout", &Context::RemoteFetchParams::retry_timeout)
|
||||
.def_readwrite("retry_backoff", &Context::RemoteFetchParams::retry_backoff)
|
||||
.def_readwrite("user_agent", &Context::RemoteFetchParams::user_agent)
|
||||
.def_readwrite("ssl_verify", &download::RemoteFetchParams::ssl_verify)
|
||||
.def_readwrite("max_retries", &download::RemoteFetchParams::max_retries)
|
||||
.def_readwrite("retry_timeout", &download::RemoteFetchParams::retry_timeout)
|
||||
.def_readwrite("retry_backoff", &download::RemoteFetchParams::retry_backoff)
|
||||
.def_readwrite("user_agent", &download::RemoteFetchParams::user_agent)
|
||||
// .def_readwrite("read_timeout_secs", &Context::RemoteFetchParams::read_timeout_secs)
|
||||
.def_readwrite("proxy_servers", &Context::RemoteFetchParams::proxy_servers)
|
||||
.def_readwrite("connect_timeout_secs", &Context::RemoteFetchParams::connect_timeout_secs);
|
||||
.def_readwrite("proxy_servers", &download::RemoteFetchParams::proxy_servers)
|
||||
.def_readwrite("connect_timeout_secs", &download::RemoteFetchParams::connect_timeout_secs);
|
||||
|
||||
py::class_<Context::OutputParams>(ctx, "OutputParams")
|
||||
.def(py::init<>())
|
||||
|
|
Loading…
Reference in New Issue