Merge branch 'c9-beta' into a9-beta

This commit is contained in:
eabdullin 2023-09-27 15:58:31 +03:00
commit 8c242d8b9e
17 changed files with 8248 additions and 435 deletions

View File

@ -1 +1 @@
71cc8d130f8f7327f57e9b96a271a0f9a18e7e0e SOURCES/dnf-4.12.0.tar.gz 0697aee277730c57446b5b87bdb12456cf245203 SOURCES/dnf-4.14.0.tar.gz

2
.gitignore vendored
View File

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

View File

@ -1,317 +0,0 @@
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

@ -0,0 +1,62 @@
From 5e082d74b73bf1b3565cfd72a3e1ba7a45a00a8b 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, 7 Sep 2022 14:40:32 +0200
Subject: [PATCH 1/2] Pass whole URL in relativeUrl to PackageTarget for RPM
URL download
The PackageTarget supports baseUrl and relativeUrl on the API, but then
the relativeUrl is just a path fragment with no definition on whether it
should be encoded. It's being passed unencoded paths from other places,
and so there's a conditional encode (only if not full URL) in libdnf.
But full URLs are actually supported in relativeUrl (in that case
baseUrl should be empty) and in that case the URL is expected to be
encoded and is not encoded for the second time.
Hence, pass the full URL to relativeUrl instead of splitting it. We also
need to decode the file name we store, as on the filesystem the RPM file
name is also decoded.
= changelog =
msg: Don't double-encode RPM URLs passed on CLI
type: bugfix
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2103015
---
dnf/repo.py | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/dnf/repo.py b/dnf/repo.py
index ec1a2537..86fb2bf4 100644
--- a/dnf/repo.py
+++ b/dnf/repo.py
@@ -47,6 +47,7 @@ import string
import sys
import time
import traceback
+import urllib
_PACKAGES_RELATIVE_DIR = "packages"
_MIRRORLIST_FILENAME = "mirrorlist"
@@ -295,7 +296,7 @@ class RemoteRPMPayload(PackagePayload):
self.local_path = os.path.join(self.pkgdir, self.__str__().lstrip("/"))
def __str__(self):
- return os.path.basename(self.remote_location)
+ return os.path.basename(urllib.parse.unquote(self.remote_location))
def _progress_cb(self, cbdata, total, done):
self.remote_size = total
@@ -308,8 +309,8 @@ class RemoteRPMPayload(PackagePayload):
def _librepo_target(self):
return libdnf.repo.PackageTarget(
- self.conf._config, os.path.basename(self.remote_location),
- self.pkgdir, 0, None, 0, os.path.dirname(self.remote_location),
+ self.conf._config, self.remote_location,
+ self.pkgdir, 0, None, 0, None,
True, 0, 0, self.callbacks)
@property
--
2.37.3

View File

@ -1,64 +0,0 @@
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

