import dnf-4.12.0-4.el9

This commit is contained in:
CentOS Sources 2022-11-15 02:02:57 -05:00 committed by Stepan Oksanichenko
parent 88f507c549
commit 57f07d2586
11 changed files with 3346 additions and 3927 deletions

View File

@ -1 +1 @@
cad8de377a20b5cf6668eb4c4150248bfaa1ed20 SOURCES/dnf-4.10.0.tar.gz
71cc8d130f8f7327f57e9b96a271a0f9a18e7e0e SOURCES/dnf-4.12.0.tar.gz

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/dnf-4.10.0.tar.gz
SOURCES/dnf-4.12.0.tar.gz

View File

@ -0,0 +1,317 @@
From 5ce5ed1ea08ad6e198c1c1642c4d9ea2db6eab86 Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Sun, 24 Apr 2022 09:08:28 +0200
Subject: [PATCH] Base.reset: plug (temporary) leak of libsolv's page file
descriptors
Consider the following call paths (mixed Python and C), extending from
livecd-creator down to libsolv:
main [livecd-tools/tools/livecd-creator]
install() [livecd-tools/imgcreate/creator.py]
fill_sack() [dnf/dnf/base.py]
_add_repo_to_sack() [dnf/dnf/base.py]
load_repo() [libdnf/python/hawkey/sack-py.cpp]
dnf_sack_load_repo() [libdnf/libdnf/dnf-sack.cpp]
write_main() [libdnf/libdnf/dnf-sack.cpp]
repo_add_solv() [libsolv/src/repo_solv.c]
repopagestore_read_or_setup_pages() [libsolv/src/repopage.c]
dup()
write_ext() [libdnf/libdnf/dnf-sack.cpp]
repo_add_solv() [libsolv/src/repo_solv.c]
repopagestore_read_or_setup_pages() [libsolv/src/repopage.c]
dup()
The dup() calls create the following file descriptors (output from
"lsof"):
> COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
> python3 6500 root 7r REG 8,1 25320727 395438 /var/tmp/imgcreate-mytcghah/install_root/var/cache/dnf/fedora.solv (deleted)
> python3 6500 root 8r REG 8,1 52531426 395450 /var/tmp/imgcreate-mytcghah/install_root/var/cache/dnf/fedora-filenames.solvx
These file descriptors are *owned* by the DnfSack object (which is derived
from GObject), as follows:
sack->priv->pool->repos[1]->repodata[1]->store.pagefd = 7
sack->priv->pool->repos[1]->repodata[2]->store.pagefd = 8
^ ^ ^ ^ ^ ^ ^
| | | | | | |
| | | | | | int
| | | | | Repopagestore [libsolv/src/repopage.h]
| | | | Repodata [libsolv/src/repodata.h]
| | | struct s_Repo [libsolv/src/repo.h]
| | struct s_Pool (aka Pool) [libsolv/src/pool.h]
| DnfSackPrivate [libdnf/libdnf/dnf-sack.cpp]
DnfSack [libdnf/libdnf/dnf-sack.h]
The file descriptors are *supposed* to be closed on the following call
path:
main [livecd-tools/tools/livecd-creator]
install() [livecd-tools/imgcreate/creator.py]
close() [livecd-tools/imgcreate/dnfinst.py]
close() [dnf/dnf/base.py]
reset() [dnf/dnf/base.py]
_sack = None
_goal = None
_transaction = None
...
dnf_sack_finalize() [libdnf/libdnf/dnf-sack.cpp]
pool_free() [libsolv/src/pool.c]
pool_freeallrepos() [libsolv/src/pool.c]
repo_freedata() [libsolv/src/repo.c]
repodata_freedata() [libsolv/src/repodata.c]
repopagestore_free() [libsolv/src/repopage.c]
close()
Namely, when dnf.Base.reset() [dnf/dnf/base.py] is called with (sack=True,
goal=True), the reference counts of the objects pointed to by the "_sack",
"_goal" and "_transaction" fields are supposed to reach zero, and then, as
part of the DnfSack object's finalization, the libsolv file descriptors
are supposed to be closed.
Now, while this *may* happen immediately in dnf.Base.reset(), it may as
well not. The reason is that there is a multitude of *circular references*
between DnfSack and the packages that it contains. When dnf.Base.reset()
is entered, we have the following picture:
_sack _goal
| |
v v
+----------------+ +-------------+
| DnfSack object | <--- | Goal object |
+----------------+ +-------------+
|^ |^ |^
|| || ||
|| || ||
+--||----||----||---+
| v| v| v| | <-- _transaction
| Pkg1 Pkg2 PkgN |
| |
| Transaction oject |
+-------------------+
That is, the reference count of the DnfSack object is (1 + 1 + N), where N
is the number of packages in the transaction. Details:
(a) The first reference comes from the "_sack" field, established like
this:
main [livecd-tools/tools/livecd-creator]
install() [livecd-tools/imgcreate/creator.py]
fill_sack() [dnf/dnf/base.py]
_build_sack() [dnf/dnf/sack.py]
Sack()
sack_init() [libdnf/python/hawkey/sack-py.cpp]
dnf_sack_new() [libdnf/libdnf/dnf-sack.cpp]
(b) The second reference on the DnfSack object comes from "_goal":
main [livecd-tools/tools/livecd-creator]
install() [livecd-tools/imgcreate/creator.py]
fill_sack() [dnf/dnf/base.py]
_goal = Goal(_sack)
goal_init() [libdnf/python/hawkey/goal-py.cpp]
Py_INCREF(_sack)
(c) Then there is one reference to "_sack" *per package* in the
transaction:
main [livecd-tools/tools/livecd-creator]
install() [livecd-tools/imgcreate/creator.py]
runInstall() [livecd-tools/imgcreate/dnfinst.py]
resolve() [dnf/dnf/base.py]
_goal2transaction() [dnf/dnf/base.py]
list_installs() [libdnf/python/hawkey/goal-py.cpp]
list_generic() [libdnf/python/hawkey/goal-py.cpp]
packagelist_to_pylist() [libdnf/python/hawkey/iutil-py.cpp]
new_package() [libdnf/python/hawkey/sack-py.cpp]
Py_BuildValue()
ts.add_install()
list_installs() creates a list of packages that need to be installed
by DNF. Inside the loop in packagelist_to_pylist(), which constructs
the elements of that list, Py_BuildValue() is called with the "O"
format specifier, and that increases the reference count on "_sack".
Subsequently, in the _goal2transaction() method, we iterate over the
package list created by list_installs(), and add each package to the
transaction (ts.add_install()). After _goal2transaction() returns,
this transaction is assigned to "self._transaction" in resolve(). This
is where the last N (back-)references on the DnfSack object come from.
(d) Now, to quote the defintion of the DnfSack object
("libdnf/docs/hawkey/tutorial-py.rst"):
> *Sack* is an abstraction for a collection of packages.
That's why the DnfSack object references all the Pkg1 through PkgN
packages.
So, when the dnf.Base.reset() method completes, the picture changes like
this:
_sack _goal
| |
-- [CUT] -- -- [CUT] --
| |
v | v
+----------------+ [C] +-------------+
| DnfSack object | <-[U]- | Goal object |
+----------------+ [T] +-------------+
|^ |^ |^ |
|| || ||
|| || || |
+--||----||----||---+ [C]
| v| v| v| | <--[U]-- _transaction
| Pkg1 Pkg2 PkgN | [T]
| | |
| Transaction oject |
+-------------------+
and we are left with N reference cycles (one between each package and the
same DnfSack object).
This set of cycles can only be cleaned up by Python's generational garbage
collector <https://stackify.com/python-garbage-collection/>. The GC will
collect the DnfSack object, and consequently close the libsolv page file
descriptors via dnf_sack_finalize() -- but garbage collection will happen
*only eventually*, unpredictably.
This means that the dnf.Base.reset() method breaks its interface contract:
> Make the Base object forget about various things.
because the libsolv file descriptors can (and frequently do, in practice)
survive dnf.Base.reset().
In general, as long as the garbage collector only tracks process-private
memory blocks, there's nothing wrong; however, file descriptors are
visible to the kernel. When dnf.Base.reset() *temporarily* leaks file
descriptors as explained above, then immediately subsequent operations
that depend on those file descriptors having been closed, can fail.
An example is livecd-creator's unmounting of:
/var/tmp/imgcreate-mytcghah/install_root/var/cache/dnf
which the kernel refuses, due to libsolv's still open file descriptors
pointing into that filesystem:
> umount: /var/tmp/imgcreate-mytcghah/install_root/var/cache/dnf: target
> is busy.
> Unable to unmount /var/tmp/imgcreate-mytcghah/install_root/var/cache/dnf
> normally, using lazy unmount
(Unfortunately, the whole lazy umount idea is misguided in livecd-tools;
it's a misfeature that should be removed, as it permits the corruption of
the loop-backed filesystem. Now that the real bug is being fixed in DNF,
lazy umount is not needed as a (broken) workaround in livecd-tools. But
that's a separate patch for livecd-tools:
<https://github.com/livecd-tools/livecd-tools/pull/227>.)
Plug the fd leak by forcing a garbage collection in dnf.Base.reset()
whenever we cut the "_sack", "_goal" and "_transaction" links -- that is,
when the "sack" and "goal" parameters are True.
Note that precisely due to the unpredictable behavior of the garbage
collector, reproducing the bug may prove elusive. In order to reproduce it
deterministically, through usage with livecd-creator, disabling automatic
garbage collection with the following patch (for livecd-tools) is
sufficient:
> diff --git a/tools/livecd-creator b/tools/livecd-creator
> index 291de10cbbf9..8d2c740c238b 100755
> --- a/tools/livecd-creator
> +++ b/tools/livecd-creator
> @@ -31,6 +31,8 @@ from dnf.exceptions import Error as DnfBaseError
> import imgcreate
> from imgcreate.errors import KickstartError
>
> +import gc
> +
> class Usage(Exception):
> def __init__(self, msg = None, no_error = False):
> Exception.__init__(self, msg, no_error)
> @@ -261,5 +263,6 @@ def do_nss_libs_hack():
> return hack
>
> if __name__ == "__main__":
> + gc.disable()
> hack = do_nss_libs_hack()
> sys.exit(main())
Also note that you need to use livecd-tools at git commit 4afde9352e82 or
later, for this fix to make any difference: said commit fixes a different
(independent) bug in livecd-tools that produces identical symptoms, but
from a different origin. In other words, if you don't have commit
4afde9352e82 in your livecd-tools install, then said bug in livecd-tools
will mask this DNF fix.
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
---
dnf/base.py | 41 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/dnf/base.py b/dnf/base.py
index caace028..520574b4 100644
--- a/dnf/base.py
+++ b/dnf/base.py
@@ -72,6 +72,7 @@ import dnf.transaction
import dnf.util
import dnf.yum.rpmtrans
import functools
+import gc
import hawkey
import itertools
import logging
@@ -569,6 +570,46 @@ class Base(object):
self._comps_trans = dnf.comps.TransactionBunch()
self._transaction = None
self._update_security_filters = []
+ if sack and goal:
+ # We've just done this, above:
+ #
+ # _sack _goal
+ # | |
+ # -- [CUT] -- -- [CUT] --
+ # | |
+ # v | v
+ # +----------------+ [C] +-------------+
+ # | DnfSack object | <-[U]- | Goal object |
+ # +----------------+ [T] +-------------+
+ # |^ |^ |^ |
+ # || || ||
+ # || || || |
+ # +--||----||----||---+ [C]
+ # | v| v| v| | <--[U]-- _transaction
+ # | Pkg1 Pkg2 PkgN | [T]
+ # | | |
+ # | Transaction oject |
+ # +-------------------+
+ #
+ # At this point, the DnfSack object would be released only
+ # eventually, by Python's generational garbage collector, due to the
+ # cyclic references DnfSack<->Pkg1 ... DnfSack<->PkgN.
+ #
+ # The delayed release is a problem: the DnfSack object may
+ # (indirectly) own "page file" file descriptors in libsolv, via
+ # libdnf. For example,
+ #
+ # sack->priv->pool->repos[1]->repodata[1]->store.pagefd = 7
+ # sack->priv->pool->repos[1]->repodata[2]->store.pagefd = 8
+ #
+ # These file descriptors are closed when the DnfSack object is
+ # eventually released, that is, when dnf_sack_finalize() (in libdnf)
+ # calls pool_free() (in libsolv).
+ #
+ # We need that to happen right now, as callers may want to unmount
+ # the filesystems which those file descriptors refer to immediately
+ # after reset() returns. Therefore, force a garbage collection here.
+ gc.collect()
def _closeRpmDB(self):
"""Closes down the instances of rpmdb that could be open."""
--
2.35.1

View File

@ -1,29 +0,0 @@
From 39e759ae6afb046cf6d60fb91b3ee208cb150a2f Mon Sep 17 00:00:00 2001
From: Jaroslav Mracek <jmracek@redhat.com>
Date: Mon, 6 Sep 2021 12:40:59 +0200
Subject: [PATCH] [doc] Improve description of multilib_policy=all (RhBug:1996681,1995630)
https://bugzilla.redhat.com/show_bug.cgi?id=1996681
https://bugzilla.redhat.com/show_bug.cgi?id=1995630
---
doc/conf_ref.rst | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/doc/conf_ref.rst b/doc/conf_ref.rst
index fa310e3..60afc86 100644
--- a/doc/conf_ref.rst
+++ b/doc/conf_ref.rst
@@ -403,7 +403,9 @@ configuration file by your distribution to override the DNF defaults.
``multilib_policy``
:ref:`string <string-label>`
- Controls how multilib packages are treated during install operations. Can either be ``"best"`` (the default) for the depsolver to prefer packages which best match the system's architecture, or ``"all"`` to install all available packages with compatible architectures.
+ Controls how multilib packages are treated during install operations. Can either be ``"best"`` (the default) for
+ the depsolver to prefer packages which best match the system's architecture, or ``"all"`` to install packages for
+ all available architectures.
.. _obsoletes_conf_option-label:
--
libgit2 1.1.0

View File

@ -0,0 +1,64 @@
From f32eff294aecaac0fd71cd8888a25fa7929460b9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= <amatej@redhat.com>
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 <inline>
#>=Pkg: A 1 1 x86_64
#>=Pkg: B 1 1 x86_64
#>=Req: A = 1-1
repo available 0 testtags <inline>
#>=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

View File

@ -1,33 +0,0 @@
From 9ce65d8575494887a08506583d9d4f05df404fac Mon Sep 17 00:00:00 2001
From: Jaroslav Rohel <jrohel@redhat.com>
Date: Wed, 20 Oct 2021 09:20:03 +0200
Subject: [PATCH] Fix: Python dnf API does not respect cacheonly (RhBug:1862970)
`Repo` object has always been constructed with default synchronization
strategy. The configuration option `cacheonly` was ignored. DNF
application set synchronization strategy later in the `Cli` object
during processing demands.
The fix takes into account the `cacheonly` option during the construction
of the `Repo` object. Synchronization strategy may still be overriden
during demand processing.
---
dnf/repo.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dnf/repo.py b/dnf/repo.py
index bb42230..1822cf0 100644
--- a/dnf/repo.py
+++ b/dnf/repo.py
@@ -434,7 +434,7 @@ class Repo(dnf.conf.RepoConf):
self._pkgdir = None
self._key_import = _NullKeyImport()
self.metadata = None # :api
- self._repo.setSyncStrategy(self.DEFAULT_SYNC)
+ self._repo.setSyncStrategy(SYNC_ONLY_CACHE if parent_conf and parent_conf.cacheonly else self.DEFAULT_SYNC)
if parent_conf:
self._repo.setSubstitutions(parent_conf.substitutions)
self._substitutions = dnf.conf.substitutions.Substitutions()
--
libgit2 1.1.0

View File

@ -1,26 +0,0 @@
From 5c598df3541c21d5c2758c42bd2eb0df8c74eddc Mon Sep 17 00:00:00 2001
From: Jaroslav Rohel <jrohel@redhat.com>
Date: Fri, 5 Nov 2021 08:52:56 +0100
Subject: [PATCH] Documentation: API notes for cacheonly
---
doc/conf_ref.rst | 3 +++
1 file changed, 3 insertions(+)
diff --git a/doc/conf_ref.rst b/doc/conf_ref.rst
index 60afc86..1a593a1 100644
--- a/doc/conf_ref.rst
+++ b/doc/conf_ref.rst
@@ -137,6 +137,9 @@ configuration file by your distribution to override the DNF defaults.
If set to ``True`` DNF will run entirely from system cache, will not update
the cache and will use it even in case it is expired. Default is ``False``.
+ API Notes: Must be set before repository objects are created. Plugins must set
+ this in the pre_config hook. Later changes are ignored.
+
.. _check_config_file_age-label:
``check_config_file_age``
--
libgit2 1.1.0

View File

@ -0,0 +1,37 @@
From 776241568cb10e3a671c574b25e06b63d86e7ac0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= <amatej@redhat.com>
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

View File

@ -1,169 +0,0 @@
From 087ad3d12ba307355dd66aba54faea97d227a3dd Mon Sep 17 00:00:00 2001
From: zhanghaolian <65838930+iWhy98@users.noreply.github.com>
Date: Tue, 25 Jan 2022 15:41:16 +0800
Subject: [PATCH 1/2] dnf:fix dnf mark error when history sqlite missing
---
dnf/cli/commands/mark.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dnf/cli/commands/mark.py b/dnf/cli/commands/mark.py
index ec16b738d..cb1f91c13 100644
--- a/dnf/cli/commands/mark.py
+++ b/dnf/cli/commands/mark.py
@@ -89,7 +89,7 @@ class MarkCommand(commands.Command):
old = self.base.history.last()
if old is None:
- rpmdb_version = self.sack._rpmdb_version()
+ rpmdb_version = self.base.sack._rpmdb_version()
else:
rpmdb_version = old.end_rpmdb_version
--
2.34.1
From bee5b97ad159af019deda4de0d80d0011dba4f7a Mon Sep 17 00:00:00 2001
From: Jaroslav Rohel <jrohel@redhat.com>
Date: Fri, 28 Jan 2022 16:53:50 +0100
Subject: [PATCH 2/2] Use rpm.TransactionSet.dbCookie() to determining if rpmdb
has changed
DNF was using private method `hawkey.Sack._rpmdb_version()` from libdnf.
The method computes SHA1 hash from sorted list of hashes stored in
the headers of the instaled packages. And it adds prefix of the number
of installed packages to the computed hash. The result was stored
to the history database and used to detect changes in the rpm database.
The patch uses new oficial librpm API function
`rpm.TransactionSet.dbCookie()`. This is a cleaner solution.
It is also a step to remove the `._rpmdb_version()` method from libdnf.
It is an attempt to remove SHA1 calculations from libdnf.
Troubleshooting FIPS compatibility.
= changelog =
msg: Use rpm.TransactionSet.dbCookie() to determining if rpmdb has changed
type: bugfix
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2043476
---
dnf/base.py | 6 +++---
dnf/cli/commands/mark.py | 2 +-
dnf/cli/output.py | 2 +-
dnf/rpm/transaction.py | 16 ++++++++++++++++
tests/test_sack.py | 6 ------
5 files changed, 21 insertions(+), 11 deletions(-)
diff --git a/dnf/base.py b/dnf/base.py
index b0a536f7f..574e80f66 100644
--- a/dnf/base.py
+++ b/dnf/base.py
@@ -907,7 +907,7 @@ class Base(object):
cmdline = ' '.join(self.cmds)
old = self.history.last()
if old is None:
- rpmdb_version = self.sack._rpmdb_version()
+ rpmdb_version = self._ts.dbCookie()
else:
rpmdb_version = old.end_rpmdb_version
@@ -1046,7 +1046,7 @@ class Base(object):
using_pkgs_pats = list(self.conf.history_record_packages)
installed_query = self.sack.query().installed()
using_pkgs = installed_query.filter(name=using_pkgs_pats).run()
- rpmdbv = self.sack._rpmdb_version()
+ rpmdbv = self._ts.dbCookie()
lastdbv = self.history.last()
if lastdbv is not None:
lastdbv = lastdbv.end_rpmdb_version
@@ -1163,7 +1163,7 @@ class Base(object):
for tsi in transaction_items:
count = display_banner(tsi.pkg, count)
- rpmdbv = rpmdb_sack._rpmdb_version()
+ rpmdbv = self._ts.dbCookie()
self.history.end(rpmdbv)
timer()
diff --git a/dnf/cli/commands/mark.py b/dnf/cli/commands/mark.py
index cb1f91c13..36bf9d436 100644
--- a/dnf/cli/commands/mark.py
+++ b/dnf/cli/commands/mark.py
@@ -89,7 +89,7 @@ class MarkCommand(commands.Command):
old = self.base.history.last()
if old is None:
- rpmdb_version = self.base.sack._rpmdb_version()
+ rpmdb_version = self.base._ts.dbCookie()
else:
rpmdb_version = old.end_rpmdb_version
diff --git a/dnf/cli/output.py b/dnf/cli/output.py
index a4e9f6c8e..ecf05c2b0 100644
--- a/dnf/cli/output.py
+++ b/dnf/cli/output.py
@@ -1607,7 +1607,7 @@ Transaction Summary
if lastdbv is not None and trans.tid == lasttid:
# If this is the last transaction, is good and it doesn't
# match the current rpmdb ... then mark it as bad.
- rpmdbv = self.sack._rpmdb_version()
+ rpmdbv = self.base._ts.dbCookie()
trans.compare_rpmdbv(str(rpmdbv))
lastdbv = None
diff --git a/dnf/rpm/transaction.py b/dnf/rpm/transaction.py
index bcc2a7024..a11f36e7e 100644
--- a/dnf/rpm/transaction.py
+++ b/dnf/rpm/transaction.py
@@ -12,8 +12,10 @@
from __future__ import absolute_import
from __future__ import unicode_literals
from dnf.i18n import _
+import logging
import rpm
+_logger = logging.getLogger('dnf')
read_ts = None
ts = None
@@ -61,6 +63,20 @@ class TransactionWrapper(object):
mi.pattern(tag, tp, pat)
return mi
+ def dbCookie(self):
+ # dbCookie() does not support lazy opening of rpm database.
+ # The following line opens the database if it is not already open.
+ if self.ts.openDB() != 0:
+ _logger.error(_('The openDB() function connot open rpm database.'))
+ return ''
+
+ cookie = self.ts.dbCookie()
+ if not cookie:
+ _logger.error(_('The dbCookie() function did not return cookie of rpm database.'))
+ return ''
+
+ return cookie
+
def __getattr__(self, attr):
if attr in self._methods:
return self.getMethod(attr)
diff --git a/tests/test_sack.py b/tests/test_sack.py
index 49a715924..2c6fe8e01 100644
--- a/tests/test_sack.py
+++ b/tests/test_sack.py
@@ -32,12 +32,6 @@ class SackTest(tests.support.DnfBaseTestCase):
REPOS = []
- def test_rpmdb_version(self):
- version = self.sack._rpmdb_version()
- self.assertIsNotNone(version)
- expected = "%s:%s" % (tests.support.TOTAL_RPMDB_COUNT, tests.support.RPMDB_CHECKSUM)
- self.assertEqual(version, expected)
-
def test_excludepkgs(self):
self.base.conf.excludepkgs = ['pepper']
self.base._setup_excludes_includes()
--
2.34.1

View File

@ -2,7 +2,7 @@
%define __cmake_in_source_build 1
# default dependencies
%global hawkey_version 0.65.0
%global hawkey_version 0.66.0
%global libcomps_version 0.1.8
%global libmodulemd_version 2.9.3
%global rpm_version 4.14.0
@ -65,19 +65,20 @@
It supports RPMs, modules and comps groups & environments.
Name: dnf
Version: 4.10.0
Release: 5%{?dist}
Version: 4.12.0
Release: 4%{?dist}
Summary: %{pkg_summary}
# For a breakdown of the licensing, see PACKAGE-LICENSING
License: GPLv2+
URL: https://github.com/rpm-software-management/dnf
Source0: %{url}/archive/%{version}/%{name}-%{version}.tar.gz
Patch1: 0001-doc-Improve-description-of-multilib_policyall-RhBug19966811995630.patch
Patch2: 0002-Fix-Python-dnf-API-does-not-respect-cacheonly-RhBug1862970.patch
Patch3: 0003-Documentation-API-notes-for-cacheonly.patch
Patch4: 0004-Use-rpm.TransactionSet.dbCookie-to-determining-if-rp.patch
Patch5: 0005-Update-translations-RhBug-2017347.patch
# Upstream commit which fixes leak of libsolv's page file descriptors.
# https://github.com/rpm-software-management/dnf/commit/5ce5ed1ea08ad6e198c1c1642c4d9ea2db6eab86
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
Patch0004: 0004-Update-translations-RHEL-9.1.patch
BuildArch: noarch
BuildRequires: cmake
BuildRequires: gettext
@ -257,22 +258,13 @@ popd
%post automatic
%systemd_post dnf-automatic.timer
%systemd_post dnf-automatic-notifyonly.timer
%systemd_post dnf-automatic-download.timer
%systemd_post dnf-automatic-install.timer
%systemd_post dnf-automatic.timer dnf-automatic-notifyonly.timer dnf-automatic-download.timer dnf-automatic-install.timer
%preun automatic
%systemd_preun dnf-automatic.timer
%systemd_preun dnf-automatic-notifyonly.timer
%systemd_preun dnf-automatic-download.timer
%systemd_preun dnf-automatic-install.timer
%systemd_preun dnf-automatic.timer dnf-automatic-notifyonly.timer dnf-automatic-download.timer dnf-automatic-install.timer
%postun automatic
%systemd_postun_with_restart dnf-automatic.timer
%systemd_postun_with_restart dnf-automatic-notifyonly.timer
%systemd_postun_with_restart dnf-automatic-download.timer
%systemd_postun_with_restart dnf-automatic-install.timer
%systemd_postun_with_restart dnf-automatic.timer dnf-automatic-notifyonly.timer dnf-automatic-download.timer dnf-automatic-install.timer
%files -f %{name}.lang
@ -375,9 +367,36 @@ popd
%{python3_sitelib}/%{name}/automatic/
%changelog
* Mon Mar 21 2022 Marek Blaha <mblaha@redhat.com> - 4.10.0-5
* Thu Sep 15 2022 Marek Blaha <mblaha@redhat.com> - 4.12.0-4
- Update translations
* Tue Jul 19 2022 Lukas Hrazky <lhrazky@redhat.com> - 4.12.0-3
- Add only relevant pkgs to upgrade transaction (RhBug:2097757)
* Thu Apr 28 2022 Richard W.M. Jones <rjones@redhat.com> - 4.12.0-2
- Backport fix for leak of libsolv's page file descriptors
* Thu Apr 28 2022 Pavla Kratochvilova <pkratoch@redhat.com> - 4.12.0-1
- Allow destdir option with modulesync command
- Add documentation for query api flags (RhBug:2035577)
- Fix swap command to work with local rpm files correctly (RhBug:2036434)
- Fix regression in verifying signatures using rpmkeys
- Fix decompression of groups.xml (RhBug:2030255)
- Fix history undo on a Reason Change (RhBug:2010259,2053014)
- Remove /usr/bin from sys.path to avoid accidentally importing garbage
- Fix python3.11 build: remove deprecated, update traceback regex
- fix dnf mark error when history sqlite missing
- [doc] clarify effect of --enablerepo and --disablerepo options (RhBug:2031414)
- [doc] default values for module_obsoletes and module_stream_switch (RhBug: 2051846)
- dnf.conf: hint users where to find more info about defaults and other options
- Fix unittests that relied on checksum being at the end of solvfiles
- completion: remove unnecessary echo
- Fix remove when no repos are enabled (RhBug:2064341)
- Add loongarch support for dnf
- Add spaces between words to fix typos (RhBug:2077296)
- [doc] Improve "proxy" configuration option documentation (RhBug:2072332)
- Fix download errors handling in non-english locales (RhBug:2024527)
* Mon Feb 07 2022 Pavla Kratochvilova <pkratoch@redhat.com> - 4.10.0-4
- Use rpm.TransactionSet.dbCookie() to determining if rpmdb has changed (RhBug:2043476)