diff --git a/SOURCES/0007-Add-reboot-option-to-DNF-Automatic.patch b/SOURCES/0007-Add-reboot-option-to-DNF-Automatic.patch new file mode 100644 index 0000000..ad51e90 --- /dev/null +++ b/SOURCES/0007-Add-reboot-option-to-DNF-Automatic.patch @@ -0,0 +1,252 @@ +From 56d3e10ecb666da53a77d17e9ac7524f3e1341d8 Mon Sep 17 00:00:00 2001 +From: Evan Goode +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 +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 + Dylan Pindur + Eduard Cuba ++ Evan Goode + Filipe Brandenburger + Frank Dana + George Machitidze +-- +2.40.0 + + +From 9deed331cb7a1890e1f11a57c989c300b1641a88 Mon Sep 17 00:00:00 2001 +From: Evan Goode +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 +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 + diff --git a/SOURCES/0008-Omit-src-RPMs-from-check-update-RhBug-2151910.patch b/SOURCES/0008-Omit-src-RPMs-from-check-update-RhBug-2151910.patch new file mode 100644 index 0000000..3462a50 --- /dev/null +++ b/SOURCES/0008-Omit-src-RPMs-from-check-update-RhBug-2151910.patch @@ -0,0 +1,45 @@ +From b0caa16589763699174f47a3e36a703e1af32ed4 Mon Sep 17 00:00:00 2001 +From: Kyle Walker +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 + diff --git a/SOURCES/0009-automatic-Fix-online-detection-with-proxy-RhBz2022440.patch b/SOURCES/0009-automatic-Fix-online-detection-with-proxy-RhBz2022440.patch new file mode 100644 index 0000000..979a7fd --- /dev/null +++ b/SOURCES/0009-automatic-Fix-online-detection-with-proxy-RhBz2022440.patch @@ -0,0 +1,66 @@ +From fcc21cf217a7dfaaf79ca36b5afab6344380eae1 Mon Sep 17 00:00:00 2001 +From: Marek Blaha +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 + diff --git a/SOURCES/0010-automatic-Return-an-error-when-transaction-fails-RhB.patch b/SOURCES/0010-automatic-Return-an-error-when-transaction-fails-RhB.patch new file mode 100644 index 0000000..4f71514 --- /dev/null +++ b/SOURCES/0010-automatic-Return-an-error-when-transaction-fails-RhB.patch @@ -0,0 +1,39 @@ +From e62164e450c05d626e4ca2b5dc2728939686b423 Mon Sep 17 00:00:00 2001 +From: Jan Kolarik +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 + diff --git a/SOURCES/0011-Document-symbols-in-dnf-history-list-output.patch b/SOURCES/0011-Document-symbols-in-dnf-history-list-output.patch new file mode 100644 index 0000000..c5aa57a --- /dev/null +++ b/SOURCES/0011-Document-symbols-in-dnf-history-list-output.patch @@ -0,0 +1,63 @@ +From 0f979bd00d22d52f4970897207bd43a74db90bcc Mon Sep 17 00:00:00 2001 +From: Evan Goode +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 + diff --git a/SPECS/dnf.spec b/SPECS/dnf.spec index ad417fa..8bb367e 100644 --- a/SPECS/dnf.spec +++ b/SPECS/dnf.spec @@ -56,6 +56,9 @@ %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 %global _docdir_fmt %{name} @@ -66,7 +69,7 @@ It supports RPMs, modules and comps groups & environments. Name: dnf Version: 4.14.0 -Release: 5%{?dist} +Release: 8%{?dist} Summary: %{pkg_summary} # For a breakdown of the licensing, see PACKAGE-LICENSING License: GPLv2+ @@ -78,6 +81,11 @@ 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 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 BuildArch: noarch BuildRequires: cmake @@ -366,6 +374,18 @@ popd %{python3_sitelib}/%{name}/automatic/ %changelog +* Wed Jun 28 2023 Jaroslav Rohel - 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 - 4.14.0-7 +- Explicitly use the python3.9 runtime (RhBug:2211019) + +* Thu May 11 2023 Jaroslav Rohel - 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 - 4.14.0-5 - Update translations