@ -0,0 +1,96 @@
From a41c3aefaa4f982511363645f5608e270094cadf Mon Sep 17 00:00:00 2001
From: Jan Kolarik <jkolarik@redhat.com>
Date: Tue, 1 Nov 2022 09:15:08 +0000
Subject: [PATCH 2/2] Document changes to offline-upgrade command
(RhBug:1939975)
A support for security filters was added to the offline-upgrade command. This commit adds the documentation into the man pages.
= changelog =
type: bugfix
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1939975
---
doc/command_ref.rst | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/doc/command_ref.rst b/doc/command_ref.rst
index f39f2c71..3ee66bac 100644
--- a/doc/command_ref.rst
+++ b/doc/command_ref.rst
@@ -114,7 +114,7 @@ Options
``--advisory=<advisory>, --advisories=<advisory>``
Include packages corresponding to the advisory ID, Eg. FEDORA-2201-123.
- Applicable for the install, repoquery, updateinfo and upgrade commands.
+ Applicable for the ``install``, ``repoquery``, ``updateinfo``, ``upgrade`` and ``offline-upgrade`` (dnf-plugins-core) commands.
``--allowerasing``
Allow erasing of installed packages to resolve dependencies. This option could be used as an alternative to the ``yum swap`` command where packages to remove are not explicitly defined.
@@ -130,12 +130,12 @@ Options
solver may use older versions of dependencies to meet their requirements.
``--bugfix``
- Include packages that fix a bugfix issue. Applicable for the install, repoquery, updateinfo and
- upgrade commands.
+ Include packages that fix a bugfix issue.
+ Applicable for the ``install``, ``repoquery``, ``updateinfo``, ``upgrade`` and ``offline-upgrade`` (dnf-plugins-core) commands.
``--bz=<bugzilla>, --bzs=<bugzilla>``
- Include packages that fix a Bugzilla ID, Eg. 123123. Applicable for the install, repoquery,
- updateinfo and upgrade commands.
+ Include packages that fix a Bugzilla ID, Eg. 123123.
+ Applicable for the ``install``, ``repoquery``, ``updateinfo``, ``upgrade`` and ``offline-upgrade`` (dnf-plugins-core) commands.
``-C, --cacheonly``
Run entirely from system cache, don't update the cache and use it even in case it is expired.
@@ -153,8 +153,8 @@ Options
``--cve=<cves>, --cves=<cves>``
Include packages that fix a CVE (Common Vulnerabilities and Exposures) ID
- (http://cve.mitre.org/about/), Eg. CVE-2201-0123. Applicable for the install, repoquery, updateinfo,
- and upgrade commands.
+ (http://cve.mitre.org/about/), Eg. CVE-2201-0123.
+ Applicable for the ``install``, ``repoquery``, ``updateinfo``, ``upgrade`` and ``offline-upgrade`` (dnf-plugins-core) commands.
``-d <debug level>, --debuglevel=<debug level>``
Debugging output level. This is an integer value between 0 (no additional information strings) and 10 (shows all debugging information, even that not understandable to the user), default is 2. Deprecated, use ``-v`` instead.
@@ -217,8 +217,8 @@ Options
specified multiple times.
``--enhancement``
- Include enhancement relevant packages. Applicable for the install, repoquery, updateinfo and
- upgrade commands.
+ Include enhancement relevant packages.
+ Applicable for the ``install``, ``repoquery``, ``updateinfo``, ``upgrade`` and ``offline-upgrade`` (dnf-plugins-core) commands.
.. _exclude_option-label:
@@ -289,8 +289,8 @@ Options
``--setopt`` using configuration from ``/path/dnf.conf``.
``--newpackage``
- Include newpackage relevant packages. Applicable for the install, repoquery, updateinfo and
- upgrade commands.
+ Include newpackage relevant packages.
+ Applicable for the ``install``, ``repoquery``, ``updateinfo``, ``upgrade`` and ``offline-upgrade`` (dnf-plugins-core) commands.
``--noautoremove``
Disable removal of dependencies that are no longer used. It sets
@@ -362,11 +362,11 @@ Options
``--sec-severity=<severity>, --secseverity=<severity>``
Includes packages that provide a fix for an issue of the specified severity.
- Applicable for the install, repoquery, updateinfo and upgrade commands.
+ Applicable for the ``install``, ``repoquery``, ``updateinfo``, ``upgrade`` and ``offline-upgrade`` (dnf-plugins-core) commands.
``--security``
- Includes packages that provide a fix for a security issue. Applicable for the
- upgrade command.
+ Includes packages that provide a fix for a security issue.
+ Applicable for the ``install``, ``repoquery``, ``updateinfo``, ``upgrade`` and ``offline-upgrade`` (dnf-plugins-core) commands.
.. _setopt_option-label:
--
2.38.1

View File

@ -0,0 +1,31 @@
From e5732ab22f092bb3fc6ce6e8f94aad72f3654383 Mon Sep 17 00:00:00 2001
From: Jan Kolarik <jkolarik@redhat.com>
Date: Wed, 31 Aug 2022 07:49:39 +0200
Subject: [PATCH 1/2] Move system-upgrade plugin to core (RhBug:2054235)
Just doc fix.
= changelog =
type: bugfix
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2054235
---
doc/command_ref.rst | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/doc/command_ref.rst b/doc/command_ref.rst
index 996ae3b4..f39f2c71 100644
--- a/doc/command_ref.rst
+++ b/doc/command_ref.rst
@@ -189,8 +189,7 @@ Options
``--downloaddir=<path>, --destdir=<path>``
Redirect downloaded packages to provided directory. The option has to be used together with the \-\
:ref:`-downloadonly <downloadonly-label>` command line option, with the
- ``download``, ``modulesync`` or ``reposync`` commands (dnf-plugins-core) or with the ``system-upgrade`` command
- (dnf-plugins-extras).
+ ``download``, ``modulesync``, ``reposync`` or ``system-upgrade`` commands (dnf-plugins-core).
.. _downloadonly-label:
--
2.38.1

View File

@ -1,37 +0,0 @@
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

@ -0,0 +1,94 @@
From 3ef5ec915ea4b5e6fe7d25542f0daccef278c01e Mon Sep 17 00:00:00 2001
From: Jan Kolarik <jkolarik@redhat.com>
Date: Tue, 13 Sep 2022 14:35:10 +0200
Subject: [PATCH] Fix plugins unit tests + unload plugins upon their deletion
---
dnf/plugin.py | 8 ++++++--
tests/api/test_dnf_base.py | 24 +++++++++++++++++++-----
2 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/dnf/plugin.py b/dnf/plugin.py
index b083727d..d2f46ce3 100644
--- a/dnf/plugin.py
+++ b/dnf/plugin.py
@@ -98,6 +98,9 @@ class Plugins(object):
self.plugin_cls = []
self.plugins = []
+ def __del__(self):
+ self._unload()
+
def _caller(self, method):
for plugin in self.plugins:
try:
@@ -164,8 +167,9 @@ class Plugins(object):
self._caller('transaction')
def _unload(self):
- logger.debug(_('Plugins were unloaded'))
- del sys.modules[DYNAMIC_PACKAGE]
+ if DYNAMIC_PACKAGE in sys.modules:
+ logger.log(dnf.logging.DDEBUG, 'Plugins were unloaded.')
+ del sys.modules[DYNAMIC_PACKAGE]
def unload_removed_plugins(self, transaction):
"""
diff --git a/tests/api/test_dnf_base.py b/tests/api/test_dnf_base.py
index e84e272b..19754b07 100644
--- a/tests/api/test_dnf_base.py
+++ b/tests/api/test_dnf_base.py
@@ -7,10 +7,23 @@ from __future__ import unicode_literals
import dnf
import dnf.conf
+import tests.support
+
from .common import TestCase
from .common import TOUR_4_4
+def conf_with_empty_plugins():
+ """
+ Use empty configuration to avoid importing plugins from default paths
+ which would lead to crash of other tests.
+ """
+ conf = tests.support.FakeConf()
+ conf.plugins = True
+ conf.pluginpath = []
+ return conf
+
+
class DnfBaseApiTest(TestCase):
def setUp(self):
self.base = dnf.Base(dnf.conf.Conf())
@@ -75,13 +88,12 @@ class DnfBaseApiTest(TestCase):
self.assertHasType(self.base.transaction, dnf.db.group.RPMTransaction)
def test_init_plugins(self):
- # Base.init_plugins(disabled_glob=(), enable_plugins=(), cli=None)
+ # Base.init_plugins()
self.assertHasAttr(self.base, "init_plugins")
- # disable plugins to avoid calling dnf.plugin.Plugins._load() multiple times
- # which causes the tests to crash
- self.base.conf.plugins = False
- self.base.init_plugins(disabled_glob=(), enable_plugins=(), cli=None)
+ self.base._conf = conf_with_empty_plugins()
+
+ self.base.init_plugins()
def test_pre_configure_plugins(self):
# Base.pre_configure_plugins()
@@ -99,6 +111,8 @@ class DnfBaseApiTest(TestCase):
# Base.unload_plugins()
self.assertHasAttr(self.base, "unload_plugins")
+ self.base._conf = conf_with_empty_plugins()
+
self.base.init_plugins()
self.base.unload_plugins()
--
2.38.1

View File

@ -0,0 +1,50 @@
From 490cf87dd27926d16fb10735b467cbc490d5c9f1 Mon Sep 17 00:00:00 2001
From: Jan Kolarik <jkolarik@redhat.com>
Date: Wed, 23 Nov 2022 08:44:41 +0000
Subject: [PATCH] Ignore processing variable files with unsupported encoding
(RhBug:2141215)
This issue could be seen for example when there are some temporary files stored by text editors in the `/etc/dnf/vars` folder. These files could be in the binary format and causes `UnicodeDecodeError` exception to be thrown during processing of the var files.
= changelog =
type: bugfix
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2141215
---
dnf/conf/substitutions.py | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/dnf/conf/substitutions.py b/dnf/conf/substitutions.py
index 1281bdf0..4d0f0d55 100644
--- a/dnf/conf/substitutions.py
+++ b/dnf/conf/substitutions.py
@@ -18,13 +18,15 @@
# Red Hat, Inc.
#
+import logging
import os
import re
-import dnf
-import dnf.exceptions
+from dnf.i18n import _
ENVIRONMENT_VARS_RE = re.compile(r'^DNF_VAR_[A-Za-z0-9_]+$')
+logger = logging.getLogger('dnf')
+
class Substitutions(dict):
# :api
@@ -60,7 +62,8 @@ class Substitutions(dict):
val = fp.readline()
if val and val[-1] == '\n':
val = val[:-1]
- except (OSError, IOError):
+ except (OSError, IOError, UnicodeDecodeError) as e:
+ logger.warning(_("Error when parsing a variable from file '{0}': {1}").format(filepath, e))
continue
if val is not None:
self[fsvar] = val
--
2.39.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,252 @@
From 56d3e10ecb666da53a77d17e9ac7524f3e1341d8 Mon Sep 17 00:00:00 2001
From: Evan Goode <mail@evangoo.de>
Date: Tue, 24 Jan 2023 09:53:47 -0500
Subject: [PATCH 1/4] Add reboot option to DNF Automatic (RhBug:2124793)
Add ability in DNF Automatic to automatically trigger a reboot after an
upgrade. The `reboot` option supports three settings: ``never`` does not
reboot the system (current behavior). ``when-changed`` triggers a reboot
after any upgrade. ``when-needed`` triggers a reboot only when rebooting
is necessary to apply changes, such as when systemd or the kernel is
upgraded. The `reboot_command` option allows customizing the command
used to reboot (default is `shutdown -r`).
= changelog =
msg: Add `reboot` option to DNF Automatic
type: enhancement
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2124793
---
dnf/automatic/main.py | 9 +++++++++
dnf/base.py | 14 ++++++++++++++
doc/automatic.rst | 12 ++++++++++++
etc/dnf/automatic.conf | 9 +++++++++
tests/automatic/test_main.py | 4 ++++
5 files changed, 48 insertions(+)
diff --git a/dnf/automatic/main.py b/dnf/automatic/main.py
index b53d9c00..b68962c2 100644
--- a/dnf/automatic/main.py
+++ b/dnf/automatic/main.py
@@ -24,6 +24,7 @@ from __future__ import unicode_literals
import argparse
import logging
+import os
import random
import socket
import time
@@ -179,6 +180,9 @@ class CommandsConfig(Config):
libdnf.conf.VectorString(['default', 'security'])))
self.add_option('random_sleep', libdnf.conf.OptionNumberInt32(300))
self.add_option('network_online_timeout', libdnf.conf.OptionNumberInt32(60))
+ self.add_option('reboot', libdnf.conf.OptionEnumString('never',
+ libdnf.conf.VectorString(['never', 'when-changed', 'when-needed'])))
+ self.add_option('reboot_command', libdnf.conf.OptionString('shutdown -r'))
def imply(self):
if self.apply_updates:
@@ -340,6 +344,11 @@ def main(args):
base.do_transaction()
emitters.notify_applied()
emitters.commit()
+
+ if (conf.commands.reboot == 'when-changed' or
+ (conf.commands.reboot == 'when-needed' and base.reboot_needed())):
+ if os.waitstatus_to_exitcode(os.system(conf.commands.reboot_command)) != 0:
+ return 1
except dnf.exceptions.Error as exc:
logger.error(_('Error: %s'), ucd(exc))
return 1
diff --git a/dnf/base.py b/dnf/base.py
index 154eb4e3..24c5a444 100644
--- a/dnf/base.py
+++ b/dnf/base.py
@@ -2790,6 +2790,20 @@ class Base(object):
return skipped_conflicts, skipped_dependency
+ def reboot_needed(self):
+ """Check whether a system reboot is recommended following the transaction
+
+ :return: bool
+ """
+ if not self.transaction:
+ return False
+
+ # List taken from DNF needs-restarting
+ need_reboot = frozenset(('kernel', 'kernel-rt', 'glibc',
+ 'linux-firmware', 'systemd', 'dbus',
+ 'dbus-broker', 'dbus-daemon'))
+ changed_pkgs = self.transaction.install_set | self.transaction.remove_set
+ return any(pkg.name in need_reboot for pkg in changed_pkgs)
def _msg_installed(pkg):
name = ucd(pkg)
diff --git a/doc/automatic.rst b/doc/automatic.rst
index b8e47ad1..ade0ca1a 100644
--- a/doc/automatic.rst
+++ b/doc/automatic.rst
@@ -90,6 +90,18 @@ Setting the mode of operation of the program.
What kind of upgrades to look at. ``default`` signals looking for all available updates, ``security`` only those with an issued security advisory.
+``reboot``
+ either one of ``never``, ``when-changed``, ``when-needed``, default: ``never``
+
+ When the system should reboot following upgrades. ``never`` does not reboot the system. ``when-changed`` triggers a reboot after any upgrade. ``when-needed`` triggers a reboot only when rebooting is necessary to apply changes, such as when systemd or the kernel is upgraded.
+
+``reboot_command``
+ string, default: ``shutdown -r``
+
+ Specify the command to run to trigger a reboot of the system. For example, add a 5-minute delay and a wall message by using ``shutdown -r +5 'Rebooting after upgrading packages'``
+
+
+
----------------------
``[emitters]`` section
----------------------
diff --git a/etc/dnf/automatic.conf b/etc/dnf/automatic.conf
index 1f7e9402..9735447f 100644
--- a/etc/dnf/automatic.conf
+++ b/etc/dnf/automatic.conf
@@ -21,6 +21,15 @@ download_updates = yes
# install.timer override this setting.
apply_updates = no
+# When the system should reboot following upgrades:
+# never = don't reboot after upgrades
+# when-changed = reboot after any changes
+# when-needed = reboot when necessary to apply changes
+reboot = never
+
+# The command that is run to trigger a system reboot.
+reboot_command = "shutdown -r"
+
[emitters]
# Name to use for this system in messages that are emitted. Default is the
diff --git a/tests/automatic/test_main.py b/tests/automatic/test_main.py
index 27ffa407..dc4acd52 100644
--- a/tests/automatic/test_main.py
+++ b/tests/automatic/test_main.py
@@ -49,3 +49,7 @@ class TestConfig(tests.support.TestCase):
conf = dnf.automatic.main.AutomaticConfig(FILE, downloadupdates=True, installupdates=False)
self.assertTrue(conf.commands.download_updates)
self.assertFalse(conf.commands.apply_updates)
+
+ # test that reboot is "never" by default
+ conf = dnf.automatic.main.AutomaticConfig(FILE)
+ self.assertEqual(conf.commands.reboot, 'never')
--
2.40.0
From 8d7608f3462deddf36d5a75ff66f847a30b78026 Mon Sep 17 00:00:00 2001
From: Evan Goode <mail@evangoo.de>
Date: Tue, 24 Jan 2023 09:59:22 -0500
Subject: [PATCH 2/4] Add Evan Goode to AUTHORS
---
AUTHORS | 1 +
1 file changed, 1 insertion(+)
diff --git a/AUTHORS b/AUTHORS
index 50bff95b..e802a51e 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -69,6 +69,7 @@ DNF CONTRIBUTORS
Dave Johansen <davejohansen@gmail.com>
Dylan Pindur <dylanpindur@gmail.com>
Eduard Cuba <ecuba@redhat.com>
+ Evan Goode <egoode@redhat.com>
Filipe Brandenburger <filbranden@gmail.com>
Frank Dana <ferdnyc@gmail.com>
George Machitidze <giomac@gmail.com>
--
2.40.0
From 9deed331cb7a1890e1f11a57c989c300b1641a88 Mon Sep 17 00:00:00 2001
From: Evan Goode <mail@evangoo.de>
Date: Tue, 24 Jan 2023 17:12:46 -0500
Subject: [PATCH 3/4] DNF Automatic reboot: 5-minute delay and wall by default
---
dnf/automatic/main.py | 2 +-
doc/automatic.rst | 4 ++--
etc/dnf/automatic.conf | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/dnf/automatic/main.py b/dnf/automatic/main.py
index b68962c2..a03c359f 100644
--- a/dnf/automatic/main.py
+++ b/dnf/automatic/main.py
@@ -182,7 +182,7 @@ class CommandsConfig(Config):
self.add_option('network_online_timeout', libdnf.conf.OptionNumberInt32(60))
self.add_option('reboot', libdnf.conf.OptionEnumString('never',
libdnf.conf.VectorString(['never', 'when-changed', 'when-needed'])))
- self.add_option('reboot_command', libdnf.conf.OptionString('shutdown -r'))
+ self.add_option('reboot_command', libdnf.conf.OptionString('shutdown -r +5 \'Rebooting after applying package updates\''))
def imply(self):
if self.apply_updates:
diff --git a/doc/automatic.rst b/doc/automatic.rst
index ade0ca1a..329c2f46 100644
--- a/doc/automatic.rst
+++ b/doc/automatic.rst
@@ -96,9 +96,9 @@ Setting the mode of operation of the program.
When the system should reboot following upgrades. ``never`` does not reboot the system. ``when-changed`` triggers a reboot after any upgrade. ``when-needed`` triggers a reboot only when rebooting is necessary to apply changes, such as when systemd or the kernel is upgraded.
``reboot_command``
- string, default: ``shutdown -r``
+ string, default: ``shutdown -r +5 'Rebooting after applying package updates'``
- Specify the command to run to trigger a reboot of the system. For example, add a 5-minute delay and a wall message by using ``shutdown -r +5 'Rebooting after upgrading packages'``
+ Specify the command to run to trigger a reboot of the system. For example, to skip the 5-minute delay and wall message, use ``shutdown -r``
diff --git a/etc/dnf/automatic.conf b/etc/dnf/automatic.conf
index 9735447f..e61b12af 100644
--- a/etc/dnf/automatic.conf
+++ b/etc/dnf/automatic.conf
@@ -28,7 +28,7 @@ apply_updates = no
reboot = never
# The command that is run to trigger a system reboot.
-reboot_command = "shutdown -r"
+reboot_command = "shutdown -r +5 'Rebooting after applying package updates'"
[emitters]
--
2.40.0
From b002f47a763e442277913a06df963b0ca91deb54 Mon Sep 17 00:00:00 2001
From: Evan Goode <mail@evangoo.de>
Date: Wed, 25 Jan 2023 09:47:59 -0500
Subject: [PATCH 4/4] DNF Automatic: error message for failed reboot command
---
dnf/automatic/main.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/dnf/automatic/main.py b/dnf/automatic/main.py
index a03c359f..11c35ecf 100644
--- a/dnf/automatic/main.py
+++ b/dnf/automatic/main.py
@@ -347,7 +347,9 @@ def main(args):
if (conf.commands.reboot == 'when-changed' or
(conf.commands.reboot == 'when-needed' and base.reboot_needed())):
- if os.waitstatus_to_exitcode(os.system(conf.commands.reboot_command)) != 0:
+ exit_code = os.waitstatus_to_exitcode(os.system(conf.commands.reboot_command))
+ if exit_code != 0:
+ logger.error('Error: reboot command returned nonzero exit code: %d', exit_code)
return 1
except dnf.exceptions.Error as exc:
logger.error(_('Error: %s'), ucd(exc))
--
2.40.0

View File

@ -0,0 +1,45 @@
From b0caa16589763699174f47a3e36a703e1af32ed4 Mon Sep 17 00:00:00 2001
From: Kyle Walker <kwalker@redhat.com>
Date: Tue, 20 Dec 2022 08:42:03 -0500
Subject: [PATCH] Omit src RPMs from check-update (RhBug: 2151910)
The current check-update operation relies on src RPMs not being included
in the available repos. When those repos are enabled, *.src RPMs can be
emitted as updates that are available. Those RPMs are not updated in the
traditional fashion and can cause confusion to end users.
This change unconditionally filters out src packages in the
_list_patterns() callpath.
= changelog =
type: bugfix
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2151910
---
dnf/base.py | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/dnf/base.py b/dnf/base.py
index 24c5a44..7e97e21 100644
--- a/dnf/base.py
+++ b/dnf/base.py
@@ -1543,6 +1543,8 @@ class Base(object):
updates = query_for_repo(q).filterm(upgrades_by_priority=True)
# reduce a query to security upgrades if they are specified
updates = self._merge_update_filters(updates, upgrade=True)
+ # reduce a query to remove src RPMs
+ updates.filterm(arch__neq=['src', 'nosrc'])
# reduce a query to latest packages
updates = updates.latest().run()
@@ -1595,6 +1597,8 @@ class Base(object):
self.sack.query()).filter(obsoletes_by_priority=inst)
# reduce a query to security upgrades if they are specified
obsoletes = self._merge_update_filters(obsoletes, warning=False, upgrade=True)
+ # reduce a query to remove src RPMs
+ obsoletes.filterm(arch__neq=['src', 'nosrc'])
obsoletesTuples = []
for new in obsoletes:
obsoleted_reldeps = new.obsoletes
--
libgit2 1.3.2

View File

@ -0,0 +1,66 @@
From fcc21cf217a7dfaaf79ca36b5afab6344380eae1 Mon Sep 17 00:00:00 2001
From: Marek Blaha <mblaha@redhat.com>
Date: Mon, 3 Apr 2023 12:19:40 +0200
Subject: [PATCH] automatic: Fix online detection with proxy (RhBz:2022440)
In case the proxy is configured (either for a repo of globally) it is
used also for detecting whether the system is online.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2022440
---
dnf/automatic/main.py | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)
diff --git a/dnf/automatic/main.py b/dnf/automatic/main.py
index 11c35ec..756531e 100644
--- a/dnf/automatic/main.py
+++ b/dnf/automatic/main.py
@@ -182,7 +182,8 @@ class CommandsConfig(Config):
self.add_option('network_online_timeout', libdnf.conf.OptionNumberInt32(60))
self.add_option('reboot', libdnf.conf.OptionEnumString('never',
libdnf.conf.VectorString(['never', 'when-changed', 'when-needed'])))
- self.add_option('reboot_command', libdnf.conf.OptionString('shutdown -r +5 \'Rebooting after applying package updates\''))
+ self.add_option('reboot_command', libdnf.conf.OptionString(
+ 'shutdown -r +5 \'Rebooting after applying package updates\''))
def imply(self):
if self.apply_updates:
@@ -255,21 +256,29 @@ def wait_for_network(repos, timeout):
'http': 80,
'https': 443,
'ftp': 21,
+ 'socks': 1080,
+ 'socks5': 1080,
}
def remote_address(url_list):
for url in url_list:
parsed_url = dnf.pycomp.urlparse.urlparse(url)
- if parsed_url.hostname and parsed_url.scheme in remote_schemes:
- yield (parsed_url.hostname,
- parsed_url.port or remote_schemes[parsed_url.scheme])
+ if (not parsed_url.hostname) \
+ or (not parsed_url.port and parsed_url.scheme not in remote_schemes):
+ # skip urls without hostname or without recognized port
+ continue
+ yield (parsed_url.hostname,
+ parsed_url.port or remote_schemes[parsed_url.scheme])
# collect possible remote repositories urls
addresses = set()
for repo in repos.iter_enabled():
- addresses.update(remote_address(repo.baseurl))
- addresses.update(remote_address([repo.mirrorlist]))
- addresses.update(remote_address([repo.metalink]))
+ if repo.proxy:
+ addresses.update(remote_address([repo.proxy]))
+ else:
+ addresses.update(remote_address(repo.baseurl))
+ addresses.update(remote_address([repo.mirrorlist]))
+ addresses.update(remote_address([repo.metalink]))
if not addresses:
# there is no remote repository enabled so network connection should not be needed
--
libgit2 1.3.2

View File

@ -0,0 +1,39 @@
From e62164e450c05d626e4ca2b5dc2728939686b423 Mon Sep 17 00:00:00 2001
From: Jan Kolarik <jkolarik@redhat.com>
Date: Thu, 20 Apr 2023 10:10:14 +0000
Subject: [PATCH] automatic: Return an error when transaction fails
(RhBug:2170093)
In case of no global error occurred within the transaction, we still need to check state of individual transaction items for any failure.
This is matching the logic in `BaseCli.do_transaction` method, where the error is emitted after printing the transaction summary.
= changelog =
msg: automatic: Return an error when transaction fails
type: bugfix
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2170093
---
dnf/automatic/main.py | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/dnf/automatic/main.py b/dnf/automatic/main.py
index 756531e7..f6f4049b 100644
--- a/dnf/automatic/main.py
+++ b/dnf/automatic/main.py
@@ -351,6 +351,13 @@ def main(args):
gpgsigcheck(base, trans.install_set)
base.do_transaction()
+
+ # In case of no global error occurred within the transaction,
+ # we need to check state of individual transaction items.
+ for tsi in trans:
+ if tsi.state == libdnf.transaction.TransactionItemState_ERROR:
+ raise dnf.exceptions.Error(_('Transaction failed'))
+
emitters.notify_applied()
emitters.commit()
--
2.40.1

View File

@ -0,0 +1,63 @@
From 0f979bd00d22d52f4970897207bd43a74db90bcc Mon Sep 17 00:00:00 2001
From: Evan Goode <mail@evangoo.de>
Date: Tue, 30 May 2023 20:48:54 +0000
Subject: [PATCH] Document symbols in `dnf history list` output
This patch adds documentation for the symbols shown in the "Action(s)"
and "Altered" columns of `dnf history list`
The "Action(s)" column abbreviates the names of transaction actions when
there was more than one action, e.g. a transaction that both installs
and upgrades packages would be displayed as "I, U".
The "Altered" column prints some extra symbols when something unusual
happened with the transaction, like if any warnings were printed or if
it completed with a non-zero status.
Some language was taken from the yum man pages:
https://github.com/rpm-software-management/yum/blob/master/docs/yum.8.
It appears we no longer use the "P" or "s" symbols.
Resolves https://bugzilla.redhat.com/show_bug.cgi?id=2172067
(RhBug:2172067)
= changelog =
msg: Document the symbols in the output of `dnf history list`
type: bugfix
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2172067
---
doc/command_ref.rst | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/doc/command_ref.rst b/doc/command_ref.rst
index 3ee66bac..0e6cea01 100644
--- a/doc/command_ref.rst
+++ b/doc/command_ref.rst
@@ -710,6 +710,24 @@ transactions and act according to this information (assuming the
which specifies a transaction by a package which it manipulated. When no
transaction is specified, list all known transactions.
+ The "Action(s)" column lists each type of action taken in the transaction. The possible values are:
+
+ * Install (I): a new package was installed on the system
+ * Downgrade (D): an older version of a package replaced the previously-installed version
+ * Obsolete (O): an obsolete package was replaced by a new package
+ * Upgrade (U): a newer version of the package replaced the previously-installed version
+ * Remove (E): a package was removed from the system
+ * Reinstall (R): a package was reinstalled with the same version
+ * Reason change (C): a package was kept in the system but its reason for being installed changed
+
+ The "Altered" column lists the number of actions taken in each transaction, possibly followed by one or two the following symbols:
+
+ * ``>``: The RPM database was changed, outside DNF, after the transaction
+ * ``<``: The RPM database was changed, outside DNF, before the transaction
+ * ``*``: The transaction aborted before completion
+ * ``#``: The transaction completed, but with a non-zero status
+ * ``E``: The transaction completed successfully, but had warning/error output
+
``--reverse``
The order of ``history list`` output is printed in reverse order.
--
2.40.1

View File

@ -8,7 +8,7 @@
%global rpm_version 4.14.0 %global rpm_version 4.14.0
# conflicts # conflicts
%global conflicts_dnf_plugins_core_version 4.0.24-3 %global conflicts_dnf_plugins_core_version 4.0.26
%global conflicts_dnf_plugins_extras_version 4.0.4 %global conflicts_dnf_plugins_extras_version 4.0.4
%global conflicts_dnfdaemon_version 0.3.19 %global conflicts_dnfdaemon_version 0.3.19
@ -56,6 +56,9 @@
%global py3pluginpath %{python3_sitelib}/%{name}-plugins %global py3pluginpath %{python3_sitelib}/%{name}-plugins
# To avoid breakage if the python3 symlink is changed
%{?python3_version:%global __python3 /usr/bin/python%{python3_version}}
# Use the same directory of the main package for subpackage licence and docs # Use the same directory of the main package for subpackage licence and docs
%global _docdir_fmt %{name} %global _docdir_fmt %{name}
@ -65,19 +68,24 @@
It supports RPMs, modules and comps groups & environments. It supports RPMs, modules and comps groups & environments.
Name: dnf Name: dnf
Version: 4.12.0 Version: 4.14.0
Release: 3%{?dist}.alma Release: 8%{?dist}.alma.1
Summary: %{pkg_summary} Summary: %{pkg_summary}
# For a breakdown of the licensing, see PACKAGE-LICENSING # For a breakdown of the licensing, see PACKAGE-LICENSING
License: GPLv2+ License: GPLv2+
URL: https://github.com/rpm-software-management/dnf URL: https://github.com/rpm-software-management/dnf
Source0: %{url}/archive/%{version}/%{name}-%{version}.tar.gz Source0: %{url}/archive/%{version}/%{name}-%{version}.tar.gz
Patch1: 0001-Pass-whole-URL-in-relativeUrl-to-PackageTarget-for-R.patch
# Upstream commit which fixes leak of libsolv's page file descriptors. Patch2: 0002-Document-changes-to-offline-upgrade-command-RhBug-19.patch
# https://github.com/rpm-software-management/dnf/commit/5ce5ed1ea08ad6e198c1c1642c4d9ea2db6eab86 Patch3: 0003-Move-system-upgrade-plugin-to-core-RhBug-2054235.patch
Patch0001: 0001-Base.reset-plug-temporary-leak-of-libsolv-s-page-fil.patch Patch4: 0004-Fix-plugins-unit-tests.patch
Patch0002: 0002-Add-only-relevant-pkgs-to-upgrade-transaction-RhBug-.patch Patch5: 0005-Ignore-processing-variable-files-with-unsupported-en.patch
Patch0003: 0003-Use-installed_all-because-installed_query-is-filtere.patch Patch6: 0006-Update-translations.patch
Patch7: 0007-Add-reboot-option-to-DNF-Automatic.patch
Patch8: 0008-Omit-src-RPMs-from-check-update-RhBug-2151910.patch
Patch9: 0009-automatic-Fix-online-detection-with-proxy-RhBz2022440.patch
Patch10: 0010-automatic-Return-an-error-when-transaction-fails-RhB.patch
Patch11: 0011-Document-symbols-in-dnf-history-list-output.patch
#Almalinux patches #Almalinux patches
Patch10000: almalinux_bugtracker.patch Patch10000: almalinux_bugtracker.patch
@ -137,13 +145,12 @@ Common data and configuration files for DNF
%package -n %{yum_subpackage_name} %package -n %{yum_subpackage_name}
Requires: %{name} = %{version}-%{release} Requires: %{name} = %{version}-%{release}
Summary: %{pkg_summary} Summary: %{pkg_summary}
%if 0%{?fedora}
%if 0%{?fedora} >= 31 %if 0%{?fedora} && 0%{?fedora} < 31
Conflicts: yum < 3.4.3-505
%else
Provides: %{name}-yum = %{version}-%{release} Provides: %{name}-yum = %{version}-%{release}
Obsoletes: %{name}-yum < 5 Obsoletes: %{name}-yum < 5
%else
Conflicts: yum < 3.4.3-505
%endif
%endif %endif
%description -n %{yum_subpackage_name} %description -n %{yum_subpackage_name}
@ -370,9 +377,51 @@ popd
%{python3_sitelib}/%{name}/automatic/ %{python3_sitelib}/%{name}/automatic/
%changelog %changelog
* Mon Apr 11 2022 Eduard Abdullin <eabdullin@almalinux.org> - 4.12.0-3.alma * Wed Sep 27 2023 Eduard Abdullin <eabdullin@almalinux.org> - 4.14.0-8.alma.1
- Added patch for almalinux bugtracker - Added patch for almalinux bugtracker
* Wed Jun 28 2023 Jaroslav Rohel <jrohel@redhat.com> - 4.14.0-8
- Return an error when transaction fails (RhBug:2170093,2212262)
- Document symbols in `dnf history list` output (RhBug:2172067,2218113)
* Tue May 30 2023 Kyle Walker <kwalker@redhat.com> - 4.14.0-7
- Explicitly use the python3.9 runtime (RhBug:2211019)
* Thu May 11 2023 Jaroslav Rohel <jrohel@redhat.com> - 4.14.0-6
- Add reboot option to DNF Automatic (RhBug:2124793)
- Omit src RPMs from check-update (RhBug:2151910,2203069)
- automatic: Fix online detection with proxy (RhBug:2022440,2189851)
* Wed Mar 15 2023 Marek Blaha <mblaha@redhat.com> - 4.14.0-5
- Update translations
* Thu Jan 05 2023 Nicola Sella <nsella@redhat.com> - 4.14.0-4
- Ignore processing variable files with unsupported encoding (RhBug:2148871)
* Wed Dec 07 2022 Nicola Sella <nsella@redhat.com> - 4.14.0-3
- Move system-upgrade plugin to core (RhBug:2131288)
- offline-upgrade: add support for security filters (RhBug:1939975,2139326)
- Fix plugins unit tests + unload plugins upon their deletion
* Mon Oct 31 2022 Nicola Sella <nsella@redhat.com> - 4.14.0-2
- Pass whole URL in relativeUrl to PackageTarget for RPM URL download
* Thu Sep 22 2022 Lukas Hrazky <lhrazky@redhat.com> - 4.14.0-1
- Update to 4.14.0
- Add doc related to --destdir and --downloadonly options (RhBug:2100811)
- Fix broken dependencies error reporting (RhBug:2088422)
- Add support for group upgrade rollback (RhBug:2016070)
- Expose plugin unload method to API (RhBug:2047251)
- Fix upgrade from file to noarch pkg (RhBug:2006018)
- Allow passing plugin parameters with dashes in names (RhBug:1980712)
- Don't include resolved advisories for obsoletes with sec. filters (RhBug:2101421)
- Add only relevant pkgs to upgrade transaction (RhBug:2097757)
- doc: Describe how gpg keys are stored for `repo_ggpcheck` (RhBug:2020678)
- bash-completion: use sqlite cache when available
* 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 * Tue Jul 19 2022 Lukas Hrazky <lhrazky@redhat.com> - 4.12.0-3
- Add only relevant pkgs to upgrade transaction (RhBug:2097757) - Add only relevant pkgs to upgrade transaction (RhBug:2097757)