From 5ecb62959ce0b4f91fe7b28bba6228aade4f6225 Mon Sep 17 00:00:00 2001 From: AlmaLinux RelEng Bot Date: Mon, 30 Mar 2026 11:20:13 -0400 Subject: [PATCH] import CS dnf-4.14.0-33.el9 --- ...-email_to-in-command_email-emitter-t.patch | 98 +++++++++++++++++++ ...and-skip-dangling-protected-dependen.patch | 43 ++++++++ SPECS/dnf.spec | 14 ++- 3 files changed, 153 insertions(+), 2 deletions(-) create mode 100644 SOURCES/0068-automatic-Expand-email_to-in-command_email-emitter-t.patch create mode 100644 SOURCES/0069-autoremove-warn-and-skip-dangling-protected-dependen.patch diff --git a/SOURCES/0068-automatic-Expand-email_to-in-command_email-emitter-t.patch b/SOURCES/0068-automatic-Expand-email_to-in-command_email-emitter-t.patch new file mode 100644 index 0000000..34214e8 --- /dev/null +++ b/SOURCES/0068-automatic-Expand-email_to-in-command_email-emitter-t.patch @@ -0,0 +1,98 @@ +From 843c725eebdd0484cf6f9d7a1de9369f336e28f7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= +Date: Thu, 19 Jun 2025 13:09:35 +0200 +Subject: [PATCH] automatic: Expand email_to in command_email emitter to + individual arguments + +Upstream commit: aa1ba2d1566198127518d0ccb38eaf5481b4649e + +If /etc/dnf/automatic.conf has: + + [emitters] + emit_via = command_email + [command_email] + email_to = root,test + +a command incompatible with s-nail-14.9.25, a "mail" command +implementation, was executed: + + execve("/usr/bin/mail", ["mail", "-Ssendwait", "-s", "Updates available on 'fedora-43'.", "-r", "root", "root test"], ...) = 0 + +The cause was that s-nail does not support multiple recipients in +a single argument. + +This patch changes how "{email_to}" expands in command_format +formatting string. Now it expands into multiple, space separated arguments. +The new syntax is also accepted by mailx tool. + +Implementation detail: A list of email_to recipients passed in +CommandEmitterMixIn does not inherit from "list" Python class or any +other iterator. It's libdnf.module.VectorString class generated by +Swig without. There the custom ShellQuotedLists formatting dictionary +needs to refer to libdnf.module.VectorString type and include "libdnf" +Python module explicitly. + +A test will be added to ci-dnf-stack repository. + +Resolve: #2241 +Resolve: https://issues.redhat.com/browse/RHEL-94321 +--- + dnf/automatic/emitter.py | 21 +++++++++++++++++---- + 1 file changed, 17 insertions(+), 4 deletions(-) + +diff --git a/dnf/automatic/emitter.py b/dnf/automatic/emitter.py +index 673da082b..7753f7715 100644 +--- a/dnf/automatic/emitter.py ++++ b/dnf/automatic/emitter.py +@@ -22,6 +22,7 @@ from __future__ import absolute_import + from __future__ import print_function + from __future__ import unicode_literals + from dnf.i18n import _ ++import libdnf + import logging + import dnf.pycomp + import smtplib +@@ -126,6 +127,20 @@ class EmailEmitter(Emitter): + logger.error(msg) + + ++class ShellQuotedLists(dict): ++ """ ++ Dictionary which returns values quoted with dnf.pycomp.shlex_quote(). ++ If a looked-up value is a list or libdnf.module.VectorString, it will ++ quote the list members and then concatenate them with a space and return ++ the resulting string. ++ """ ++ def __getitem__(self, key): ++ value = super(ShellQuotedLists, self).__getitem__(key) ++ if isinstance(value, (list, libdnf.module.VectorString)): ++ return ' '.join(dnf.pycomp.shlex_quote(item) for item in value) ++ else: ++ return dnf.pycomp.shlex_quote(value) ++ + class CommandEmitterMixIn(object): + """ + Executes a desired command, and pushes data into its stdin. +@@ -141,9 +156,7 @@ class CommandEmitterMixIn(object): + msg = self._prepare_msg() + # all strings passed to shell should be quoted to avoid accidental code + # execution +- quoted_msg = dict((key, dnf.pycomp.shlex_quote(val)) +- for key, val in msg.items()) +- command = command_fmt.format(**quoted_msg) ++ command = command_fmt.format_map(ShellQuotedLists(msg)) + stdin_feed = stdin_fmt.format(**msg).encode('utf-8') + + # Execute the command +@@ -171,7 +184,7 @@ class CommandEmailEmitter(CommandEmitterMixIn, EmailEmitter): + return {'subject': subject, + 'body': body, + 'email_from': self._conf.email_from, +- 'email_to': ' '.join(self._conf.email_to)} ++ 'email_to': self._conf.email_to} + + + class StdIoEmitter(Emitter): +-- +2.52.0 + diff --git a/SOURCES/0069-autoremove-warn-and-skip-dangling-protected-dependen.patch b/SOURCES/0069-autoremove-warn-and-skip-dangling-protected-dependen.patch new file mode 100644 index 0000000..42af557 --- /dev/null +++ b/SOURCES/0069-autoremove-warn-and-skip-dangling-protected-dependen.patch @@ -0,0 +1,43 @@ +From bffb669be6d49bd570c3a898aebc3a6dd28abf30 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= +Date: Mon, 26 Jan 2026 12:29:11 +0100 +Subject: [PATCH] autoremove: warn and skip dangling protected dependencies + +Requires new libdnf 0.76.0 API. +--- + dnf/base.py | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +diff --git a/dnf/base.py b/dnf/base.py +index 7d3dfdee..a20c18ee 100644 +--- a/dnf/base.py ++++ b/dnf/base.py +@@ -2308,9 +2308,23 @@ class Base(object): + logger.warning(_('No packages marked for removal.')) + + else: +- pkgs = self.sack.query()._unneeded(self.history.swdb, ++ unneeded_pkgs = self.sack.query()._unneeded(self.history.swdb, + debug_solver=self.conf.debug_solver) +- for pkg in pkgs: ++ ++ protected = self.sack.query().installed().filterm(name=self.conf.protected_packages) ++ protected_found = False ++ for pkg in protected: ++ if pkg in unneeded_pkgs: ++ msg = _('Unneeded protected package: %s (and its dependencies) cannot be removed, ' ++ 'either mark it as user-installed or change protected_packages configuration option.') ++ logger.warning(msg, pkg) ++ protected_found = True ++ ++ if protected_found: ++ unneeded_pkgs = self.sack.query()._unneeded_extra_userinstalled(self.history.swdb, protected, ++ debug_solver=self.conf.debug_solver) ++ ++ for pkg in unneeded_pkgs: + self.package_remove(pkg) + + def remove(self, pkg_spec, reponame=None, forms=None): +-- +2.53.0 + diff --git a/SPECS/dnf.spec b/SPECS/dnf.spec index 9e3e657..1ff455a 100644 --- a/SPECS/dnf.spec +++ b/SPECS/dnf.spec @@ -22,7 +22,7 @@ %endif %if 0%{?rhel} == 9 - %global hawkey_version 0.69.0-16 + %global hawkey_version 0.69.0-18 %endif # override dependencies for fedora 26 @@ -73,7 +73,7 @@ It supports RPMs, modules and comps groups & environments. Name: dnf Version: 4.14.0 -Release: 31%{?dist} +Release: 33%{?dist} Summary: %{pkg_summary} # For a breakdown of the licensing, see PACKAGE-LICENSING License: GPLv2+ @@ -146,6 +146,8 @@ Patch64: 0064-doc-Document-detect_releasevers-and-update-example.patch Patch65: 0065-tests-Patch-detect_releasevers-not-detect_releasever.patch Patch66: 0066-Document-how-releasever-releasever_-major-minor-affe.patch Patch67: 0067-Move-releasever_minor-setter-docstring-to-the-correc.patch +Patch68: 0068-automatic-Expand-email_to-in-command_email-emitter-t.patch +Patch69: 0069-autoremove-warn-and-skip-dangling-protected-dependen.patch BuildArch: noarch BuildRequires: cmake @@ -452,6 +454,14 @@ popd # bootc subpackage does not include any files %changelog +* Wed Feb 11 2026 Ales Matej - 4.14.0-33 +- autoremove: when a dangling protected dependency is found produce a wanrning + and skip it (RHEL-76112) + +* Fri Jan 09 2026 Petr Pisar - 4.14.0-32 +- automatic: Expand email_to in command_email emitter to individual arguments + (RHEL-94321) + * Mon Jun 30 2025 Evan Goode - 4.14.0-31 - Introduce $releasever_major, $releasever_minor variables, shell-style variable substitution (RHEL-65817)