import libdnf-0.48.0-5.el8
This commit is contained in:
parent
14e924f91d
commit
0211e1573c
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1 @@
|
||||
SOURCES/libdnf-0.39.1.tar.gz
|
||||
SOURCES/libdnf-0.48.0.tar.gz
|
||||
|
@ -1 +1 @@
|
||||
a74a37b029439749298705ff3c1ccfbd0f0fd821 SOURCES/libdnf-0.39.1.tar.gz
|
||||
452c2195741b627bd97b0be11cd4a4dc4118e330 SOURCES/libdnf-0.48.0.tar.gz
|
||||
|
@ -0,0 +1,244 @@
|
||||
From a96d701f7f55ff475e11ac9cda63b81c31c54e7a Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Mach <dmach@redhat.com>
|
||||
Date: Wed, 6 May 2020 08:34:46 +0200
|
||||
Subject: [PATCH] history: Fix dnf history rollback when a package was removed
|
||||
(RhBug:1683134)
|
||||
|
||||
---
|
||||
libdnf/transaction/MergedTransaction.cpp | 25 +++-
|
||||
.../transaction/MergedTransactionTest.cpp | 120 ++++++++++++++++--
|
||||
.../transaction/MergedTransactionTest.hpp | 6 +-
|
||||
3 files changed, 137 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/libdnf/transaction/MergedTransaction.cpp b/libdnf/transaction/MergedTransaction.cpp
|
||||
index a7c06ffa9..a8d878cb5 100644
|
||||
--- a/libdnf/transaction/MergedTransaction.cpp
|
||||
+++ b/libdnf/transaction/MergedTransaction.cpp
|
||||
@@ -19,6 +19,7 @@
|
||||
*/
|
||||
|
||||
#include "MergedTransaction.hpp"
|
||||
+#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
namespace libdnf {
|
||||
@@ -171,6 +172,21 @@ MergedTransaction::getConsoleOutput()
|
||||
return output;
|
||||
}
|
||||
|
||||
+
|
||||
+static bool transaction_item_sort_function(const std::shared_ptr<TransactionItemBase> lhs, const std::shared_ptr<TransactionItemBase> rhs) {
|
||||
+ if (lhs->isForwardAction() && rhs->isForwardAction()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (lhs->isBackwardAction() && rhs->isBackwardAction()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (lhs->isBackwardAction()) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/**
|
||||
* Get list of transaction items involved in the merged transaction
|
||||
* Actions are merged using following rules:
|
||||
@@ -203,6 +219,9 @@ MergedTransaction::getItems()
|
||||
// iterate over transaction
|
||||
for (auto t : transactions) {
|
||||
auto transItems = t->getItems();
|
||||
+ // sort transaction items by their action type - forward/backward
|
||||
+ // this fixes behavior of the merging algorithm in several edge cases
|
||||
+ std::sort(transItems.begin(), transItems.end(), transaction_item_sort_function);
|
||||
// iterate over transaction items
|
||||
for (auto transItem : transItems) {
|
||||
// get item and its type
|
||||
@@ -383,10 +402,6 @@ MergedTransaction::mergeItem(ItemPairMap &itemPairMap, TransactionItemBasePtr mT
|
||||
auto firstState = previousItemPair.first->getAction();
|
||||
auto newState = mTransItem->getAction();
|
||||
|
||||
- if (firstState == TransactionItemAction::INSTALL && mTransItem->isBackwardAction()) {
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
switch (firstState) {
|
||||
case TransactionItemAction::REMOVE:
|
||||
case TransactionItemAction::OBSOLETED:
|
||||
@@ -399,6 +414,8 @@ MergedTransaction::mergeItem(ItemPairMap &itemPairMap, TransactionItemBasePtr mT
|
||||
// Install -> Remove = (nothing)
|
||||
itemPairMap.erase(name);
|
||||
break;
|
||||
+ } else if (mTransItem->isBackwardAction()) {
|
||||
+ break;
|
||||
}
|
||||
// altered -> transfer install to the altered package
|
||||
mTransItem->setAction(TransactionItemAction::INSTALL);
|
||||
diff --git a/tests/libdnf/transaction/MergedTransactionTest.cpp b/tests/libdnf/transaction/MergedTransactionTest.cpp
|
||||
index 90ad182cf..52507700b 100644
|
||||
--- a/tests/libdnf/transaction/MergedTransactionTest.cpp
|
||||
+++ b/tests/libdnf/transaction/MergedTransactionTest.cpp
|
||||
@@ -700,7 +700,7 @@ MergedTransactionTest::test_downgrade()
|
||||
}
|
||||
|
||||
void
|
||||
-MergedTransactionTest::test_install_downgrade()
|
||||
+MergedTransactionTest::test_install_downgrade_upgrade_remove()
|
||||
{
|
||||
auto trans1 = std::make_shared< libdnf::swdb_private::Transaction >(conn);
|
||||
trans1->addItem(
|
||||
@@ -724,19 +724,123 @@ MergedTransactionTest::test_install_downgrade()
|
||||
TransactionItemReason::USER
|
||||
);
|
||||
|
||||
+ auto trans3 = std::make_shared< libdnf::swdb_private::Transaction >(conn);
|
||||
+ trans3->addItem(
|
||||
+ nevraToRPMItem(conn, "tour-0:4.6-1.noarch"),
|
||||
+ "repo2",
|
||||
+ TransactionItemAction::UPGRADED,
|
||||
+ TransactionItemReason::USER
|
||||
+ );
|
||||
+ trans3->addItem(
|
||||
+ nevraToRPMItem(conn, "tour-0:4.8-1.noarch"),
|
||||
+ "repo1",
|
||||
+ TransactionItemAction::UPGRADE,
|
||||
+ TransactionItemReason::USER
|
||||
+ );
|
||||
+
|
||||
+ auto trans4 = std::make_shared< libdnf::swdb_private::Transaction >(conn);
|
||||
+ trans4->addItem(
|
||||
+ nevraToRPMItem(conn, "tour-0:4.8-1.noarch"),
|
||||
+ "repo1",
|
||||
+ TransactionItemAction::REMOVE,
|
||||
+ TransactionItemReason::USER
|
||||
+ );
|
||||
+
|
||||
MergedTransaction merged(trans1);
|
||||
+
|
||||
+ // test merging trans1, trans2
|
||||
merged.merge(trans2);
|
||||
+ auto items2 = merged.getItems();
|
||||
+ CPPUNIT_ASSERT_EQUAL(1, (int)items2.size());
|
||||
+ auto item2 = items2.at(0);
|
||||
+ CPPUNIT_ASSERT_EQUAL(std::string("tour-4.6-1.noarch"), item2->getItem()->toStr());
|
||||
+ CPPUNIT_ASSERT_EQUAL(std::string("repo2"), item2->getRepoid());
|
||||
+ CPPUNIT_ASSERT_EQUAL(TransactionItemAction::INSTALL, item2->getAction());
|
||||
+ CPPUNIT_ASSERT_EQUAL(TransactionItemReason::USER, item2->getReason());
|
||||
|
||||
- auto items = merged.getItems();
|
||||
- CPPUNIT_ASSERT_EQUAL(1, (int)items.size());
|
||||
+ // test merging trans1, trans2, trans3
|
||||
+ merged.merge(trans3);
|
||||
+ auto items3 = merged.getItems();
|
||||
+ CPPUNIT_ASSERT_EQUAL(1, (int)items3.size());
|
||||
+ auto item3 = items3.at(0);
|
||||
+ CPPUNIT_ASSERT_EQUAL(std::string("tour-4.8-1.noarch"), item3->getItem()->toStr());
|
||||
+ CPPUNIT_ASSERT_EQUAL(std::string("repo1"), item3->getRepoid());
|
||||
+ CPPUNIT_ASSERT_EQUAL(TransactionItemAction::INSTALL, item3->getAction());
|
||||
+ CPPUNIT_ASSERT_EQUAL(TransactionItemReason::USER, item3->getReason());
|
||||
|
||||
- auto item = items.at(0);
|
||||
- CPPUNIT_ASSERT_EQUAL(std::string("tour-4.6-1.noarch"), item->getItem()->toStr());
|
||||
- CPPUNIT_ASSERT_EQUAL(std::string("repo2"), item->getRepoid());
|
||||
- CPPUNIT_ASSERT_EQUAL(TransactionItemAction::INSTALL, item->getAction());
|
||||
- CPPUNIT_ASSERT_EQUAL(TransactionItemReason::USER, item->getReason());
|
||||
+ // test merging trans1, trans2, trans3, trans4
|
||||
+ merged.merge(trans4);
|
||||
+ auto items4 = merged.getItems();
|
||||
+ CPPUNIT_ASSERT_EQUAL(0, (int)items4.size());
|
||||
+ // trans4 removes the package, empty output is expected
|
||||
}
|
||||
|
||||
+
|
||||
+void
|
||||
+MergedTransactionTest::test_downgrade_upgrade_remove()
|
||||
+{
|
||||
+ auto trans1 = std::make_shared< libdnf::swdb_private::Transaction >(conn);
|
||||
+ trans1->addItem(
|
||||
+ nevraToRPMItem(conn, "tour-0:4.6-1.noarch"),
|
||||
+ "repo2",
|
||||
+ TransactionItemAction::DOWNGRADE,
|
||||
+ TransactionItemReason::USER
|
||||
+ );
|
||||
+ trans1->addItem(
|
||||
+ nevraToRPMItem(conn, "tour-0:4.8-1.noarch"),
|
||||
+ "repo1",
|
||||
+ TransactionItemAction::DOWNGRADED,
|
||||
+ TransactionItemReason::USER
|
||||
+ );
|
||||
+
|
||||
+ // items are in reversed order than in test_install_downgrade_upgrade_remove()
|
||||
+ // fixing this required ordering transaction items by forward/backward action
|
||||
+ auto trans2 = std::make_shared< libdnf::swdb_private::Transaction >(conn);
|
||||
+ trans2->addItem(
|
||||
+ nevraToRPMItem(conn, "tour-0:4.8-1.noarch"),
|
||||
+ "repo1",
|
||||
+ TransactionItemAction::UPGRADE,
|
||||
+ TransactionItemReason::USER
|
||||
+ );
|
||||
+ trans2->addItem(
|
||||
+ nevraToRPMItem(conn, "tour-0:4.6-1.noarch"),
|
||||
+ "repo2",
|
||||
+ TransactionItemAction::UPGRADED,
|
||||
+ TransactionItemReason::USER
|
||||
+ );
|
||||
+
|
||||
+ auto trans3 = std::make_shared< libdnf::swdb_private::Transaction >(conn);
|
||||
+ trans3->addItem(
|
||||
+ nevraToRPMItem(conn, "tour-0:4.8-1.noarch"),
|
||||
+ "repo1",
|
||||
+ TransactionItemAction::REMOVE,
|
||||
+ TransactionItemReason::USER
|
||||
+ );
|
||||
+
|
||||
+ MergedTransaction merged(trans1);
|
||||
+
|
||||
+ // test merging trans1, trans2
|
||||
+ merged.merge(trans2);
|
||||
+ auto items2 = merged.getItems();
|
||||
+ CPPUNIT_ASSERT_EQUAL(1, (int)items2.size());
|
||||
+ auto item2 = items2.at(0);
|
||||
+ CPPUNIT_ASSERT_EQUAL(std::string("tour-4.8-1.noarch"), item2->getItem()->toStr());
|
||||
+ CPPUNIT_ASSERT_EQUAL(std::string("repo1"), item2->getRepoid());
|
||||
+ CPPUNIT_ASSERT_EQUAL(TransactionItemAction::REINSTALL, item2->getAction());
|
||||
+ CPPUNIT_ASSERT_EQUAL(TransactionItemReason::USER, item2->getReason());
|
||||
+
|
||||
+ // test merging trans1, trans2, trans3
|
||||
+ merged.merge(trans3);
|
||||
+ auto items3 = merged.getItems();
|
||||
+ CPPUNIT_ASSERT_EQUAL(1, (int)items3.size());
|
||||
+ auto item3 = items3.at(0);
|
||||
+ CPPUNIT_ASSERT_EQUAL(std::string("tour-4.8-1.noarch"), item3->getItem()->toStr());
|
||||
+ CPPUNIT_ASSERT_EQUAL(std::string("repo1"), item3->getRepoid());
|
||||
+ CPPUNIT_ASSERT_EQUAL(TransactionItemAction::REMOVE, item3->getAction());
|
||||
+ CPPUNIT_ASSERT_EQUAL(TransactionItemReason::USER, item3->getReason());
|
||||
+}
|
||||
+
|
||||
+
|
||||
void
|
||||
MergedTransactionTest::test_multilib_identity()
|
||||
{
|
||||
diff --git a/tests/libdnf/transaction/MergedTransactionTest.hpp b/tests/libdnf/transaction/MergedTransactionTest.hpp
|
||||
index 9f1ed660a..77585e865 100644
|
||||
--- a/tests/libdnf/transaction/MergedTransactionTest.hpp
|
||||
+++ b/tests/libdnf/transaction/MergedTransactionTest.hpp
|
||||
@@ -26,7 +26,8 @@ class MergedTransactionTest : public CppUnit::TestCase {
|
||||
CPPUNIT_TEST(test_add_obsoleted_obsoleted);
|
||||
|
||||
CPPUNIT_TEST(test_downgrade);
|
||||
- CPPUNIT_TEST(test_install_downgrade);
|
||||
+ CPPUNIT_TEST(test_install_downgrade_upgrade_remove);
|
||||
+ CPPUNIT_TEST(test_downgrade_upgrade_remove);
|
||||
|
||||
CPPUNIT_TEST(test_multilib_identity);
|
||||
|
||||
@@ -56,7 +57,8 @@ class MergedTransactionTest : public CppUnit::TestCase {
|
||||
// END: tests ported from DNF unit tests
|
||||
|
||||
void test_downgrade();
|
||||
- void test_install_downgrade();
|
||||
+ void test_install_downgrade_upgrade_remove();
|
||||
+ void test_downgrade_upgrade_remove();
|
||||
|
||||
void test_multilib_identity();
|
||||
private:
|
@ -1,131 +0,0 @@
|
||||
From 1dffef87fc2f07763f64eeabc1ea891e68d23541 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Domonkos <mdomonko@redhat.com>
|
||||
Date: Tue, 26 Nov 2019 13:05:49 +0100
|
||||
Subject: [PATCH] [user-agent] Drop the whitelist
|
||||
|
||||
- Stop checking os-release(5) data against a hard-coded whitelist and
|
||||
just use them as they are, to avoid a maintenance burden in the
|
||||
future (see [1] for details)
|
||||
|
||||
- Clean up the getUserAgent() function a bit
|
||||
|
||||
Note that, by removing the whitelist, there's a risk of leaking a
|
||||
"unique" value from the os-release file now, but a rather small one.
|
||||
|
||||
[1] https://github.com/rpm-software-management/libdnf/pull/851
|
||||
---
|
||||
libdnf/utils/os-release.cpp | 58 ++++++++++++++++++++--------------------------------------
|
||||
libdnf/utils/os-release.hpp | 7 ++-----
|
||||
2 files changed, 22 insertions(+), 43 deletions(-)
|
||||
|
||||
diff --git a/libdnf/utils/os-release.cpp b/libdnf/utils/os-release.cpp
|
||||
index 57be110..1d8a95b 100644
|
||||
--- a/libdnf/utils/os-release.cpp
|
||||
+++ b/libdnf/utils/os-release.cpp
|
||||
@@ -36,17 +36,8 @@
|
||||
namespace libdnf {
|
||||
|
||||
// sorted by precedence (see os-release(5) for details)
|
||||
-static const std::array<const std::string, 2> paths = {"/etc/os-release", "/usr/lib/os-release"};
|
||||
-// whitelists used for sanity-checking the os-release data when constructing a
|
||||
-// User-Agent string (to avoid reporting rare systems or platforms that could
|
||||
-// be tracked)
|
||||
-static const std::map<std::string, std::vector<std::string>> distros = {
|
||||
- // taken from the {fedora,generic}-release.spec files
|
||||
- { "Fedora", { "cinnamon", "cloud", "container", "coreos", "generic", "iot",
|
||||
- "kde", "matecompiz", "server", "silverblue", "snappy", "soas",
|
||||
- "workstation", "xfce" } },
|
||||
-};
|
||||
-std::array<const std::string, 1> canons = { "Linux" };
|
||||
+static const std::array<const std::string, 2>
|
||||
+paths = {"/etc/os-release", "/usr/lib/os-release"};
|
||||
|
||||
std::map<std::string, std::string> getOsReleaseData()
|
||||
{
|
||||
@@ -118,47 +109,38 @@ std::string getUserAgent(const std::map<std::string, std::string> & osReleaseDat
|
||||
{
|
||||
std::ostringstream oss;
|
||||
auto logger(Log::getLogger());
|
||||
- std::string msg = "os-release: falling back to basic User-Agent";
|
||||
|
||||
- // start with the basic libdnf string
|
||||
oss << USER_AGENT;
|
||||
+ std::string fallback = oss.str();
|
||||
|
||||
- // mandatory OS data (bail out if missing or unknown)
|
||||
if (!osReleaseData.count("NAME") || !osReleaseData.count("VERSION_ID")) {
|
||||
- logger->debug(tfm::format("%s: missing NAME or VERSION_ID", msg));
|
||||
- return oss.str();
|
||||
+ logger->debug(tfm::format(
|
||||
+ "User-Agent: falling back to '%s': missing NAME or VERSION_ID",
|
||||
+ fallback
|
||||
+ ));
|
||||
+ return fallback;
|
||||
}
|
||||
std::string name = osReleaseData.at("NAME");
|
||||
std::string version = osReleaseData.at("VERSION_ID");
|
||||
- if (!distros.count(name)) {
|
||||
- logger->debug(tfm::format("%s: distro %s not whitelisted", msg, name));
|
||||
- return oss.str();
|
||||
- }
|
||||
+ std::string variant = "generic";
|
||||
+ if (osReleaseData.count("VARIANT_ID"))
|
||||
+ variant = osReleaseData.at("VARIANT_ID");
|
||||
|
||||
- // mandatory platform data from RPM (bail out if missing or unknown)
|
||||
std::string canon = getCanonOs();
|
||||
std::string arch = getBaseArch();
|
||||
- if (canon.empty() || arch.empty()
|
||||
- || std::find(canons.begin(), canons.end(), canon) == canons.end()) {
|
||||
- logger->debug(tfm::format("%s: could not detect canonical OS or basearch", msg));
|
||||
- return oss.str();
|
||||
- }
|
||||
-
|
||||
- // optional OS data (use fallback values if missing or unknown)
|
||||
- std::string variant = "generic";
|
||||
- auto list = distros.at(name);
|
||||
- if (osReleaseData.count("VARIANT_ID")) {
|
||||
- std::string value = osReleaseData.at("VARIANT_ID");
|
||||
- if (std::find(list.begin(), list.end(), value) != list.end())
|
||||
- variant = value;
|
||||
+ if (canon.empty() || arch.empty()) {
|
||||
+ logger->debug(tfm::format(
|
||||
+ "User-Agent: falling back to '%s': could not detect OS or basearch",
|
||||
+ fallback
|
||||
+ ));
|
||||
+ return fallback;
|
||||
}
|
||||
|
||||
- // good to go!
|
||||
- oss << " (" << name << " " << version << "; " << variant << "; "
|
||||
- << canon << "." << arch << ")";
|
||||
+ oss << " (" << name << " " << version << "; " << variant << "; " << canon
|
||||
+ << "." << arch << ")";
|
||||
|
||||
std::string result = oss.str();
|
||||
- logger->debug(tfm::format("os-release: User-Agent constructed: %s", result));
|
||||
+ logger->debug(tfm::format("User-Agent: constructed: '%s'", result));
|
||||
return result;
|
||||
}
|
||||
|
||||
diff --git a/libdnf/utils/os-release.hpp b/libdnf/utils/os-release.hpp
|
||||
index ef4d14f..e7b24a7 100644
|
||||
--- a/libdnf/utils/os-release.hpp
|
||||
+++ b/libdnf/utils/os-release.hpp
|
||||
@@ -50,11 +50,8 @@ getOsReleaseData();
|
||||
* libdnf (NAME VERSION_ID; VARIANT_ID; OS.BASEARCH)
|
||||
*
|
||||
* where NAME, VERSION_ID and VARIANT_ID are OS identifiers read from the
|
||||
- * passed os-release data, and OS and BASEARCH (if found) are the canonical OS
|
||||
- * name and base architecture, respectively, detected using RPM.
|
||||
- *
|
||||
- * Note that the OS part (enclosed in parentheses) will only be included for
|
||||
- * whitelisted values.
|
||||
+ * passed os-release data, and OS and BASEARCH are the canonical OS name and
|
||||
+ * base architecture, respectively, detected using RPM.
|
||||
*
|
||||
* @param osReleaseData a map containing os-release data (will be loaded from
|
||||
* disk if not specified)
|
||||
--
|
||||
libgit2 0.28.2
|
||||
|
@ -0,0 +1,51 @@
|
||||
From 69e7baa4f6484c39ce25869d0c6252393b7c0411 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= <amatej@redhat.com>
|
||||
Date: Thu, 4 Jun 2020 11:13:48 +0200
|
||||
Subject: [PATCH] Add log file level main config option (RhBug:1802074)
|
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1802074
|
||||
---
|
||||
libdnf/conf/ConfigMain.cpp | 3 +++
|
||||
libdnf/conf/ConfigMain.hpp | 1 +
|
||||
4 files changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libdnf/conf/ConfigMain.cpp b/libdnf/conf/ConfigMain.cpp
|
||||
index 305b8e233..06352b7f3 100644
|
||||
--- a/libdnf/conf/ConfigMain.cpp
|
||||
+++ b/libdnf/conf/ConfigMain.cpp
|
||||
@@ -169,6 +169,7 @@ class ConfigMain::Impl {
|
||||
|
||||
OptionNumber<std::int32_t> debuglevel{2, 0, 10};
|
||||
OptionNumber<std::int32_t> errorlevel{3, 0, 10};
|
||||
+ OptionNumber<std::int32_t> logfilelevel{9, 0, 10};
|
||||
OptionPath installroot{"/", false, true};
|
||||
OptionPath config_file_path{CONF_FILENAME};
|
||||
OptionBool plugins{true};
|
||||
@@ -350,6 +351,7 @@ ConfigMain::Impl::Impl(Config & owner)
|
||||
{
|
||||
owner.optBinds().add("debuglevel", debuglevel);
|
||||
owner.optBinds().add("errorlevel", errorlevel);
|
||||
+ owner.optBinds().add("logfilelevel", logfilelevel);
|
||||
owner.optBinds().add("installroot", installroot);
|
||||
owner.optBinds().add("config_file_path", config_file_path);
|
||||
owner.optBinds().add("plugins", plugins);
|
||||
@@ -491,6 +493,7 @@ ConfigMain::~ConfigMain() = default;
|
||||
|
||||
OptionNumber<std::int32_t> & ConfigMain::debuglevel() { return pImpl->debuglevel; }
|
||||
OptionNumber<std::int32_t> & ConfigMain::errorlevel() { return pImpl->errorlevel; }
|
||||
+OptionNumber<std::int32_t> & ConfigMain::logfilelevel() { return pImpl->logfilelevel; }
|
||||
OptionString & ConfigMain::installroot() { return pImpl->installroot; }
|
||||
OptionString & ConfigMain::config_file_path() { return pImpl->config_file_path; }
|
||||
OptionBool & ConfigMain::plugins() { return pImpl->plugins; }
|
||||
diff --git a/libdnf/conf/ConfigMain.hpp b/libdnf/conf/ConfigMain.hpp
|
||||
index 118ecbf1c..706471029 100644
|
||||
--- a/libdnf/conf/ConfigMain.hpp
|
||||
+++ b/libdnf/conf/ConfigMain.hpp
|
||||
@@ -49,6 +49,7 @@ class ConfigMain : public Config {
|
||||
|
||||
OptionNumber<std::int32_t> & debuglevel();
|
||||
OptionNumber<std::int32_t> & errorlevel();
|
||||
+ OptionNumber<std::int32_t> & logfilelevel();
|
||||
OptionString & installroot();
|
||||
OptionString & config_file_path();
|
||||
OptionBool & plugins();
|
@ -1,88 +0,0 @@
|
||||
From c398ea4431ea539b0847fdf7fddf1892655081de Mon Sep 17 00:00:00 2001
|
||||
From: Jaroslav Rohel <jrohel@redhat.com>
|
||||
Date: Sun, 15 Dec 2019 16:43:01 +0100
|
||||
Subject: [PATCH] [context] wildcard support in dnf_context_repo_set_data
|
||||
(RhBug:1781420)
|
||||
|
||||
Adds support for wildcard pattern in repo_id to these functions:
|
||||
gboolean dnf_context_repo_enable(DnfContext *context,
|
||||
const gchar *repo_id, GError **error);
|
||||
gboolean dnf_context_repo_disable(DnfContext *context,
|
||||
const gchar *repo_id, GError **error);
|
||||
|
||||
For example, it is used by microdnf for enable and disable repositories
|
||||
(arguments "--enablerepo=" and "--disablerepo=").
|
||||
---
|
||||
libdnf/dnf-context.cpp | 26 +++++++++++++-------------
|
||||
1 file changed, 13 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/libdnf/dnf-context.cpp b/libdnf/dnf-context.cpp
|
||||
index 061bf6f85..4b0a009fc 100644
|
||||
--- a/libdnf/dnf-context.cpp
|
||||
+++ b/libdnf/dnf-context.cpp
|
||||
@@ -52,6 +52,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
+#include <fnmatch.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "log.hpp"
|
||||
@@ -2273,20 +2274,19 @@ dnf_context_repo_set_data(DnfContext *context,
|
||||
GError **error)
|
||||
{
|
||||
DnfContextPrivate *priv = GET_PRIVATE(context);
|
||||
- DnfRepo *repo = NULL;
|
||||
- guint i;
|
||||
+ bool found = false;
|
||||
|
||||
- /* find a repo with a matching ID */
|
||||
- for (i = 0; i < priv->repos->len; i++) {
|
||||
- auto repo_tmp = static_cast<DnfRepo *>(g_ptr_array_index(priv->repos, i));
|
||||
- if (g_strcmp0(dnf_repo_get_id(repo_tmp), repo_id) == 0) {
|
||||
- repo = repo_tmp;
|
||||
- break;
|
||||
+ /* set repos with a matching ID */
|
||||
+ for (guint i = 0; i < priv->repos->len; ++i) {
|
||||
+ auto repo = static_cast<DnfRepo *>(g_ptr_array_index(priv->repos, i));
|
||||
+ if (fnmatch(repo_id, dnf_repo_get_id(repo), 0) == 0) {
|
||||
+ dnf_repo_set_enabled(repo, enabled);
|
||||
+ found = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* nothing found */
|
||||
- if (repo == NULL) {
|
||||
+ if (!found) {
|
||||
g_set_error(error,
|
||||
DNF_ERROR,
|
||||
DNF_ERROR_INTERNAL_ERROR,
|
||||
@@ -2294,8 +2294,6 @@ dnf_context_repo_set_data(DnfContext *context,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
- /* this is runtime only */
|
||||
- dnf_repo_set_enabled(repo, enabled);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -2305,7 +2303,8 @@ dnf_context_repo_set_data(DnfContext *context,
|
||||
* @repo_id: A repo_id, e.g. "fedora-rawhide"
|
||||
* @error: A #GError or %NULL
|
||||
*
|
||||
- * Enables a specific repo.
|
||||
+ * Enables a specific repo(s).
|
||||
+ * Wildcard pattern is supported.
|
||||
*
|
||||
* This must be done before dnf_context_setup() is called.
|
||||
*
|
||||
@@ -2329,7 +2328,8 @@ dnf_context_repo_enable(DnfContext *context,
|
||||
* @repo_id: A repo_id, e.g. "fedora-rawhide"
|
||||
* @error: A #GError or %NULL
|
||||
*
|
||||
- * Disables a specific repo.
|
||||
+ * Disables a specific repo(s).
|
||||
+ * Wildcard pattern is supported.
|
||||
*
|
||||
* This must be done before dnf_context_setup() is called.
|
||||
*
|
@ -0,0 +1,83 @@
|
||||
From 227cf617dd6afd7583f1c864c66ba2ca95e3d09d Mon Sep 17 00:00:00 2001
|
||||
From: Pavla Kratochvilova <pkratoch@redhat.com>
|
||||
Date: Wed, 24 Jun 2020 08:48:49 +0200
|
||||
Subject: [PATCH 1/2] Accept '==' as an operator in reldeps (RhBug:1847946)
|
||||
|
||||
Although rpm doesn't support this and using '==' can result in an
|
||||
unexpected behavior, libdnf accepted '==' by mistake for some time and
|
||||
other tools (namely Ansible Tower) already rely on it.
|
||||
|
||||
This brings back the '==' support with a deprecation warning.
|
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1847946
|
||||
---
|
||||
libdnf/repo/DependencySplitter.cpp | 14 +++++++++++++-
|
||||
1 file changed, 13 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libdnf/repo/DependencySplitter.cpp b/libdnf/repo/DependencySplitter.cpp
|
||||
index 0030ea6d3..402962286 100644
|
||||
--- a/libdnf/repo/DependencySplitter.cpp
|
||||
+++ b/libdnf/repo/DependencySplitter.cpp
|
||||
@@ -20,16 +20,21 @@
|
||||
|
||||
#include "DependencySplitter.hpp"
|
||||
#include "../dnf-sack.h"
|
||||
+#include "../log.hpp"
|
||||
#include "../utils/regex/regex.hpp"
|
||||
|
||||
+#include "bgettext/bgettext-lib.h"
|
||||
+#include "tinyformat/tinyformat.hpp"
|
||||
+
|
||||
namespace libdnf {
|
||||
|
||||
static const Regex RELDEP_REGEX =
|
||||
- Regex("^(\\S*)\\s*(<=|>=|<|>|=)?\\s*(\\S*)$", REG_EXTENDED);
|
||||
+ Regex("^(\\S*)\\s*(<=|>=|<|>|=|==)?\\s*(\\S*)$", REG_EXTENDED);
|
||||
|
||||
static bool
|
||||
getCmpFlags(int *cmp_type, std::string matchCmpType)
|
||||
{
|
||||
+ auto logger(Log::getLogger());
|
||||
int subexpr_len = matchCmpType.size();
|
||||
auto match_start = matchCmpType.c_str();
|
||||
if (subexpr_len == 2) {
|
||||
@@ -41,6 +46,13 @@ getCmpFlags(int *cmp_type, std::string matchCmpType)
|
||||
*cmp_type |= HY_GT;
|
||||
*cmp_type |= HY_EQ;
|
||||
}
|
||||
+ else if (strncmp(match_start, "==", 2) == 0) {
|
||||
+ auto msg = tfm::format(_("Using '==' operator in reldeps can result in an undefined "
|
||||
+ "behavior. It is deprecated and the support will be dropped "
|
||||
+ "in future versions. Use '=' operator instead."));
|
||||
+ logger->warning(msg);
|
||||
+ *cmp_type |= HY_EQ;
|
||||
+ }
|
||||
else
|
||||
return false;
|
||||
} else if (subexpr_len == 1) {
|
||||
|
||||
From 1f9b14f1d30113a602e18f60ef7ba1f11aead10f Mon Sep 17 00:00:00 2001
|
||||
From: Pavla Kratochvilova <pkratoch@redhat.com>
|
||||
Date: Wed, 24 Jun 2020 13:08:48 +0200
|
||||
Subject: [PATCH 2/2] Add tests for '==' operator in reldeps
|
||||
|
||||
---
|
||||
python/hawkey/tests/tests/test_reldep.py | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/python/hawkey/tests/tests/test_reldep.py b/python/hawkey/tests/tests/test_reldep.py
|
||||
index 8b479cfd7..a9f6cae6f 100644
|
||||
--- a/python/hawkey/tests/tests/test_reldep.py
|
||||
+++ b/python/hawkey/tests/tests/test_reldep.py
|
||||
@@ -61,6 +61,11 @@ def test_custom_querying(self):
|
||||
reldep = hawkey.Reldep(self.sack, "P-lib = 3-3")
|
||||
q = hawkey.Query(self.sack).filter(provides=reldep)
|
||||
self.assertLength(q, 1)
|
||||
+ # '==' operator is deprecated and the support will be dropped in future
|
||||
+ # versions (see bug 1847946)
|
||||
+ reldep = hawkey.Reldep(self.sack, "P-lib == 3-3")
|
||||
+ q = hawkey.Query(self.sack).filter(provides=reldep)
|
||||
+ self.assertLength(q, 1)
|
||||
reldep = hawkey.Reldep(self.sack, "P-lib >= 3")
|
||||
q = hawkey.Query(self.sack).filter(provides=reldep)
|
||||
self.assertLength(q, 1)
|
@ -1,339 +0,0 @@
|
||||
From b36464f01ffadab9ca49eed1a06ab480626b28c2 Mon Sep 17 00:00:00 2001
|
||||
From: Jaroslav Mracek <jmracek@redhat.com>
|
||||
Date: Mon, 16 Dec 2019 10:10:51 +0100
|
||||
Subject: [PATCH 1/2] Add new query filter upgrades_by_priority
|
||||
|
||||
It returns upgrades only from repository with the lowest priority.
|
||||
---
|
||||
libdnf/hy-types.h | 3 +-
|
||||
libdnf/sack/query.cpp | 60 ++++++++++++++++++++++++++++++++++
|
||||
python/hawkey/hawkeymodule.cpp | 1 +
|
||||
python/hawkey/query-py.cpp | 5 ++-
|
||||
4 files changed, 67 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libdnf/hy-types.h b/libdnf/hy-types.h
|
||||
index b34988d89..380a0d5cc 100644
|
||||
--- a/libdnf/hy-types.h
|
||||
+++ b/libdnf/hy-types.h
|
||||
@@ -97,7 +97,8 @@ enum _hy_key_name_e {
|
||||
* @brief Use for strings of whole NEVRA (missing epoch is handled as epoch 0)
|
||||
* Allowed compare types - only HY_EQ or HY_NEQ
|
||||
*/
|
||||
- HY_PKG_NEVRA_STRICT = 36
|
||||
+ HY_PKG_NEVRA_STRICT = 36,
|
||||
+ HY_PKG_UPGRADES_BY_PRIORITY = 37,
|
||||
};
|
||||
|
||||
enum _hy_comparison_type_e {
|
||||
diff --git a/libdnf/sack/query.cpp b/libdnf/sack/query.cpp
|
||||
index eea0ce1b1..ecfd3110f 100644
|
||||
--- a/libdnf/sack/query.cpp
|
||||
+++ b/libdnf/sack/query.cpp
|
||||
@@ -148,6 +148,13 @@ NameArchSolvableComparator(const Solvable * first, const Solvable * second)
|
||||
return first->arch < second->arch;
|
||||
}
|
||||
|
||||
+static bool
|
||||
+NamePrioritySolvableKey(const Solvable * first, const Solvable * second)
|
||||
+{
|
||||
+ if (first->name != second->name)
|
||||
+ return first->name < second->name;
|
||||
+ return first->repo->priority > second->repo->priority;
|
||||
+}
|
||||
|
||||
static bool
|
||||
match_type_num(int keyname) {
|
||||
@@ -158,6 +165,7 @@ match_type_num(int keyname) {
|
||||
case HY_PKG_LATEST_PER_ARCH:
|
||||
case HY_PKG_UPGRADABLE:
|
||||
case HY_PKG_UPGRADES:
|
||||
+ case HY_PKG_UPGRADES_BY_PRIORITY:
|
||||
case HY_PKG_DOWNGRADABLE:
|
||||
case HY_PKG_DOWNGRADES:
|
||||
return true;
|
||||
@@ -690,6 +698,7 @@ class Query::Impl {
|
||||
void filterAdvisory(const Filter & f, Map *m, int keyname);
|
||||
void filterLatest(const Filter & f, Map *m);
|
||||
void filterUpdown(const Filter & f, Map *m);
|
||||
+ void filterUpdownByPriority(const Filter & f, Map *m);
|
||||
void filterUpdownAble(const Filter &f, Map *m);
|
||||
void filterDataiterator(const Filter & f, Map *m);
|
||||
int filterUnneededOrSafeToRemove(const Swdb &swdb, bool debug_solver, bool safeToRemove);
|
||||
@@ -1732,6 +1741,54 @@ Query::Impl::filterUpdown(const Filter & f, Map *m)
|
||||
}
|
||||
}
|
||||
|
||||
+void
|
||||
+Query::Impl::filterUpdownByPriority(const Filter & f, Map *m)
|
||||
+{
|
||||
+ Pool *pool = dnf_sack_get_pool(sack);
|
||||
+ auto resultPset = result.get();
|
||||
+
|
||||
+ dnf_sack_make_provides_ready(sack);
|
||||
+ auto repoInstalled = pool->installed;
|
||||
+ if (!repoInstalled) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ for (auto match_in : f.getMatches()) {
|
||||
+ if (match_in.num == 0)
|
||||
+ continue;
|
||||
+ std::vector<Solvable *> upgradeCandidates;
|
||||
+ upgradeCandidates.reserve(resultPset->size());
|
||||
+ Id id = -1;
|
||||
+ while ((id = resultPset->next(id)) != -1) {
|
||||
+ Solvable *candidate = pool_id2solvable(pool, id);
|
||||
+ if (candidate->repo == repoInstalled)
|
||||
+ continue;
|
||||
+ upgradeCandidates.push_back(candidate);
|
||||
+ }
|
||||
+ if (upgradeCandidates.empty()) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ std::sort(upgradeCandidates.begin(), upgradeCandidates.end(), NamePrioritySolvableKey);
|
||||
+ Id name = 0;
|
||||
+ int priority = 0;
|
||||
+ for (auto * candidate: upgradeCandidates) {
|
||||
+ if (name != candidate->name) {
|
||||
+ name = candidate->name;
|
||||
+ priority = candidate->repo->priority;
|
||||
+ id = pool_solvable2id(pool, candidate);
|
||||
+ if (what_upgrades(pool, id) > 0) {
|
||||
+ MAPSET(m, id);
|
||||
+ }
|
||||
+ } else if (priority == candidate->repo->priority) {
|
||||
+ id = pool_solvable2id(pool, candidate);
|
||||
+ if (what_upgrades(pool, id) > 0) {
|
||||
+ MAPSET(m, id);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void
|
||||
Query::Impl::filterUpdownAble(const Filter &f, Map *m)
|
||||
{
|
||||
@@ -1949,6 +2006,9 @@ Query::Impl::apply()
|
||||
case HY_PKG_UPGRADES:
|
||||
filterUpdown(f, &m);
|
||||
break;
|
||||
+ case HY_PKG_UPGRADES_BY_PRIORITY:
|
||||
+ filterUpdownByPriority(f, &m);
|
||||
+ break;
|
||||
default:
|
||||
filterDataiterator(f, &m);
|
||||
}
|
||||
diff --git a/python/hawkey/hawkeymodule.cpp b/python/hawkey/hawkeymodule.cpp
|
||||
index 0f05f46c2..4351e96e1 100644
|
||||
--- a/python/hawkey/hawkeymodule.cpp
|
||||
+++ b/python/hawkey/hawkeymodule.cpp
|
||||
@@ -281,6 +281,7 @@ PYCOMP_MOD_INIT(_hawkey)
|
||||
PyModule_AddIntConstant(m, "PKG_SUPPLEMENTS", HY_PKG_SUPPLEMENTS);
|
||||
PyModule_AddIntConstant(m, "PKG_UPGRADABLE", HY_PKG_UPGRADABLE);
|
||||
PyModule_AddIntConstant(m, "PKG_UPGRADES", HY_PKG_UPGRADES);
|
||||
+ PyModule_AddIntConstant(m, "PKG_UPGRADES_BY_PRIORITY", HY_PKG_UPGRADES_BY_PRIORITY);
|
||||
PyModule_AddIntConstant(m, "PKG_URL", HY_PKG_URL);
|
||||
PyModule_AddIntConstant(m, "PKG_VERSION", HY_PKG_VERSION);
|
||||
|
||||
diff --git a/python/hawkey/query-py.cpp b/python/hawkey/query-py.cpp
|
||||
index 116ffa1b0..286e306d3 100644
|
||||
--- a/python/hawkey/query-py.cpp
|
||||
+++ b/python/hawkey/query-py.cpp
|
||||
@@ -89,6 +89,7 @@ static const int keyname_int_matches[] = {
|
||||
HY_PKG_SUPPLEMENTS,
|
||||
HY_PKG_UPGRADABLE,
|
||||
HY_PKG_UPGRADES,
|
||||
+ HY_PKG_UPGRADES_BY_PRIORITY,
|
||||
HY_PKG_URL,
|
||||
HY_PKG_VERSION
|
||||
};
|
||||
@@ -128,6 +129,7 @@ static const char * const keyname_char_matches[] = {
|
||||
"supplements",
|
||||
"upgradable",
|
||||
"upgrades",
|
||||
+ "upgrades_by_priority",
|
||||
"url",
|
||||
"version",
|
||||
NULL
|
||||
@@ -273,7 +275,8 @@ filter_add(HyQuery query, key_t keyname, int cmp_type, PyObject *match)
|
||||
keyname == HY_PKG_LATEST_PER_ARCH ||
|
||||
keyname == HY_PKG_LATEST ||
|
||||
keyname == HY_PKG_UPGRADABLE ||
|
||||
- keyname == HY_PKG_UPGRADES) {
|
||||
+ keyname == HY_PKG_UPGRADES ||
|
||||
+ keyname == HY_PKG_UPGRADES_BY_PRIORITY) {
|
||||
int val;
|
||||
|
||||
if (!PyInt_Check(match) || cmp_type != HY_EQ) {
|
||||
|
||||
From 4b83ae692f90d0d3cbc377c7f93bdb7e99e477ef Mon Sep 17 00:00:00 2001
|
||||
From: Jaroslav Mracek <jmracek@redhat.com>
|
||||
Date: Mon, 16 Dec 2019 18:34:37 +0100
|
||||
Subject: [PATCH 2/2] Add new query filter obsoletes_by_priority
|
||||
|
||||
---
|
||||
libdnf/hy-types.h | 1 +
|
||||
libdnf/sack/query.cpp | 65 ++++++++++++++++++++++++++++++++++
|
||||
python/hawkey/hawkeymodule.cpp | 1 +
|
||||
python/hawkey/query-py.cpp | 5 ++-
|
||||
4 files changed, 71 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libdnf/hy-types.h b/libdnf/hy-types.h
|
||||
index 380a0d5cc..e96459c25 100644
|
||||
--- a/libdnf/hy-types.h
|
||||
+++ b/libdnf/hy-types.h
|
||||
@@ -99,6 +99,7 @@ enum _hy_key_name_e {
|
||||
*/
|
||||
HY_PKG_NEVRA_STRICT = 36,
|
||||
HY_PKG_UPGRADES_BY_PRIORITY = 37,
|
||||
+ HY_PKG_OBSOLETES_BY_PRIORITY = 38,
|
||||
};
|
||||
|
||||
enum _hy_comparison_type_e {
|
||||
diff --git a/libdnf/sack/query.cpp b/libdnf/sack/query.cpp
|
||||
index ecfd3110f..6e9e4715f 100644
|
||||
--- a/libdnf/sack/query.cpp
|
||||
+++ b/libdnf/sack/query.cpp
|
||||
@@ -179,6 +179,7 @@ match_type_pkg(int keyname) {
|
||||
switch (keyname) {
|
||||
case HY_PKG:
|
||||
case HY_PKG_OBSOLETES:
|
||||
+ case HY_PKG_OBSOLETES_BY_PRIORITY:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@@ -692,6 +693,7 @@ class Query::Impl {
|
||||
void filterArch(const Filter & f, Map *m);
|
||||
void filterSourcerpm(const Filter & f, Map *m);
|
||||
void filterObsoletes(const Filter & f, Map *m);
|
||||
+ void filterObsoletesByPriority(const Filter & f, Map *m);
|
||||
void filterProvidesReldep(const Filter & f, Map *m);
|
||||
void filterReponame(const Filter & f, Map *m);
|
||||
void filterLocation(const Filter & f, Map *m);
|
||||
@@ -702,6 +704,7 @@ class Query::Impl {
|
||||
void filterUpdownAble(const Filter &f, Map *m);
|
||||
void filterDataiterator(const Filter & f, Map *m);
|
||||
int filterUnneededOrSafeToRemove(const Swdb &swdb, bool debug_solver, bool safeToRemove);
|
||||
+ void obsoletesByPriority(Pool * pool, Solvable * candidate, Map * m, const Map * target, int obsprovides);
|
||||
|
||||
bool isGlob(const std::vector<const char *> &matches) const;
|
||||
};
|
||||
@@ -1469,6 +1472,65 @@ Query::Impl::filterObsoletes(const Filter & f, Map *m)
|
||||
}
|
||||
}
|
||||
|
||||
+void
|
||||
+Query::Impl::obsoletesByPriority(Pool * pool, Solvable * candidate, Map * m, const Map * target, int obsprovides)
|
||||
+{
|
||||
+ if (!candidate->repo)
|
||||
+ return;
|
||||
+ for (Id *r_id = candidate->repo->idarraydata + candidate->obsoletes; *r_id; ++r_id) {
|
||||
+ Id r, rr;
|
||||
+ FOR_PROVIDES(r, rr, *r_id) {
|
||||
+ if (!MAPTST(target, r))
|
||||
+ continue;
|
||||
+ assert(r != SYSTEMSOLVABLE);
|
||||
+ Solvable *so = pool_id2solvable(pool, r);
|
||||
+ if (!obsprovides && !pool_match_nevr(pool, so, *r_id))
|
||||
+ continue; /* only matching pkg names */
|
||||
+ MAPSET(m, pool_solvable2id(pool, candidate));
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+Query::Impl::filterObsoletesByPriority(const Filter & f, Map *m)
|
||||
+{
|
||||
+ Pool *pool = dnf_sack_get_pool(sack);
|
||||
+ int obsprovides = pool_get_flag(pool, POOL_FLAG_OBSOLETEUSESPROVIDES);
|
||||
+ Map *target;
|
||||
+ auto resultPset = result.get();
|
||||
+
|
||||
+ assert(f.getMatchType() == _HY_PKG);
|
||||
+ assert(f.getMatches().size() == 1);
|
||||
+ target = dnf_packageset_get_map(f.getMatches()[0].pset);
|
||||
+ dnf_sack_make_provides_ready(sack);
|
||||
+ std::vector<Solvable *> obsoleteCandidates;
|
||||
+ obsoleteCandidates.reserve(resultPset->size());
|
||||
+ Id id = -1;
|
||||
+ while ((id = resultPset->next(id)) != -1) {
|
||||
+ Solvable *candidate = pool_id2solvable(pool, id);
|
||||
+ obsoleteCandidates.push_back(candidate);
|
||||
+ }
|
||||
+ if (obsoleteCandidates.empty()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ std::sort(obsoleteCandidates.begin(), obsoleteCandidates.end(), NamePrioritySolvableKey);
|
||||
+ Id name = 0;
|
||||
+ int priority = 0;
|
||||
+ for (auto * candidate: obsoleteCandidates) {
|
||||
+ if (candidate->repo == pool->installed) {
|
||||
+ obsoletesByPriority(pool, candidate, m, target, obsprovides);
|
||||
+ }
|
||||
+ if (name != candidate->name) {
|
||||
+ name = candidate->name;
|
||||
+ priority = candidate->repo->priority;
|
||||
+ obsoletesByPriority(pool, candidate, m, target, obsprovides);
|
||||
+ } else if (priority == candidate->repo->priority) {
|
||||
+ obsoletesByPriority(pool, candidate, m, target, obsprovides);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void
|
||||
Query::Impl::filterProvidesReldep(const Filter & f, Map *m)
|
||||
{
|
||||
@@ -1969,6 +2031,9 @@ Query::Impl::apply()
|
||||
filterObsoletes(f, &m);
|
||||
}
|
||||
break;
|
||||
+ case HY_PKG_OBSOLETES_BY_PRIORITY:
|
||||
+ filterObsoletesByPriority(f, &m);
|
||||
+ break;
|
||||
case HY_PKG_PROVIDES:
|
||||
assert(f.getMatchType() == _HY_RELDEP);
|
||||
filterProvidesReldep(f, &m);
|
||||
diff --git a/python/hawkey/hawkeymodule.cpp b/python/hawkey/hawkeymodule.cpp
|
||||
index 4351e96e1..82d05e2cb 100644
|
||||
--- a/python/hawkey/hawkeymodule.cpp
|
||||
+++ b/python/hawkey/hawkeymodule.cpp
|
||||
@@ -270,6 +270,7 @@ PYCOMP_MOD_INIT(_hawkey)
|
||||
PyModule_AddIntConstant(m, "PKG_NEVRA", HY_PKG_NEVRA);
|
||||
PyModule_AddIntConstant(m, "PKG_NEVRA_STRICT", HY_PKG_NEVRA_STRICT);
|
||||
PyModule_AddIntConstant(m, "PKG_OBSOLETES", HY_PKG_OBSOLETES);
|
||||
+ PyModule_AddIntConstant(m, "PKG_OBSOLETES_BY_PRIORITY", HY_PKG_OBSOLETES_BY_PRIORITY);
|
||||
PyModule_AddIntConstant(m, "PKG_PROVIDES", HY_PKG_PROVIDES);
|
||||
PyModule_AddIntConstant(m, "PKG_RECOMMENDS", HY_PKG_RECOMMENDS);
|
||||
PyModule_AddIntConstant(m, "PKG_RELEASE", HY_PKG_RELEASE);
|
||||
diff --git a/python/hawkey/query-py.cpp b/python/hawkey/query-py.cpp
|
||||
index 286e306d3..9178a6d0c 100644
|
||||
--- a/python/hawkey/query-py.cpp
|
||||
+++ b/python/hawkey/query-py.cpp
|
||||
@@ -78,6 +78,7 @@ static const int keyname_int_matches[] = {
|
||||
HY_PKG_NEVRA,
|
||||
HY_PKG_NEVRA_STRICT,
|
||||
HY_PKG_OBSOLETES,
|
||||
+ HY_PKG_OBSOLETES_BY_PRIORITY,
|
||||
HY_PKG_PROVIDES,
|
||||
HY_PKG_RECOMMENDS,
|
||||
HY_PKG_RELEASE,
|
||||
@@ -118,6 +119,7 @@ static const char * const keyname_char_matches[] = {
|
||||
"nevra",
|
||||
"nevra_strict",
|
||||
"obsoletes",
|
||||
+ "obsoletes_by_priority",
|
||||
"provides",
|
||||
"recommends",
|
||||
"release",
|
||||
@@ -342,7 +344,8 @@ filter_add(HyQuery query, key_t keyname, int cmp_type, PyObject *match)
|
||||
// match is a sequence now:
|
||||
switch (keyname) {
|
||||
case HY_PKG:
|
||||
- case HY_PKG_OBSOLETES: {
|
||||
+ case HY_PKG_OBSOLETES:
|
||||
+ case HY_PKG_OBSOLETES_BY_PRIORITY: {
|
||||
// It could be a sequence of packages or reldep/strings. Lets try packages first.
|
||||
auto pset = pyseq_to_packageset(match, query->getSack());
|
||||
if (!pset) {
|
@ -1,98 +0,0 @@
|
||||
From dc3b2a2b22106fa4c0033a5557584f3b08c942e2 Mon Sep 17 00:00:00 2001
|
||||
From: Marek Blaha <mblaha@redhat.com>
|
||||
Date: Fri, 3 Jan 2020 12:35:33 +0100
|
||||
Subject: [PATCH] Remove killGpgAgent function (RhBug:1781601)
|
||||
|
||||
Instead ensure that /run/user/$UID directory exists so gpgagent could
|
||||
create its socket in it.
|
||||
The solution with KILLAGENT caused race condition with gpgme_release()
|
||||
call and that resulted in dnf being possibly terminated by SIGPIPE after
|
||||
importing the first repository gpg key.
|
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1781601
|
||||
---
|
||||
libdnf/repo/Repo.cpp | 56 +++++++++++++++++++++++---------------------
|
||||
1 file changed, 29 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/libdnf/repo/Repo.cpp b/libdnf/repo/Repo.cpp
|
||||
index 850e5b4a8..c1891cce9 100644
|
||||
--- a/libdnf/repo/Repo.cpp
|
||||
+++ b/libdnf/repo/Repo.cpp
|
||||
@@ -846,27 +846,35 @@ std::vector<Key> Repo::Impl::retrieve(const std::string & url)
|
||||
return keyInfos;
|
||||
}
|
||||
|
||||
-static void killGpgAgent(gpgme_ctx_t context, const std::string & gpgDir)
|
||||
-{
|
||||
+/*
|
||||
+ * Creates the '/run/user/$UID' directory if it doesn't exist. If this
|
||||
+ * directory exists, gpgagent will create its sockets under
|
||||
+ * '/run/user/$UID/gnupg'.
|
||||
+ *
|
||||
+ * If this directory doesn't exist, gpgagent will create its sockets in gpg
|
||||
+ * home directory, which is under '/var/cache/yum/metadata/' and this was
|
||||
+ * causing trouble with container images, see [1].
|
||||
+ *
|
||||
+ * Previous solution was to send the agent a "KILLAGENT" message, but that
|
||||
+ * would cause a race condition with calling gpgme_release(), see [2], [3],
|
||||
+ * [4].
|
||||
+ *
|
||||
+ * Since the agent doesn't clean up its sockets properly, by creating this
|
||||
+ * directory we make sure they are in a place that is not causing trouble with
|
||||
+ * container images.
|
||||
+ *
|
||||
+ * [1] https://bugzilla.redhat.com/show_bug.cgi?id=1650266
|
||||
+ * [2] https://bugzilla.redhat.com/show_bug.cgi?id=1769831
|
||||
+ * [3] https://github.com/rpm-software-management/microdnf/issues/50
|
||||
+ * [4] https://bugzilla.redhat.com/show_bug.cgi?id=1781601
|
||||
+ */
|
||||
+static void ensure_socket_dir_exists() {
|
||||
auto logger(Log::getLogger());
|
||||
-
|
||||
- auto gpgErr = gpgme_set_protocol(context, GPGME_PROTOCOL_ASSUAN);
|
||||
- if (gpgErr != GPG_ERR_NO_ERROR) {
|
||||
- auto msg = tfm::format(_("%s: gpgme_set_protocol(): %s"), __func__, gpgme_strerror(gpgErr));
|
||||
- logger->warning(msg);
|
||||
- return;
|
||||
- }
|
||||
- std::string gpgAgentSock = gpgDir + "/S.gpg-agent";
|
||||
- gpgErr = gpgme_ctx_set_engine_info(context, GPGME_PROTOCOL_ASSUAN, gpgAgentSock.c_str(), gpgDir.c_str());
|
||||
- if (gpgErr != GPG_ERR_NO_ERROR) {
|
||||
- auto msg = tfm::format(_("%s: gpgme_ctx_set_engine_info(): %s"), __func__, gpgme_strerror(gpgErr));
|
||||
- logger->warning(msg);
|
||||
- return;
|
||||
- }
|
||||
- gpgErr = gpgme_op_assuan_transact_ext(context, "KILLAGENT", NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
- if (gpgErr != GPG_ERR_NO_ERROR) {
|
||||
- auto msg = tfm::format(_("%s: gpgme_op_assuan_transact_ext(): %s"), __func__, gpgme_strerror(gpgErr));
|
||||
- logger->debug(msg);
|
||||
+ std::string dirname = "/run/user/" + std::to_string(getuid());
|
||||
+ int res = mkdir(dirname.c_str(), 0700);
|
||||
+ if (res != 0 && errno != EEXIST) {
|
||||
+ logger->debug(tfm::format("Failed to create directory \"%s\": %d - %s",
|
||||
+ dirname, errno, strerror(errno)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -876,6 +884,7 @@ void Repo::Impl::importRepoKeys()
|
||||
|
||||
auto gpgDir = getCachedir() + "/pubring";
|
||||
auto knownKeys = keyidsFromPubring(gpgDir);
|
||||
+ ensure_socket_dir_exists();
|
||||
for (const auto & gpgkeyUrl : conf->gpgkey().getValue()) {
|
||||
auto keyInfos = retrieve(gpgkeyUrl);
|
||||
for (auto & keyInfo : keyInfos) {
|
||||
@@ -908,13 +917,6 @@ void Repo::Impl::importRepoKeys()
|
||||
|
||||
gpgImportKey(ctx, keyInfo.rawKey);
|
||||
|
||||
- // Running gpg-agent kept opened sockets on the system.
|
||||
- // It tries to exit gpg-agent. Path to the communication socket is derived from homedir.
|
||||
- // The gpg-agent automaticaly removes all its socket before exit.
|
||||
- // Newer gpg-agent creates sockets under [/var]/run/user/{pid}/... if directory exists.
|
||||
- // In this case gpg-agent will not be exited.
|
||||
- killGpgAgent(ctx, gpgDir);
|
||||
-
|
||||
logger->debug(tfm::format(_("repo %s: imported key 0x%s."), id, keyInfo.getId()));
|
||||
}
|
||||
|
6094
SOURCES/0004-Update-translations-RhBug-1820548.patch
Normal file
6094
SOURCES/0004-Update-translations-RhBug-1820548.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,21 @@
|
||||
diff -u b/python/hawkey/goal-py.cpp b/python/hawkey/goal-py.cpp
|
||||
--- b/python/hawkey/goal-py.cpp
|
||||
+++ b/python/hawkey/goal-py.cpp
|
||||
@@ -253,7 +253,7 @@
|
||||
int c_value = PyObject_IsTrue(value);
|
||||
self->goal->set_protect_running_kernel(c_value);
|
||||
return 0;
|
||||
-} CATCH_TO_PYTHON
|
||||
+} CATCH_TO_PYTHON_INT
|
||||
|
||||
static PyObject *
|
||||
erase(_GoalObject *self, PyObject *args, PyObject *kwds) try
|
||||
@@ -645,7 +645,7 @@
|
||||
|
||||
static PyGetSetDef goal_getsetters[] = {
|
||||
{(char*)"actions", (getter)get_actions, NULL, NULL, NULL},
|
||||
- {"protect_running_kernel", (getter)get_protect_running_kernel,
|
||||
+ {(char*)"protect_running_kernel", (getter)get_protect_running_kernel,
|
||||
(setter)set_protect_running_kernel, NULL, NULL},
|
||||
{NULL} /* sentinel */
|
||||
};
|
File diff suppressed because it is too large
Load Diff
@ -1,126 +0,0 @@
|
||||
From 594560870c416d0133b08a64e0632a53a6217f71 Mon Sep 17 00:00:00 2001
|
||||
From: Marek Blaha <mblaha@redhat.com>
|
||||
Date: Mon, 20 Jan 2020 09:58:03 +0100
|
||||
Subject: [PATCH] Fix filtering packages by advisory (RhBug:1770125)
|
||||
|
||||
Currently the filter does not work well in situation when more versions
|
||||
and architectures of advisory packages are available.
|
||||
|
||||
Let's have package gjs-1.56.2-6.fc30.x86_64
|
||||
and two advisories related to gjs package:
|
||||
FEDORA-2019-f4eb34cf4c
|
||||
gjs-1.56.2-1.fc30.src
|
||||
gjs-1.56.2-1.fc30.x86_64
|
||||
FEDORA-2019-57b5902ed1
|
||||
gjs-1.56.2-6.fc30.src
|
||||
gjs-1.56.2-6.fc30.x86_64
|
||||
|
||||
In this case the FEDORA-2019-57b5902ed1 advisory is not matched for
|
||||
gjs-1.56.2-6.fc30.x86_64 package (considering >= operator as in 'dnf
|
||||
update --bugfix') because only the package of `src` architecture as been
|
||||
checked. The checking of other versions/architectures was missing.
|
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1770125
|
||||
---
|
||||
libdnf/sack/query.cpp | 63 +++++++++++++++----------------------------
|
||||
1 file changed, 22 insertions(+), 41 deletions(-)
|
||||
|
||||
diff --git a/libdnf/sack/query.cpp b/libdnf/sack/query.cpp
|
||||
index 6e9e4715f..122a50df6 100644
|
||||
--- a/libdnf/sack/query.cpp
|
||||
+++ b/libdnf/sack/query.cpp
|
||||
@@ -518,9 +518,9 @@ advisoryPkgCompareSolvable(const AdvisoryPkg &first, const Solvable &s)
|
||||
{
|
||||
if (first.getName() != s.name)
|
||||
return first.getName() < s.name;
|
||||
- if (first.getEVR() != s.evr)
|
||||
- return first.getEVR() < s.evr;
|
||||
- return first.getArch() < s.arch;
|
||||
+ if (first.getArch() != s.arch)
|
||||
+ return first.getArch() < s.arch;
|
||||
+ return first.getEVR() < s.evr;
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -1607,13 +1607,12 @@ Query::Impl::filterLocation(const Filter & f, Map *m)
|
||||
|
||||
/**
|
||||
* @brief Reduce query to security filters. It reflect following compare types: HY_EQ, HY_GT, HY_LT.
|
||||
-* In case HY_GT or HY_LT, it first find all advisory packages that EQ to packages in result.
|
||||
-* Then it adds packages from Result to Map *m if Name and Arch is EQ, and EVR comparison is
|
||||
-* according to one of selected compare type (HY_EQ, HY_GT, HY_LT).
|
||||
*
|
||||
-* @param f p_f:...
|
||||
-* @param m p_m:...
|
||||
-* @param keyname p_keyname:...
|
||||
+* @param f: Filter that should be applied on advisories
|
||||
+* @param m: Map of query results complying the filter
|
||||
+* @param keyname: how are the advisories matched. HY_PKG_ADVISORY, HY_PKG_ADVISORY_BUG,
|
||||
+* HY_PKG_ADVISORY_CVE, HY_PKG_ADVISORY_TYPE and HY_PKG_ADVISORY_SEVERITY
|
||||
+* are supported
|
||||
*/
|
||||
void
|
||||
Query::Impl::filterAdvisory(const Filter & f, Map *m, int keyname)
|
||||
@@ -1668,7 +1667,6 @@ Query::Impl::filterAdvisory(const Filter & f, Map *m, int keyname)
|
||||
// convert nevras (from DnfAdvisoryPkg) to pool ids
|
||||
Id id = -1;
|
||||
int cmp_type = f.getCmpType();
|
||||
- bool cmpTypeGreaterOrLower = cmp_type & HY_GT || cmp_type & HY_LT;
|
||||
while (true) {
|
||||
if (pkgs.size() == 0)
|
||||
break;
|
||||
@@ -1676,40 +1674,23 @@ Query::Impl::filterAdvisory(const Filter & f, Map *m, int keyname)
|
||||
if (id == -1)
|
||||
break;
|
||||
Solvable* s = pool_id2solvable(pool, id);
|
||||
- auto low = std::lower_bound(pkgs.begin(), pkgs.end(), *s, advisoryPkgCompareSolvable);
|
||||
- if (low != pkgs.end() && low->nevraEQ(s)) {
|
||||
- if (cmpTypeGreaterOrLower) {
|
||||
- pkgsSecondRun.push_back(*low);
|
||||
- } else {
|
||||
+ if (cmp_type == HY_EQ) {
|
||||
+ auto low = std::lower_bound(pkgs.begin(), pkgs.end(), *s, advisoryPkgCompareSolvable);
|
||||
+ if (low != pkgs.end() && low->nevraEQ(s)) {
|
||||
MAPSET(m, id);
|
||||
}
|
||||
- }
|
||||
- }
|
||||
- if (!cmpTypeGreaterOrLower) {
|
||||
- return;
|
||||
- }
|
||||
- std::sort(pkgsSecondRun.begin(), pkgsSecondRun.end(), advisoryPkgSort);
|
||||
- id = -1;
|
||||
- while (true) {
|
||||
- if (pkgsSecondRun.size() == 0)
|
||||
- break;
|
||||
- id = resultPset->next(id);
|
||||
- if (id == -1)
|
||||
- break;
|
||||
- Solvable* s = pool_id2solvable(pool, id);
|
||||
- auto low = std::lower_bound(pkgsSecondRun.begin(), pkgsSecondRun.end(), *s,
|
||||
- advisoryPkgCompareSolvableNameArch);
|
||||
- while (low != pkgsSecondRun.end() && low->getName() == s->name &&
|
||||
- low->getArch() == s->arch) {
|
||||
-
|
||||
- int cmp = pool_evrcmp(pool, s->evr, low->getEVR(), EVRCMP_COMPARE);
|
||||
- if ((cmp > 0 && cmp_type & HY_GT) ||
|
||||
- (cmp < 0 && cmp_type & HY_LT) ||
|
||||
- (cmp == 0 && cmp_type & HY_EQ)) {
|
||||
- MAPSET(m, id);
|
||||
- break;
|
||||
+ } else {
|
||||
+ auto low = std::lower_bound(pkgs.begin(), pkgs.end(), *s, advisoryPkgCompareSolvableNameArch);
|
||||
+ while (low != pkgs.end() && low->getName() == s->name && low->getArch() == s->arch) {
|
||||
+ int cmp = pool_evrcmp(pool, s->evr, low->getEVR(), EVRCMP_COMPARE);
|
||||
+ if ((cmp > 0 && cmp_type & HY_GT) ||
|
||||
+ (cmp < 0 && cmp_type & HY_LT) ||
|
||||
+ (cmp == 0 && cmp_type & HY_EQ)) {
|
||||
+ MAPSET(m, id);
|
||||
+ break;
|
||||
+ }
|
||||
+ ++low;
|
||||
}
|
||||
- ++low;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,306 +0,0 @@
|
||||
From add2ce925b65532455e3522113bede4f99993638 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hr=C3=A1zk=C3=BD?= <lhrazky@redhat.com>
|
||||
Date: Wed, 10 Jul 2019 15:42:19 +0200
|
||||
Subject: [PATCH 1/5] Query: use the common dep switch branch for CONFLICTS
|
||||
when applying
|
||||
|
||||
Join the HY_PKG_CONFLICTS switch branch with the rest of the
|
||||
dependencies and remove the matchtype assert. The assert is done in the
|
||||
filterRcoReldep() function and the rest is the same.
|
||||
---
|
||||
libdnf/sack/query.cpp | 5 +----
|
||||
1 file changed, 1 insertion(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libdnf/sack/query.cpp b/libdnf/sack/query.cpp
|
||||
index 122a50df..f044faa6 100644
|
||||
--- a/libdnf/sack/query.cpp
|
||||
+++ b/libdnf/sack/query.cpp
|
||||
@@ -1977,9 +1977,6 @@ Query::Impl::apply()
|
||||
case HY_PKG_EMPTY:
|
||||
/* used to set query empty by keeping Map m empty */
|
||||
break;
|
||||
- case HY_PKG_CONFLICTS:
|
||||
- filterRcoReldep(f, &m);
|
||||
- break;
|
||||
case HY_PKG_NAME:
|
||||
filterName(f, &m);
|
||||
break;
|
||||
@@ -2019,12 +2016,12 @@ Query::Impl::apply()
|
||||
assert(f.getMatchType() == _HY_RELDEP);
|
||||
filterProvidesReldep(f, &m);
|
||||
break;
|
||||
+ case HY_PKG_CONFLICTS:
|
||||
case HY_PKG_ENHANCES:
|
||||
case HY_PKG_RECOMMENDS:
|
||||
case HY_PKG_REQUIRES:
|
||||
case HY_PKG_SUGGESTS:
|
||||
case HY_PKG_SUPPLEMENTS:
|
||||
- assert(f.getMatchType() == _HY_RELDEP);
|
||||
filterRcoReldep(f, &m);
|
||||
break;
|
||||
case HY_PKG_REPONAME:
|
||||
--
|
||||
2.25.4
|
||||
|
||||
|
||||
From 8b06d5b286d165eb8002b6a002d336ab2b72b0b2 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hr=C3=A1zk=C3=BD?= <lhrazky@redhat.com>
|
||||
Date: Thu, 11 Jul 2019 11:54:11 +0200
|
||||
Subject: [PATCH 2/5] Query: add a dependency by solvable filter
|
||||
(RhBug:1534123,1698034)
|
||||
|
||||
This allows to filter all dependencies (requires, conflicts, recommends,
|
||||
etc.) by a list of solvables that match the dependency.
|
||||
|
||||
Can be used in the dnf repoquery command instead of a low-level piece of
|
||||
code which was expanding packages to their provides and then matching the
|
||||
dependencies as reldeps.
|
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1534123
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1698034
|
||||
---
|
||||
libdnf/sack/query.cpp | 33 +++++++++++++++++++++++++++++++--
|
||||
1 file changed, 31 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libdnf/sack/query.cpp b/libdnf/sack/query.cpp
|
||||
index f044faa6..d96d5d12 100644
|
||||
--- a/libdnf/sack/query.cpp
|
||||
+++ b/libdnf/sack/query.cpp
|
||||
@@ -280,7 +280,7 @@ valid_filter_num(int keyname, int cmp_type)
|
||||
static bool
|
||||
valid_filter_pkg(int keyname, int cmp_type)
|
||||
{
|
||||
- if (!match_type_pkg(keyname))
|
||||
+ if (!match_type_pkg(keyname) && !match_type_reldep(keyname))
|
||||
return false;
|
||||
return cmp_type == HY_EQ || cmp_type == HY_NEQ;
|
||||
}
|
||||
@@ -683,6 +683,7 @@ private:
|
||||
void filterNevraStrict(int cmpType, const char **matches);
|
||||
void initResult();
|
||||
void filterPkg(const Filter & f, Map *m);
|
||||
+ void filterDepSolvable(const Filter & f, Map * m);
|
||||
void filterRcoReldep(const Filter & f, Map *m);
|
||||
void filterName(const Filter & f, Map *m);
|
||||
void filterEpoch(const Filter & f, Map *m);
|
||||
@@ -1058,6 +1059,30 @@ Query::Impl::filterPkg(const Filter & f, Map *m)
|
||||
map_init_clone(m, dnf_packageset_get_map(f.getMatches()[0].pset));
|
||||
}
|
||||
|
||||
+void
|
||||
+Query::Impl::filterDepSolvable(const Filter & f, Map * m)
|
||||
+{
|
||||
+ assert(f.getMatchType() == _HY_PKG);
|
||||
+ assert(f.getMatches().size() == 1);
|
||||
+
|
||||
+ dnf_sack_make_provides_ready(sack);
|
||||
+ Pool * pool = dnf_sack_get_pool(sack);
|
||||
+ Id rco_key = reldep_keyname2id(f.getKeyname());
|
||||
+
|
||||
+ IdQueue out;
|
||||
+
|
||||
+ const auto filter_pset = f.getMatches()[0].pset;
|
||||
+ Id id = -1;
|
||||
+ while ((id = filter_pset->next(id)) != -1) {
|
||||
+ out.clear();
|
||||
+ pool_whatmatchessolvable(pool, rco_key, id, out.getQueue(), -1);
|
||||
+
|
||||
+ for (int j = 0; j < out.size(); ++j) {
|
||||
+ MAPSET(m, out[j]);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void
|
||||
Query::Impl::filterRcoReldep(const Filter & f, Map *m)
|
||||
{
|
||||
@@ -2022,7 +2047,11 @@ Query::Impl::apply()
|
||||
case HY_PKG_REQUIRES:
|
||||
case HY_PKG_SUGGESTS:
|
||||
case HY_PKG_SUPPLEMENTS:
|
||||
- filterRcoReldep(f, &m);
|
||||
+ if (f.getMatchType() == _HY_RELDEP)
|
||||
+ filterRcoReldep(f, &m);
|
||||
+ else {
|
||||
+ filterDepSolvable(f, &m);
|
||||
+ }
|
||||
break;
|
||||
case HY_PKG_REPONAME:
|
||||
filterReponame(f, &m);
|
||||
--
|
||||
2.25.4
|
||||
|
||||
|
||||
From 1a62aa8336ab390a1825d052a096b613805b20ca Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hr=C3=A1zk=C3=BD?= <lhrazky@redhat.com>
|
||||
Date: Wed, 21 Aug 2019 16:50:49 +0200
|
||||
Subject: [PATCH 3/5] Hawkey tests: fix filtering on requires by passing a
|
||||
query
|
||||
|
||||
Fixes tests after allowing to pass a query (or an iterable of packages)
|
||||
as an argument to dependency filters (requires, suggests, etc.) in
|
||||
"Query: add a dependency by solvable filter".
|
||||
|
||||
Drops the exception check and adds a simple test for the new
|
||||
functionality.
|
||||
---
|
||||
python/hawkey/tests/tests/test_query.py | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/python/hawkey/tests/tests/test_query.py b/python/hawkey/tests/tests/test_query.py
|
||||
index 1d45f163..3ee009dd 100644
|
||||
--- a/python/hawkey/tests/tests/test_query.py
|
||||
+++ b/python/hawkey/tests/tests/test_query.py
|
||||
@@ -352,12 +352,17 @@ class TestQueryUpdates(base.TestCase):
|
||||
q = hawkey.Query(self.sack).filter(name="penny")
|
||||
o = hawkey.Query(self.sack)
|
||||
self.assertRaises(hawkey.QueryException, o.filter, obsoletes__gt=q)
|
||||
- self.assertRaises(hawkey.ValueException, o.filter, requires=q)
|
||||
|
||||
o = hawkey.Query(self.sack).filter(obsoletes=q)
|
||||
self.assertLength(o, 1)
|
||||
self.assertEqual(str(o[0]), "fool-1-5.noarch")
|
||||
|
||||
+ def test_requires_with_package_list(self):
|
||||
+ q = hawkey.Query(self.sack).filter(name="fool")
|
||||
+ o = hawkey.Query(self.sack).filter(requires=q)
|
||||
+ self.assertLength(o, 1)
|
||||
+ self.assertEqual(str(o[0]), "walrus-2-6.noarch")
|
||||
+
|
||||
def test_subquery_evaluated(self):
|
||||
q = hawkey.Query(self.sack).filter(name="penny")
|
||||
self.assertFalse(q.evaluated)
|
||||
--
|
||||
2.25.4
|
||||
|
||||
|
||||
From d1554451b123c2a83f665d743214ca4d3d0ef3a0 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hr=C3=A1zk=C3=BD?= <lhrazky@redhat.com>
|
||||
Date: Tue, 14 Jan 2020 13:40:58 +0100
|
||||
Subject: [PATCH 4/5] Query: Add support for a sequence of packages to
|
||||
dependency queries
|
||||
|
||||
In addition to supporting a query as an argument to the dependency
|
||||
filters (which then gets resolved to a list of packages), add support
|
||||
for passing a sequence of packages directly.
|
||||
---
|
||||
python/hawkey/query-py.cpp | 16 ++++++++--------
|
||||
python/hawkey/tests/tests/test_query.py | 8 +++++++-
|
||||
2 files changed, 15 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/python/hawkey/query-py.cpp b/python/hawkey/query-py.cpp
|
||||
index 274b8c3e..5e1d368b 100644
|
||||
--- a/python/hawkey/query-py.cpp
|
||||
+++ b/python/hawkey/query-py.cpp
|
||||
@@ -345,7 +345,13 @@ filter_add(HyQuery query, key_t keyname, int cmp_type, PyObject *match)
|
||||
switch (keyname) {
|
||||
case HY_PKG:
|
||||
case HY_PKG_OBSOLETES:
|
||||
- case HY_PKG_OBSOLETES_BY_PRIORITY: {
|
||||
+ case HY_PKG_OBSOLETES_BY_PRIORITY:
|
||||
+ case HY_PKG_CONFLICTS:
|
||||
+ case HY_PKG_REQUIRES:
|
||||
+ case HY_PKG_ENHANCES:
|
||||
+ case HY_PKG_RECOMMENDS:
|
||||
+ case HY_PKG_SUGGESTS:
|
||||
+ case HY_PKG_SUPPLEMENTS: {
|
||||
// It could be a sequence of packages or reldep/strings. Lets try packages first.
|
||||
auto pset = pyseq_to_packageset(match, query->getSack());
|
||||
if (!pset) {
|
||||
@@ -372,13 +378,7 @@ filter_add(HyQuery query, key_t keyname, int cmp_type, PyObject *match)
|
||||
|
||||
break;
|
||||
}
|
||||
- case HY_PKG_CONFLICTS:
|
||||
- case HY_PKG_PROVIDES:
|
||||
- case HY_PKG_REQUIRES:
|
||||
- case HY_PKG_ENHANCES:
|
||||
- case HY_PKG_RECOMMENDS:
|
||||
- case HY_PKG_SUGGESTS:
|
||||
- case HY_PKG_SUPPLEMENTS: {
|
||||
+ case HY_PKG_PROVIDES: {
|
||||
auto reldeplist = pyseq_to_reldeplist(match, query->getSack(), cmp_type);
|
||||
if (reldeplist == NULL)
|
||||
return 1;
|
||||
diff --git a/python/hawkey/tests/tests/test_query.py b/python/hawkey/tests/tests/test_query.py
|
||||
index 3ee009dd..ff942e71 100644
|
||||
--- a/python/hawkey/tests/tests/test_query.py
|
||||
+++ b/python/hawkey/tests/tests/test_query.py
|
||||
@@ -357,12 +357,18 @@ class TestQueryUpdates(base.TestCase):
|
||||
self.assertLength(o, 1)
|
||||
self.assertEqual(str(o[0]), "fool-1-5.noarch")
|
||||
|
||||
- def test_requires_with_package_list(self):
|
||||
+ def test_requires_with_query(self):
|
||||
q = hawkey.Query(self.sack).filter(name="fool")
|
||||
o = hawkey.Query(self.sack).filter(requires=q)
|
||||
self.assertLength(o, 1)
|
||||
self.assertEqual(str(o[0]), "walrus-2-6.noarch")
|
||||
|
||||
+ def test_requires_with_package_list(self):
|
||||
+ q = hawkey.Query(self.sack).filter(name="fool")
|
||||
+ o = hawkey.Query(self.sack).filter(requires=q.run())
|
||||
+ self.assertLength(o, 1)
|
||||
+ self.assertEqual(str(o[0]), "walrus-2-6.noarch")
|
||||
+
|
||||
def test_subquery_evaluated(self):
|
||||
q = hawkey.Query(self.sack).filter(name="penny")
|
||||
self.assertFalse(q.evaluated)
|
||||
--
|
||||
2.25.4
|
||||
|
||||
|
||||
From cbaafb957532dfde13080903503cae4488b0863f Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= <amatej@redhat.com>
|
||||
Date: Tue, 17 Mar 2020 13:11:14 +0100
|
||||
Subject: [PATCH 5/5] Use libsolv selection for filtering DepSolvables
|
||||
(RhBug:1812596)
|
||||
|
||||
We cannot use pool_whatmatchessolvable because it considers only
|
||||
installable solvables, which means source rpms are ignored.
|
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1812596
|
||||
---
|
||||
libdnf/sack/query.cpp | 18 ++++++++++++++++--
|
||||
1 file changed, 16 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libdnf/sack/query.cpp b/libdnf/sack/query.cpp
|
||||
index d96d5d12..390703c9 100644
|
||||
--- a/libdnf/sack/query.cpp
|
||||
+++ b/libdnf/sack/query.cpp
|
||||
@@ -29,6 +29,7 @@ extern "C" {
|
||||
#include <solv/bitmap.h>
|
||||
#include <solv/evr.h>
|
||||
#include <solv/solver.h>
|
||||
+#include <solv/selection.h>
|
||||
}
|
||||
|
||||
#include "query.hpp"
|
||||
@@ -1075,9 +1076,22 @@ Query::Impl::filterDepSolvable(const Filter & f, Map * m)
|
||||
Id id = -1;
|
||||
while ((id = filter_pset->next(id)) != -1) {
|
||||
out.clear();
|
||||
- pool_whatmatchessolvable(pool, rco_key, id, out.getQueue(), -1);
|
||||
|
||||
- for (int j = 0; j < out.size(); ++j) {
|
||||
+ queue_init(out.getQueue());
|
||||
+ // queue_push2 because we are creating a selection, which contains pairs
|
||||
+ // of <flags, Id>, SOLVER_SOOLVABLE_ALL is a special flag which includes
|
||||
+ // all packages from specified pool, Id is ignored.
|
||||
+ queue_push2(out.getQueue(), SOLVER_SOLVABLE_ALL, 0);
|
||||
+
|
||||
+ int flags = 0;
|
||||
+ flags |= SELECTION_FILTER | SELECTION_WITH_ALL;
|
||||
+ selection_make_matchsolvable(pool, out.getQueue(), id, flags, rco_key, 0);
|
||||
+
|
||||
+ // Queue from selection_make_matchsolvable is a selection, which means
|
||||
+ // it conntains pairs <flags, Id>, flags refers to how was the Id
|
||||
+ // matched, that is not important here, so skip it and iterate just
|
||||
+ // over the Ids.
|
||||
+ for (int j = 1; j < out.size(); j += 2) {
|
||||
MAPSET(m, out[j]);
|
||||
}
|
||||
}
|
||||
--
|
||||
2.25.4
|
||||
|
@ -1,8 +1,11 @@
|
||||
%global libsolv_version 0.7.7
|
||||
%global libmodulemd_version 1.6.1
|
||||
%global librepo_version 1.11.0
|
||||
%global dnf_conflict 4.2.13
|
||||
%global libmodulemd_version 2.5.0
|
||||
%global librepo_version 1.12.0
|
||||
%global dnf_conflict 4.2.23
|
||||
%global swig_version 3.0.12
|
||||
%global libdnf_major_version 0
|
||||
%global libdnf_minor_version 48
|
||||
%global libdnf_micro_version 0
|
||||
|
||||
# set sphinx package name according to distro
|
||||
%global requires_python2_sphinx python2-sphinx
|
||||
@ -43,25 +46,24 @@
|
||||
%bcond_without zchunk
|
||||
%endif
|
||||
|
||||
%bcond_with sanitizers
|
||||
|
||||
%global _cmake_opts \\\
|
||||
-DENABLE_RHSM_SUPPORT=%{?with_rhsm:ON}%{!?with_rhsm:OFF} \\\
|
||||
%{nil}
|
||||
|
||||
Name: libdnf
|
||||
Version: 0.39.1
|
||||
Release: 6%{?dist}
|
||||
Version: %{libdnf_major_version}.%{libdnf_minor_version}.%{libdnf_micro_version}
|
||||
Release: 5%{?dist}
|
||||
Summary: Library providing simplified C and Python API to libsolv
|
||||
License: LGPLv2+
|
||||
URL: https://github.com/rpm-software-management/libdnf
|
||||
Source0: %{url}/archive/%{version}/%{name}-%{version}.tar.gz
|
||||
Patch1: 0001-user-agent-Drop-the-whitelist.patch
|
||||
Patch2: 0002-context-wildcard-support-in-dnf_context_repo_set_data-RhBug1781420.patch
|
||||
Patch3: 0003-Add-2-query-filters.patch
|
||||
Patch4: 0004-Remove-killGpgAgent-function-RhBug1781601.patch
|
||||
Patch5: 0005-Update-translations-from-zanata-RhBug-1754965.patch
|
||||
Patch6: 0006-Fix-filtering-packages-by-advisory-RhBug-1770125.patch
|
||||
# Includes Use libsolv selection for filtering DepSolvables (RhBug:1812596)
|
||||
Patch7: 0007-Add-expanding-solvable-provides-for-dependency-matching-RhBug-1819172.patch
|
||||
Patch1: 0001-history-Fix-dnf-history-rollback-when-a-package-was-removed-RhBug1683134.patch
|
||||
Patch2: 0002-Add-log-file-level-main-config-option-RhBug-1802074.patch
|
||||
Patch3: 0003-Accept-double-eq-as-an-operator-in-reldeps-RhBug-1847946.patch
|
||||
Patch4: 0004-Update-translations-RhBug-1820548.patch
|
||||
Patch5: 0005-Handle-exception-in-a-python-binding-by-the-proper-function-RhBug-1870492.patch
|
||||
|
||||
BuildRequires: cmake
|
||||
BuildRequires: gcc
|
||||
@ -85,11 +87,17 @@ BuildRequires: pkgconfig(sqlite3)
|
||||
BuildRequires: pkgconfig(json-c)
|
||||
BuildRequires: pkgconfig(cppunit)
|
||||
BuildRequires: pkgconfig(libcrypto)
|
||||
BuildRequires: pkgconfig(modulemd) >= %{libmodulemd_version}
|
||||
BuildRequires: pkgconfig(modulemd-2.0) >= %{libmodulemd_version}
|
||||
BuildRequires: pkgconfig(smartcols)
|
||||
BuildRequires: gettext
|
||||
BuildRequires: gpgme-devel
|
||||
|
||||
%if %{with sanitizers}
|
||||
BuildRequires: libasan-static
|
||||
BuildRequires: liblsan-static
|
||||
BuildRequires: libubsan-static
|
||||
%endif
|
||||
|
||||
Requires: libmodulemd%{?_isa} >= %{libmodulemd_version}
|
||||
Requires: libsolv%{?_isa} >= %{libsolv_version}
|
||||
Requires: librepo%{?_isa} >= %{librepo_version}
|
||||
@ -132,7 +140,8 @@ BuildRequires: swig >= %{swig_version}
|
||||
|
||||
%description -n python2-%{name}
|
||||
Python 2 bindings for the libdnf library.
|
||||
%endif # with python2
|
||||
%endif
|
||||
# endif with python2
|
||||
|
||||
%if %{with python3}
|
||||
%package -n python3-%{name}
|
||||
@ -166,7 +175,8 @@ Conflicts: python-dnf < %{dnf_conflict}
|
||||
|
||||
%description -n python2-hawkey
|
||||
Python 2 bindings for the hawkey library.
|
||||
%endif # with python2
|
||||
%endif
|
||||
# endif with python2
|
||||
|
||||
%if %{with python3}
|
||||
%package -n python3-hawkey
|
||||
@ -190,7 +200,7 @@ Python 3 bindings for the hawkey library.
|
||||
%autosetup -p1
|
||||
%if %{with python2}
|
||||
mkdir build-py2
|
||||
%endif # with python2
|
||||
%endif
|
||||
%if %{with python3}
|
||||
mkdir build-py3
|
||||
%endif
|
||||
@ -203,10 +213,12 @@ pushd build-py2
|
||||
%define _cmake_builddir build-py2
|
||||
%define __builddir build-py2
|
||||
%endif
|
||||
%cmake -DPYTHON_DESIRED:FILEPATH=%{__python2} -DWITH_MAN=OFF ../ %{!?with_zchunk:-DWITH_ZCHUNK=OFF} %{!?with_valgrind:-DDISABLE_VALGRIND=1} %{_cmake_opts}
|
||||
%cmake -DPYTHON_DESIRED:FILEPATH=%{__python2} -DWITH_MAN=OFF ../ %{!?with_zchunk:-DWITH_ZCHUNK=OFF} %{!?with_valgrind:-DDISABLE_VALGRIND=1} %{_cmake_opts} -DLIBDNF_MAJOR_VERSION=%{libdnf_major_version} -DLIBDNF_MINOR_VERSION=%{libdnf_minor_version} -DLIBDNF_MICRO_VERSION=%{libdnf_micro_version} \
|
||||
-DWITH_SANITIZERS=%{?with_sanitizers:ON}%{!?with_sanitizers:OFF}
|
||||
%make_build
|
||||
popd
|
||||
%endif # with python2
|
||||
%endif
|
||||
# endif with python2
|
||||
|
||||
%if %{with python3}
|
||||
pushd build-py3
|
||||
@ -215,7 +227,8 @@ pushd build-py3
|
||||
%define _cmake_builddir build-py3
|
||||
%define __builddir build-py3
|
||||
%endif
|
||||
%cmake -DPYTHON_DESIRED:FILEPATH=%{__python3} -DWITH_GIR=0 -DWITH_MAN=0 -Dgtkdoc=0 ../ %{!?with_zchunk:-DWITH_ZCHUNK=OFF} %{!?with_valgrind:-DDISABLE_VALGRIND=1} %{_cmake_opts}
|
||||
%cmake -DPYTHON_DESIRED:FILEPATH=%{__python3} -DWITH_GIR=0 -DWITH_MAN=0 -Dgtkdoc=0 ../ %{!?with_zchunk:-DWITH_ZCHUNK=OFF} %{!?with_valgrind:-DDISABLE_VALGRIND=1} %{_cmake_opts} -DLIBDNF_MAJOR_VERSION=%{libdnf_major_version} -DLIBDNF_MINOR_VERSION=%{libdnf_minor_version} -DLIBDNF_MICRO_VERSION=%{libdnf_micro_version} \
|
||||
-DWITH_SANITIZERS=%{?with_sanitizers:ON}%{!?with_sanitizers:OFF}
|
||||
%make_build
|
||||
popd
|
||||
%endif
|
||||
@ -225,7 +238,7 @@ popd
|
||||
pushd build-py2
|
||||
make ARGS="-V" test
|
||||
popd
|
||||
%endif # with python2
|
||||
%endif
|
||||
%if %{with python3}
|
||||
# If we didn't run the general tests yet, do it now.
|
||||
%if %{without python2}
|
||||
@ -247,7 +260,7 @@ popd
|
||||
pushd build-py2
|
||||
%make_install
|
||||
popd
|
||||
%endif # with python2
|
||||
%endif
|
||||
%if %{with python3}
|
||||
pushd build-py3
|
||||
%make_install
|
||||
@ -280,7 +293,7 @@ popd
|
||||
%if %{with python2}
|
||||
%files -n python2-%{name}
|
||||
%{python2_sitearch}/%{name}/
|
||||
%endif # with python2
|
||||
%endif
|
||||
|
||||
%if %{with python3}
|
||||
%files -n python3-%{name}
|
||||
@ -290,7 +303,7 @@ popd
|
||||
%if %{with python2}
|
||||
%files -n python2-hawkey
|
||||
%{python2_sitearch}/hawkey/
|
||||
%endif # with python2
|
||||
%endif
|
||||
|
||||
%if %{with python3}
|
||||
%files -n python3-hawkey
|
||||
@ -298,8 +311,78 @@ popd
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Wed May 06 2020 Nicola Sella <nsella@redhat.com> - 0.39.1-6
|
||||
- Add expanding solvable provides for dependency matching (RhBug:1819172)
|
||||
* Thu Aug 20 2020 Nicola Sella <nsella@redhat.com> - 0.48.0-5
|
||||
- [covscan] Handle exception in a python binding by the proper function (RhBug:1870492)
|
||||
|
||||
* Tue Jul 28 2020 Marek Blaha <mblaha@redhat.com> - 0.48.0-4
|
||||
- Update translations (RhBug:1820548)
|
||||
|
||||
* Fri Jul 17 2020 Nicola Sella <nsella@redhat.com> - 0.48.0-3
|
||||
- Add log file level main config option (RhBug:1802074)
|
||||
- Accept '==' as an operator in reldeps (RhBug:1847946)
|
||||
|
||||
* Wed Jun 10 2020 Ales Matej <amatej@redhat.com> - 0.48.0-2
|
||||
- [history] Fix dnf history rollback when a package was removed (RhBug:1683134)
|
||||
|
||||
* Wed Jun 03 2020 Nicola Sella <nsella@redhat.com> - 0.48.0-1
|
||||
- Update to 0.48.0
|
||||
- swdb: Catch only SQLite3 exceptions and simplify the messages
|
||||
- MergedTransaction list multiple comments (RhBug:1773679)
|
||||
- Modify CMake to pull *.po files from weblate
|
||||
- Optimize DependencyContainer creation from an existing queue
|
||||
- fix a memory leak in dnf_package_get_requires()
|
||||
- Fix memory leaks on g_build_filename()
|
||||
- Fix memory leak in dnf_context_setup()
|
||||
- Add `hy_goal_favor` and `hy_goal_disfavor`
|
||||
- Define a cleanup function for `DnfPackageSet`
|
||||
- dnf-repo: fix dnf_repo_get_public_keys double-free
|
||||
- Do not cache RPMDB
|
||||
- Use single-quotes around string literals used in SQL statements
|
||||
- SQLite3: Do not close the database if it wasn't opened (RhBug:1761976)
|
||||
- Don't create a new history DB connection for in-memory DB
|
||||
- transaction/Swdb: Use a single logger variable in constructor
|
||||
- utils: Add a safe version of pathExists()
|
||||
- swdb: Handle the case when pathExists() fails on e.g. permission
|
||||
- Repo: prepend "file://" if a local path is used as baseurl
|
||||
- Move urlEncode() to utils
|
||||
- utils: Add 'exclude' argument to urlEncode()
|
||||
- Encode package URL for downloading through librepo (RhBug:1817130)
|
||||
- Replace std::runtime_error with libdnf::RepoError
|
||||
- Fixes and error handling improvements of the File class
|
||||
- [context] Use ConfigRepo for gpgkey and baseurl (RhBug:1807864)
|
||||
- [context] support "priority" option in .repo config file (RhBug:1797265)
|
||||
|
||||
* Fri Apr 03 2020 Ales Matej <amatej@redhat.com> - 0.47.0-1
|
||||
- Update to 0.47.0
|
||||
- Allow excluding packages with "excludepkgs" and globs
|
||||
- Make parsing of reldeps more strict (RhBug:1788107)
|
||||
- Add expanding solvable provides for dependency matching (RhBug:1534123)
|
||||
- DnfRepo: fix module_hotfixes keyfile priority level
|
||||
- Add custom exceptions to libdnf interface
|
||||
- Port to libmodulemd-2 API (RhBug:1693683)
|
||||
- Add prereq_ignoreinst & regular_requires properties for pkg (RhBug:1543449)
|
||||
- Reset active modules when no module enabled or default (RhBug:1767351)
|
||||
- Add comment option to transaction (RhBug:1773679)
|
||||
- Baseurl is not exclusive with mirrorlist/metalink (RhBug:1775184)
|
||||
- Add new function to reset all modules in C API (dnf_context_reset_all_modules)
|
||||
- Handle situation when an unprivileged user cannot create history database (RhBug:1634385)
|
||||
- Add query filter: latest by priority
|
||||
- Add setter for running kernel protection setting
|
||||
- Add DNF_NO_PROTECTED flag to allow empty list of protected packages
|
||||
- Config options: only first empty value clears existing (RhBug:1788154)
|
||||
- [conf] Set useful default colors when color is enabled
|
||||
- [context] Use installonly_limit from global config (RhBug:1256108)
|
||||
- [context] Add API to get/set "install_weak_deps"
|
||||
- [context] Adds support for includepkgs in repository configuration.
|
||||
- [context] Adds support for excludepkgs, exclude, includepkgs, and disable_excludes in main configuration.
|
||||
- [context] Added function dnf_transaction_set_dont_solve_goal
|
||||
- [context] Added functions dnf_context_get/set_config_file_path
|
||||
- [context] Respect "plugins" global conf value
|
||||
- [context] Add API to disable/enable plugins
|
||||
- [context] Create new repo instead of reusing old one (RhBug:1795004)
|
||||
- [context] Error when main config file can't be opened (RhBug:1794864)
|
||||
- [context] Add function function dnf_context_is_set_config_file_path
|
||||
- [context] Support repositories defined in main configuration file
|
||||
|
||||
* Tue Feb 18 2020 Ales Matej <amatej@redhat.com> - 0.39.1-5
|
||||
- Fix filtering of packages by advisory (RhBug:1770125)
|
||||
|
Loading…
Reference in New Issue
Block a user