From 18e0f49243166831b8e78fa4748a822b2d2bb6fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hr=C3=A1zk=C3=BD?= Date: Tue, 19 Jul 2022 14:16:02 +0200 Subject: [PATCH] Backport patches Resolves: rhbz#2101398 --- ...t-pkgs-to-upgrade-transaction-RhBug-.patch | 64 +++++++++++++++++++ ...l-because-installed_query-is-filtere.patch | 37 +++++++++++ dnf.spec | 9 ++- 3 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 0002-Add-only-relevant-pkgs-to-upgrade-transaction-RhBug-.patch create mode 100644 0003-Use-installed_all-because-installed_query-is-filtere.patch diff --git a/0002-Add-only-relevant-pkgs-to-upgrade-transaction-RhBug-.patch b/0002-Add-only-relevant-pkgs-to-upgrade-transaction-RhBug-.patch new file mode 100644 index 0000000..a0cdeb8 --- /dev/null +++ b/0002-Add-only-relevant-pkgs-to-upgrade-transaction-RhBug-.patch @@ -0,0 +1,64 @@ +From f32eff294aecaac0fd71cd8888a25fa7929460b9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= +Date: Mon, 4 Jul 2022 09:43:25 +0200 +Subject: [PATCH] Add only relevant pkgs to upgrade transaction (RhBug:2097757) + +https://bugzilla.redhat.com/show_bug.cgi?id=2097757 + +Without this patch dnf can create the following transaction during dnf upgrade --security when there is an advisory for B-2-2: + +``` +repo @System 0 testtags +#>=Pkg: A 1 1 x86_64 +#>=Pkg: B 1 1 x86_64 +#>=Req: A = 1-1 + +repo available 0 testtags +#>=Pkg: A 2 2 x86_64 +#>=Pkg: B 2 2 x86_64 +#>=Req: A = 2-2 +system x86_64 rpm @System +job update oneof A-1-1.x86_64@@System B-2-2.x86_64@available [targeted,setevr,setarch] +result transaction,problems +``` + +Problem is that without forcebest nothing gets upgraded despite the available advisory and --security switch. + +This can also be seen in CI test case: rpm-software-management/ci-dnf-stack#1130 +--- + dnf/base.py | 19 ++++++++++++++++++- + 1 file changed, 18 insertions(+), 1 deletion(-) + +diff --git a/dnf/base.py b/dnf/base.py +index caace028..92fb3bd0 100644 +--- a/dnf/base.py ++++ b/dnf/base.py +@@ -2118,7 +2118,24 @@ class Base(object): + query.filterm(reponame=reponame) + query = self._merge_update_filters(query, pkg_spec=pkg_spec, upgrade=True) + if query: +- query = query.union(installed_query.latest()) ++ # Given that we use libsolv's targeted transactions, we need to ensure that the transaction contains both ++ # the new targeted version and also the current installed version (for the upgraded package). This is ++ # because if it only contained the new version, libsolv would decide to reinstall the package even if it ++ # had just a different buildtime or vendor but the same version ++ # (https://github.com/openSUSE/libsolv/issues/287) ++ # - In general, the query already contains both the new and installed versions but not always. ++ # If repository-packages command is used, the installed packages are filtered out because they are from ++ # the @system repo. We need to add them back in. ++ # - However we need to add installed versions of just the packages that are being upgraded. We don't want ++ # to add all installed packages because it could increase the number of solutions for the transaction ++ # (especially without --best) and since libsolv prefers the smallest possible upgrade it could result ++ # in no upgrade even if there is one available. This is a problem in general but its critical with ++ # --security transactions (https://bugzilla.redhat.com/show_bug.cgi?id=2097757) ++ # - We want to add only the latest versions of installed packages, this is specifically for installonly ++ # packages. Otherwise if for example kernel-1 and kernel-3 were installed and present in the ++ # transaction libsolv could decide to install kernel-2 because it is an upgrade for kernel-1 even ++ # though we don't want it because there already is a newer version present. ++ query = query.union(installed_query.latest().filter(name=[pkg.name for pkg in query])) + sltr = dnf.selector.Selector(self.sack) + sltr.set(pkg=query) + self._goal.upgrade(select=sltr) +-- +2.36.1 + diff --git a/0003-Use-installed_all-because-installed_query-is-filtere.patch b/0003-Use-installed_all-because-installed_query-is-filtere.patch new file mode 100644 index 0000000..e5de647 --- /dev/null +++ b/0003-Use-installed_all-because-installed_query-is-filtere.patch @@ -0,0 +1,37 @@ +From 776241568cb10e3a671c574b25e06b63d86e7ac0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= +Date: Mon, 4 Jul 2022 09:46:29 +0200 +Subject: [PATCH] Use `installed_all` because `installed_query` is filtered + user input + +`installed_query` could be missing packages. If we specify we want to +upgrade a specific nevra that is not yet installed, then `installed_query` +is empty because it is based on user input, but there could be other +versions of the pkg installed. + +Eg: if kernel-1 and kernel-3 are installed and we specify we want to +upgrade kernel-2, nothing should be done because we already have higher +version, but now `installed_query` would be empty and kernel-2 would be +installed. + +Therefore, we need to use `installed_all`. +--- + dnf/base.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dnf/base.py b/dnf/base.py +index 92fb3bd0..1b0f07ed 100644 +--- a/dnf/base.py ++++ b/dnf/base.py +@@ -2135,7 +2135,7 @@ class Base(object): + # packages. Otherwise if for example kernel-1 and kernel-3 were installed and present in the + # transaction libsolv could decide to install kernel-2 because it is an upgrade for kernel-1 even + # though we don't want it because there already is a newer version present. +- query = query.union(installed_query.latest().filter(name=[pkg.name for pkg in query])) ++ query = query.union(installed_all.latest().filter(name=[pkg.name for pkg in query])) + sltr = dnf.selector.Selector(self.sack) + sltr.set(pkg=query) + self._goal.upgrade(select=sltr) +-- +2.36.1 + diff --git a/dnf.spec b/dnf.spec index f2e0a9e..71738ac 100644 --- a/dnf.spec +++ b/dnf.spec @@ -66,7 +66,7 @@ It supports RPMs, modules and comps groups & environments. Name: dnf Version: 4.12.0 -Release: 2%{?dist} +Release: 3%{?dist} Summary: %{pkg_summary} # For a breakdown of the licensing, see PACKAGE-LICENSING License: GPLv2+ @@ -75,7 +75,9 @@ Source0: %{url}/archive/%{version}/%{name}-%{version}.tar.gz # Upstream commit which fixes leak of libsolv's page file descriptors. # https://github.com/rpm-software-management/dnf/commit/5ce5ed1ea08ad6e198c1c1642c4d9ea2db6eab86 -Patch0002: 0001-Base.reset-plug-temporary-leak-of-libsolv-s-page-fil.patch +Patch0001: 0001-Base.reset-plug-temporary-leak-of-libsolv-s-page-fil.patch +Patch0002: 0002-Add-only-relevant-pkgs-to-upgrade-transaction-RhBug-.patch +Patch0003: 0003-Use-installed_all-because-installed_query-is-filtere.patch BuildArch: noarch BuildRequires: cmake BuildRequires: gettext @@ -364,6 +366,9 @@ popd %{python3_sitelib}/%{name}/automatic/ %changelog +* Tue Jul 19 2022 Lukas Hrazky - 4.12.0-3 +- Add only relevant pkgs to upgrade transaction (RhBug:2097757) + * Thu Apr 28 2022 Richard W.M. Jones - 4.12.0-2 - Backport fix for leak of libsolv's page file descriptors