Blame SOURCES/0002-Add-only-relevant-pkgs-to-upgrade-transaction-RhBug-.patch

a58eb0
From f32eff294aecaac0fd71cd8888a25fa7929460b9 Mon Sep 17 00:00:00 2001
a58eb0
From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= <amatej@redhat.com>
a58eb0
Date: Mon, 4 Jul 2022 09:43:25 +0200
a58eb0
Subject: [PATCH] Add only relevant pkgs to upgrade transaction (RhBug:2097757)
a58eb0
a58eb0
https://bugzilla.redhat.com/show_bug.cgi?id=2097757
a58eb0
a58eb0
Without this patch dnf can create the following transaction during dnf upgrade --security when there is an advisory for B-2-2:
a58eb0
a58eb0
```
a58eb0
repo @System 0 testtags <inline>
a58eb0
#>=Pkg: A 1 1 x86_64
a58eb0
#>=Pkg: B 1 1 x86_64
a58eb0
#>=Req: A = 1-1
a58eb0
a58eb0
repo available 0 testtags <inline>
a58eb0
#>=Pkg: A 2 2 x86_64
a58eb0
#>=Pkg: B 2 2 x86_64
a58eb0
#>=Req: A = 2-2
a58eb0
system x86_64 rpm @System
a58eb0
job update oneof A-1-1.x86_64@@System B-2-2.x86_64@available [targeted,setevr,setarch]
a58eb0
result transaction,problems
a58eb0
```
a58eb0
a58eb0
Problem is that without forcebest nothing gets upgraded despite the available advisory and --security switch.
a58eb0
a58eb0
This can also be seen in CI test case: rpm-software-management/ci-dnf-stack#1130
a58eb0
---
a58eb0
 dnf/base.py | 19 ++++++++++++++++++-
a58eb0
 1 file changed, 18 insertions(+), 1 deletion(-)
a58eb0
a58eb0
diff --git a/dnf/base.py b/dnf/base.py
a58eb0
index caace028..92fb3bd0 100644
a58eb0
--- a/dnf/base.py
a58eb0
+++ b/dnf/base.py
a58eb0
@@ -2118,7 +2118,24 @@ class Base(object):
a58eb0
             query.filterm(reponame=reponame)
a58eb0
         query = self._merge_update_filters(query, pkg_spec=pkg_spec, upgrade=True)
a58eb0
         if query:
a58eb0
-            query = query.union(installed_query.latest())
a58eb0
+            # Given that we use libsolv's targeted transactions, we need to ensure that the transaction contains both
a58eb0
+            # the new targeted version and also the current installed version (for the upgraded package). This is
a58eb0
+            # because if it only contained the new version, libsolv would decide to reinstall the package even if it
a58eb0
+            # had just a different buildtime or vendor but the same version
a58eb0
+            # (https://github.com/openSUSE/libsolv/issues/287)
a58eb0
+            #   - In general, the query already contains both the new and installed versions but not always.
a58eb0
+            #     If repository-packages command is used, the installed packages are filtered out because they are from
a58eb0
+            #     the @system repo. We need to add them back in.
a58eb0
+            #   - However we need to add installed versions of just the packages that are being upgraded. We don't want
a58eb0
+            #     to add all installed packages because it could increase the number of solutions for the transaction
a58eb0
+            #     (especially without --best) and since libsolv prefers the smallest possible upgrade it could result
a58eb0
+            #     in no upgrade even if there is one available. This is a problem in general but its critical with
a58eb0
+            #     --security transactions (https://bugzilla.redhat.com/show_bug.cgi?id=2097757)
a58eb0
+            #   - We want to add only the latest versions of installed packages, this is specifically for installonly
a58eb0
+            #     packages. Otherwise if for example kernel-1 and kernel-3 were installed and present in the
a58eb0
+            #     transaction libsolv could decide to install kernel-2 because it is an upgrade for kernel-1 even
a58eb0
+            #     though we don't want it because there already is a newer version present.
a58eb0
+            query = query.union(installed_query.latest().filter(name=[pkg.name for pkg in query]))
a58eb0
             sltr = dnf.selector.Selector(self.sack)
a58eb0
             sltr.set(pkg=query)
a58eb0
             self._goal.upgrade(select=sltr)
a58eb0
-- 
a58eb0
2.36.1
a58eb0