From 58179dc230027fefe201cc9ca4b2340006e9f4ce Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Mar 28 2023 08:58:06 +0000 Subject: import dnf-4.14.0-4.el9 --- diff --git a/.dnf.metadata b/.dnf.metadata index 2c26a84..481b8dd 100644 --- a/.dnf.metadata +++ b/.dnf.metadata @@ -1 +1 @@ -71cc8d130f8f7327f57e9b96a271a0f9a18e7e0e SOURCES/dnf-4.12.0.tar.gz +0697aee277730c57446b5b87bdb12456cf245203 SOURCES/dnf-4.14.0.tar.gz diff --git a/.gitignore b/.gitignore index 6838c8a..7748361 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/dnf-4.12.0.tar.gz +SOURCES/dnf-4.14.0.tar.gz diff --git a/SOURCES/0001-Base.reset-plug-temporary-leak-of-libsolv-s-page-fil.patch b/SOURCES/0001-Base.reset-plug-temporary-leak-of-libsolv-s-page-fil.patch deleted file mode 100644 index 2162232..0000000 --- a/SOURCES/0001-Base.reset-plug-temporary-leak-of-libsolv-s-page-fil.patch +++ /dev/null @@ -1,317 +0,0 @@ -From 5ce5ed1ea08ad6e198c1c1642c4d9ea2db6eab86 Mon Sep 17 00:00:00 2001 -From: Laszlo Ersek -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 . 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: -.) - -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 ---- - 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 - diff --git a/SOURCES/0001-Pass-whole-URL-in-relativeUrl-to-PackageTarget-for-R.patch b/SOURCES/0001-Pass-whole-URL-in-relativeUrl-to-PackageTarget-for-R.patch new file mode 100644 index 0000000..b8ea3b7 --- /dev/null +++ b/SOURCES/0001-Pass-whole-URL-in-relativeUrl-to-PackageTarget-for-R.patch @@ -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?= +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 + diff --git a/SOURCES/0002-Add-only-relevant-pkgs-to-upgrade-transaction-RhBug-.patch b/SOURCES/0002-Add-only-relevant-pkgs-to-upgrade-transaction-RhBug-.patch deleted file mode 100644 index a0cdeb8..0000000 --- a/SOURCES/0002-Add-only-relevant-pkgs-to-upgrade-transaction-RhBug-.patch +++ /dev/null @@ -1,64 +0,0 @@ -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/SOURCES/0002-Document-changes-to-offline-upgrade-command-RhBug-19.patch b/SOURCES/0002-Document-changes-to-offline-upgrade-command-RhBug-19.patch new file mode 100644 index 0000000..9643071 --- /dev/null +++ b/SOURCES/0002-Document-changes-to-offline-upgrade-command-RhBug-19.patch @@ -0,0 +1,96 @@ +From a41c3aefaa4f982511363645f5608e270094cadf Mon Sep 17 00:00:00 2001 +From: Jan Kolarik +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=, --advisories=`` + 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=, --bzs=`` +- 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=`` + 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 , --debuglevel=`` + 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=, --secseverity=`` + 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 + diff --git a/SOURCES/0003-Move-system-upgrade-plugin-to-core-RhBug-2054235.patch b/SOURCES/0003-Move-system-upgrade-plugin-to-core-RhBug-2054235.patch new file mode 100644 index 0000000..ea3d079 --- /dev/null +++ b/SOURCES/0003-Move-system-upgrade-plugin-to-core-RhBug-2054235.patch @@ -0,0 +1,31 @@ +From e5732ab22f092bb3fc6ce6e8f94aad72f3654383 Mon Sep 17 00:00:00 2001 +From: Jan Kolarik +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=, --destdir=`` + Redirect downloaded packages to provided directory. The option has to be used together with the \-\ + :ref:`-downloadonly ` 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 + diff --git a/SOURCES/0003-Use-installed_all-because-installed_query-is-filtere.patch b/SOURCES/0003-Use-installed_all-because-installed_query-is-filtere.patch deleted file mode 100644 index e5de647..0000000 --- a/SOURCES/0003-Use-installed_all-because-installed_query-is-filtere.patch +++ /dev/null @@ -1,37 +0,0 @@ -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/SOURCES/0004-Fix-plugins-unit-tests.patch b/SOURCES/0004-Fix-plugins-unit-tests.patch new file mode 100644 index 0000000..bc88733 --- /dev/null +++ b/SOURCES/0004-Fix-plugins-unit-tests.patch @@ -0,0 +1,94 @@ +From 3ef5ec915ea4b5e6fe7d25542f0daccef278c01e Mon Sep 17 00:00:00 2001 +From: Jan Kolarik +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 + diff --git a/SOURCES/0005-Ignore-processing-variable-files-with-unsupported-en.patch b/SOURCES/0005-Ignore-processing-variable-files-with-unsupported-en.patch new file mode 100644 index 0000000..87b2b81 --- /dev/null +++ b/SOURCES/0005-Ignore-processing-variable-files-with-unsupported-en.patch @@ -0,0 +1,50 @@ +From 490cf87dd27926d16fb10735b467cbc490d5c9f1 Mon Sep 17 00:00:00 2001 +From: Jan Kolarik +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 + diff --git a/SPECS/dnf.spec b/SPECS/dnf.spec index 71738ac..e6374d9 100644 --- a/SPECS/dnf.spec +++ b/SPECS/dnf.spec @@ -8,7 +8,7 @@ %global rpm_version 4.14.0 # 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_dnfdaemon_version 0.3.19 @@ -65,19 +65,19 @@ It supports RPMs, modules and comps groups & environments. Name: dnf -Version: 4.12.0 -Release: 3%{?dist} +Version: 4.14.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-Pass-whole-URL-in-relativeUrl-to-PackageTarget-for-R.patch +Patch2: 0002-Document-changes-to-offline-upgrade-command-RhBug-19.patch +Patch3: 0003-Move-system-upgrade-plugin-to-core-RhBug-2054235.patch +Patch4: 0004-Fix-plugins-unit-tests.patch +Patch5: 0005-Ignore-processing-variable-files-with-unsupported-en.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 BuildArch: noarch BuildRequires: cmake BuildRequires: gettext @@ -133,13 +133,12 @@ Common data and configuration files for DNF %package -n %{yum_subpackage_name} Requires: %{name} = %{version}-%{release} 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} Obsoletes: %{name}-yum < 5 -%else -Conflicts: yum < 3.4.3-505 -%endif %endif %description -n %{yum_subpackage_name} @@ -366,6 +365,33 @@ popd %{python3_sitelib}/%{name}/automatic/ %changelog +* Thu Jan 05 2023 Nicola Sella - 4.14.0-4 +- Ignore processing variable files with unsupported encoding (RhBug:2148871) + +* Wed Dec 03 2022 Nicola Sella - 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 - 4.14.0-2 +- Pass whole URL in relativeUrl to PackageTarget for RPM URL download + +* Thu Sep 22 2022 Lukas Hrazky - 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 - 4.12.0-4 +- Update translations + * Tue Jul 19 2022 Lukas Hrazky - 4.12.0-3 - Add only relevant pkgs to upgrade transaction (RhBug:2097757)