From 4887f43d983898e48feaffc467327bc7fc4e1180 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Fri, 10 Feb 2023 14:04:27 +0300 Subject: Add support for fetch timeout to system package managers --- bpkg/system-package-manager-debian.cxx | 27 +++++++++++++++++--- bpkg/system-package-manager-debian.hxx | 4 ++- bpkg/system-package-manager-debian.test.cxx | 3 +++ bpkg/system-package-manager-fedora.cxx | 39 +++++++++++++++++++---------- bpkg/system-package-manager-fedora.hxx | 6 ++++- bpkg/system-package-manager-fedora.test.cxx | 3 +++ bpkg/system-package-manager.cxx | 10 +++++--- bpkg/system-package-manager.hxx | 8 +++++- 8 files changed, 78 insertions(+), 22 deletions(-) diff --git a/bpkg/system-package-manager-debian.cxx b/bpkg/system-package-manager-debian.cxx index b131851..b541541 100644 --- a/bpkg/system-package-manager-debian.cxx +++ b/bpkg/system-package-manager-debian.cxx @@ -670,8 +670,13 @@ namespace bpkg // Prepare the common `apt-get ` options. // pair system_package_manager_debian:: - apt_get_common (const char* command) + apt_get_common (const char* command, strings& args_storage) { + // Pre-allocate the required number of entries in the arguments storage. + // + if (fetch_timeout_) + args_storage.reserve (1); + cstrings args; if (!sudo_.empty ()) @@ -721,6 +726,18 @@ namespace bpkg args.push_back ("--assume-no"); } + // Add the network operations timeout options, if requested. + // + if (fetch_timeout_) + { + args.push_back ("-o"); + + args_storage.push_back ( + "Acquire::http::Timeout=" + to_string (*fetch_timeout_)); + + args.push_back (args_storage.back ().c_str ()); + } + try { const process_path* pp (nullptr); @@ -758,7 +775,9 @@ namespace bpkg void system_package_manager_debian:: apt_get_update () { - pair args_pp (apt_get_common ("update")); + strings args_storage; + pair args_pp ( + apt_get_common ("update", args_storage)); cstrings& args (args_pp.first); const process_path& pp (args_pp.second); @@ -815,7 +834,9 @@ namespace bpkg { assert (!pkgs.empty ()); - pair args_pp (apt_get_common ("install")); + strings args_storage; + pair args_pp ( + apt_get_common ("install", args_storage)); cstrings& args (args_pp.first); const process_path& pp (args_pp.second); diff --git a/bpkg/system-package-manager-debian.hxx b/bpkg/system-package-manager-debian.hxx index e01b25d..0186b76 100644 --- a/bpkg/system-package-manager-debian.hxx +++ b/bpkg/system-package-manager-debian.hxx @@ -146,6 +146,7 @@ namespace bpkg const target_triplet& h, string a, optional progress, + optional fetch_timeout, bool install, bool fetch, bool yes, @@ -154,6 +155,7 @@ namespace bpkg h, a.empty () ? arch_from_target (h) : move (a), progress, + fetch_timeout, install, fetch, yes, @@ -188,7 +190,7 @@ namespace bpkg apt_get_install (const strings&); pair - apt_get_common (const char*); + apt_get_common (const char*, strings& args_storage); static package_status parse_name_value (const package_name&, const string&, bool, bool); diff --git a/bpkg/system-package-manager-debian.test.cxx b/bpkg/system-package-manager-debian.test.cxx index d719860..3e71ad2 100644 --- a/bpkg/system-package-manager-debian.test.cxx +++ b/bpkg/system-package-manager-debian.test.cxx @@ -92,6 +92,7 @@ namespace bpkg host_triplet, "" /* arch */, nullopt /* progress */, + nullopt /* fetch_timeout */, false /* install */, false /* fetch */, false /* yes */, @@ -120,6 +121,7 @@ namespace bpkg host_triplet, "" /* arch */, nullopt /* progress */, + nullopt /* fetch_timeout */, false /* install */, false /* fetch */, false /* yes */, @@ -287,6 +289,7 @@ namespace bpkg host_triplet, "" /* arch */, nullopt /* progress */, + nullopt /* fetch_timeout */, install, fetch, false /* yes */, diff --git a/bpkg/system-package-manager-fedora.cxx b/bpkg/system-package-manager-fedora.cxx index 335cbda..3178e4e 100644 --- a/bpkg/system-package-manager-fedora.cxx +++ b/bpkg/system-package-manager-fedora.cxx @@ -739,8 +739,15 @@ namespace bpkg // Prepare the common options for commands which update the system. // pair system_package_manager_fedora:: - dnf_common (const char* command) + dnf_common (const char* command, + optional fetch_timeout, + strings& args_storage) { + // Pre-allocate the required number of entries in the arguments storage. + // + if (fetch_timeout) + args_storage.reserve (1); + cstrings args; if (!sudo_.empty ()) @@ -780,16 +787,16 @@ namespace bpkg args.push_back ("--assumeno"); } - // @@ Should we also add --setopt=timeout=... and --setopt=minrate=... - // options if --fetch-timeout common is specified? For example: + // Add the network operations timeout configuration options, if requested. // - // string t; - // if (fetch_timeout_) - // { - // t = "--setopt=timeout=" + to_string (*fetch_timeout_); - // args.push_back (t.c_str ()); - // args.push_back ("--setopt=minrate=0"); - // } + if (fetch_timeout) + { + args_storage.push_back ( + "--setopt=timeout=" + to_string (*fetch_timeout)); + + args.push_back (args_storage.back ().c_str ()); + args.push_back ("--setopt=minrate=0"); + } try { @@ -828,7 +835,9 @@ namespace bpkg void system_package_manager_fedora:: dnf_makecache () { - pair args_pp (dnf_common ("makecache")); + strings args_storage; + pair args_pp ( + dnf_common ("makecache", fetch_timeout_, args_storage)); cstrings& args (args_pp.first); const process_path& pp (args_pp.second); @@ -908,7 +917,9 @@ namespace bpkg { assert (!pkgs.empty ()); - pair args_pp (dnf_common ("install")); + strings args_storage; + pair args_pp ( + dnf_common ("install", fetch_timeout_, args_storage)); cstrings& args (args_pp.first); const process_path& pp (args_pp.second); @@ -1006,7 +1017,9 @@ namespace bpkg { assert (!pkgs.empty ()); - pair args_pp (dnf_common ("mark")); + strings args_storage; + pair args_pp ( + dnf_common ("mark", nullopt /* fetch_timeout */, args_storage)); cstrings& args (args_pp.first); const process_path& pp (args_pp.second); diff --git a/bpkg/system-package-manager-fedora.hxx b/bpkg/system-package-manager-fedora.hxx index df2e765..6c72b81 100644 --- a/bpkg/system-package-manager-fedora.hxx +++ b/bpkg/system-package-manager-fedora.hxx @@ -211,6 +211,7 @@ namespace bpkg const target_triplet& h, string a, optional progress, + optional fetch_timeout, bool install, bool fetch, bool yes, @@ -219,6 +220,7 @@ namespace bpkg h, a.empty () ? arch_from_target (h) : move (a), progress, + fetch_timeout, install, fetch, yes, @@ -256,7 +258,9 @@ namespace bpkg dnf_mark_install (const strings&); pair - dnf_common (const char*); + dnf_common (const char*, + optional fetch_timeout, + strings& args_storage); static package_status parse_name_value (const package_name&, const string&, bool, bool, bool); diff --git a/bpkg/system-package-manager-fedora.test.cxx b/bpkg/system-package-manager-fedora.test.cxx index 8064d19..11969b3 100644 --- a/bpkg/system-package-manager-fedora.test.cxx +++ b/bpkg/system-package-manager-fedora.test.cxx @@ -102,6 +102,7 @@ namespace bpkg host_triplet, "" /* arch */, nullopt /* progress */, + nullopt /* fetch_timeout */, false /* install */, false /* fetch */, false /* yes */, @@ -132,6 +133,7 @@ namespace bpkg host_triplet, "" /* arch */, nullopt /* progress */, + nullopt /* fetch_timeout */, false /* install */, false /* fetch */, false /* yes */, @@ -321,6 +323,7 @@ namespace bpkg host_triplet, "" /* arch */, nullopt /* progress */, + nullopt /* fetch_timeout */, install, fetch, false /* yes */, diff --git a/bpkg/system-package-manager.cxx b/bpkg/system-package-manager.cxx index caf951f..2ec7a60 100644 --- a/bpkg/system-package-manager.cxx +++ b/bpkg/system-package-manager.cxx @@ -53,10 +53,14 @@ namespace bpkg { // Note: similar to make_consumption_system_package_manager() below. - optional progress (co.progress () ? true : + optional progress (co.progress () ? true : co.no_progress () ? false : optional ()); + optional fetch_timeout (co.fetch_timeout_specified () + ? co.fetch_timeout () + : optional ()); + unique_ptr r; if (optional oos = host_os_release (host)) @@ -80,7 +84,7 @@ namespace bpkg r.reset (new system_package_manager_debian ( move (os), host, arch, - progress, install, fetch, yes, sudo)); + progress, fetch_timeout, install, fetch, yes, sudo)); } else if (is_or_like (os, "fedora") || is_or_like (os, "rhel") || @@ -100,7 +104,7 @@ namespace bpkg r.reset (new system_package_manager_fedora ( move (os), host, arch, - progress, install, fetch, yes, sudo)); + progress, fetch_timeout, install, fetch, yes, sudo)); } // NOTE: remember to update the --sys-distribution pkg-build option // documentation if adding support for another package manager. diff --git a/bpkg/system-package-manager.hxx b/bpkg/system-package-manager.hxx index 63bf676..941c981 100644 --- a/bpkg/system-package-manager.hxx +++ b/bpkg/system-package-manager.hxx @@ -188,10 +188,14 @@ namespace bpkg // available version of the not yet installed or partially installed // packages. // + // If fetch timeout (in seconds) is specified, then use it for all the + // underlying network operations. + // system_package_manager (bpkg::os_release&& osr, const target_triplet& h, string a, optional progress, + optional fetch_timeout, bool install, bool fetch, bool yes, @@ -200,6 +204,7 @@ namespace bpkg host (h), arch (move (a)), progress_ (progress), + fetch_timeout_ (fetch_timeout), install_ (install), fetch_ (fetch), yes_ (yes), @@ -283,7 +288,8 @@ namespace bpkg const string& version_id, const vector& like_ids); protected: - optional progress_; // --[no]-progress (see also stderr_term) + optional progress_; // --[no]-progress (see also stderr_term) + optional fetch_timeout_; // --fetch-timeout // The --sys-* option values. // -- cgit v1.1