diff --git a/include/libdnf5/conf/config_main.hpp b/include/libdnf5/conf/config_main.hpp index 23c6fac78..d6c534240 100644 --- a/include/libdnf5/conf/config_main.hpp +++ b/include/libdnf5/conf/config_main.hpp @@ -244,6 +244,10 @@ class LIBDNF_API ConfigMain : public Config { const OptionStringAppendList & get_exclude_from_weak_option() const; OptionBool & get_exclude_from_weak_autodetect_option(); const OptionBool & get_exclude_from_weak_autodetect_option() const; + OptionStringAppendList & get_metalink_exclude_domain_option(); + const OptionStringAppendList & get_metalink_exclude_domain_option() const; + OptionStringAppendList & get_metalink_exclude_location_option(); + const OptionStringAppendList & get_metalink_exclude_location_option() const; OptionString & get_proxy_option(); const OptionString & get_proxy_option() const; OptionString & get_proxy_username_option(); diff --git a/libdnf5/conf/config_main.cpp b/libdnf5/conf/config_main.cpp index a83e4a2bf..c4995c883 100644 --- a/libdnf5/conf/config_main.cpp +++ b/libdnf5/conf/config_main.cpp @@ -245,6 +245,8 @@ class ConfigMain::Impl { OptionStringAppendList includepkgs{std::vector{}}; OptionStringAppendList exclude_from_weak{std::vector{}}; OptionBool exclude_from_weak_autodetect{true}; + OptionStringAppendList metalink_exclude_domain{std::vector{}}; + OptionStringAppendList metalink_exclude_location{std::vector{}}; OptionString proxy{""}; OptionString proxy_username{nullptr}; OptionString proxy_password{nullptr}; @@ -423,6 +425,8 @@ ConfigMain::Impl::Impl(Config & owner) : owner(owner) { owner.opt_binds().add("includepkgs", includepkgs); owner.opt_binds().add("exclude_from_weak", exclude_from_weak); owner.opt_binds().add("exclude_from_weak_autodetect", exclude_from_weak_autodetect); + owner.opt_binds().add("metalink_exclude_domain", metalink_exclude_domain); + owner.opt_binds().add("metalink_exclude_location", metalink_exclude_location); owner.opt_binds().add("proxy", proxy); owner.opt_binds().add("proxy_username", proxy_username); owner.opt_binds().add("proxy_password", proxy_password); @@ -1121,6 +1125,22 @@ const OptionBool & ConfigMain::get_exclude_from_weak_autodetect_option() const { return p_impl->exclude_from_weak_autodetect; } +OptionStringAppendList & ConfigMain::get_metalink_exclude_domain_option() { + return p_impl->metalink_exclude_domain; +} + +const OptionStringAppendList & ConfigMain::get_metalink_exclude_domain_option() const { + return p_impl->metalink_exclude_domain; +} + +OptionStringAppendList & ConfigMain::get_metalink_exclude_location_option() { + return p_impl->metalink_exclude_location; +} + +const OptionStringAppendList & ConfigMain::get_metalink_exclude_location_option() const { + return p_impl->metalink_exclude_location; +} + OptionString & ConfigMain::get_proxy_option() { return p_impl->proxy; } @@ -1459,6 +1479,8 @@ void ConfigMain::Impl::load_from_config(const ConfigMain::Impl & other) { load_option(includepkgs, other.includepkgs); load_option(exclude_from_weak, other.exclude_from_weak); load_option(exclude_from_weak_autodetect, other.exclude_from_weak_autodetect); + load_option(metalink_exclude_domain, other.metalink_exclude_domain); + load_option(metalink_exclude_location, other.metalink_exclude_location); load_option(proxy, other.proxy); load_option(proxy_username, other.proxy_username); load_option(proxy_password, other.proxy_password); diff --git a/libdnf5/repo/repo_downloader.cpp b/libdnf5/repo/repo_downloader.cpp index a53d51d2c..226611c43 100644 --- a/libdnf5/repo/repo_downloader.cpp +++ b/libdnf5/repo/repo_downloader.cpp @@ -563,6 +563,22 @@ LibrepoHandle RepoDownloader::init_remote_handle(Repo & repo, const char * destd source = Source::MIRRORLIST; } if (source != Source::NONE) { + if (source == Source::METALINK) { + auto & metalink_exclude_domain = config.get_main_config().get_metalink_exclude_domain_option().get_value(); + if (!metalink_exclude_domain.empty()) { + std::vector c_metalink_exclude_domain(metalink_exclude_domain.size() + 1, nullptr); + str_vector_to_char_array(metalink_exclude_domain, c_metalink_exclude_domain.data()); + h.set_opt(LRO_METALINK_EXCLUDE_DOMAIN, c_metalink_exclude_domain.data()); + } + + auto & metalink_exclude_location = + config.get_main_config().get_metalink_exclude_location_option().get_value(); + if (!metalink_exclude_location.empty()) { + std::vector c_metalink_exclude_location(metalink_exclude_location.size() + 1, nullptr); + str_vector_to_char_array(metalink_exclude_location, c_metalink_exclude_location.data()); + h.set_opt(LRO_METALINK_EXCLUDE_LOCATION, c_metalink_exclude_location.data()); + } + } if (mirror_setup) { if (source == Source::METALINK) { h.set_opt(LRO_METALINKURL, tmp.c_str()); @@ -763,12 +779,6 @@ void RepoDownloader::add_countme_flag(DownloadData & download_data, LibrepoHandl if (!config.get_countme_option().get_value() || getuid() != 0) return; - // Bail out if not a remote handle - long local; - handle.get_info(LRI_LOCAL, &local); - if (local) - return; - // Bail out if no metalink or mirrorlist is defined auto & metalink = config.get_metalink_option(); auto & mirrorlist = config.get_mirrorlist_option(); diff --git a/test/libdnf5/conf/test_config_parser.cpp b/test/libdnf5/conf/test_config_parser.cpp index e1faf1ef2..db42a8151 100644 --- a/test/libdnf5/conf/test_config_parser.cpp +++ b/test/libdnf5/conf/test_config_parser.cpp @@ -22,7 +22,10 @@ #include "libdnf5/utils/fs/file.hpp" #include "libdnf5/utils/fs/temp.hpp" +#include +#include #include +#include #include #include @@ -381,3 +384,35 @@ void ConfigParserTest::test_read_modify_write() { CPPUNIT_ASSERT_EQUAL(modified_crazy_ini_content.size(), output_content.size()); CPPUNIT_ASSERT_EQUAL(modified_crazy_ini_content, std::string_view{output_content}); } + +void ConfigParserTest::test_metalink_exclude_options() { + constexpr std::string_view ini_content = + "[main]\n" + "metalink_exclude_domain=^mirror1\\\\.example\\\\.com$\n" + "metalink_exclude_location=^XX$\n"; + + libdnf5::utils::fs::TempDir temp_dir("libdnf_test_config_parser"); + std::filesystem::path ini_path = temp_dir.get_path() / "input.ini"; + libdnf5::utils::fs::File(ini_path, "w").write(ini_content); + + libdnf5::ConfigParser parser; + parser.read(ini_path); + + libdnf5::Base base; + libdnf5::ConfigMain & config = base.get_config(); + libdnf5::Vars vars(base); + libdnf5::MemoryBufferLogger logger(100); + config.load_from_parser(parser, "main", vars, logger); + + auto & domain_option = config.get_metalink_exclude_domain_option(); + auto & location_option = config.get_metalink_exclude_location_option(); + + auto & domain_values = domain_option.get_value(); + auto & location_values = location_option.get_value(); + + CPPUNIT_ASSERT_EQUAL(size_t(1), domain_values.size()); + CPPUNIT_ASSERT_EQUAL(std::string("^mirror1\\.example\\.com$"), domain_values[0]); + + CPPUNIT_ASSERT_EQUAL(size_t(1), location_values.size()); + CPPUNIT_ASSERT_EQUAL(std::string("^XX$"), location_values[0]); +} diff --git a/test/libdnf5/conf/test_config_parser.hpp b/test/libdnf5/conf/test_config_parser.hpp index 48d23233f..7cef5bee3 100644 --- a/test/libdnf5/conf/test_config_parser.hpp +++ b/test/libdnf5/conf/test_config_parser.hpp @@ -38,6 +38,7 @@ class ConfigParserTest : public CppUnit::TestCase { CPPUNIT_TEST(test_read_write_with_comments_header); CPPUNIT_TEST(test_read_write_crazy); CPPUNIT_TEST(test_read_modify_write); + CPPUNIT_TEST(test_metalink_exclude_options); #endif CPPUNIT_TEST_SUITE_END(); @@ -56,6 +57,7 @@ class ConfigParserTest : public CppUnit::TestCase { void test_read_write_with_comments_header(); void test_read_write_crazy(); void test_read_modify_write(); + void test_metalink_exclude_options(); }; #endif