From 3c6952ac574279c00e49b676ff36b6c39e052b8d Mon Sep 17 00:00:00 2001 From: Gwyn Ciesla Date: Mon, 24 Jul 2023 12:24:19 -0500 Subject: [PATCH] Fix dnf5 compatibility and python 3.12 issue. --- 64675.patch | 377 +++++++++++++++++++++++++++++++++++++++++++ match_hostname.patch | 36 +++++ salt.spec | 9 +- 3 files changed, 421 insertions(+), 1 deletion(-) create mode 100644 64675.patch create mode 100644 match_hostname.patch diff --git a/64675.patch b/64675.patch new file mode 100644 index 0000000..3a53e1c --- /dev/null +++ b/64675.patch @@ -0,0 +1,377 @@ +From f51113921a4a1ba6c37150e7ed5f1b206e96e18a Mon Sep 17 00:00:00 2001 +From: David Murphy < dmurphy@saltstack.com> +Date: Wed, 19 Jul 2023 18:13:57 -0600 +Subject: [PATCH 01/11] Added support for dnf5 for Fedora + +--- + salt/modules/yumpkg.py | 38 +++++++++++++++-------- + tests/pytests/unit/modules/test_yumpkg.py | 14 +++++++-- + 2 files changed, 36 insertions(+), 16 deletions(-) + +diff --git a/salt/modules/yumpkg.py b/salt/modules/yumpkg.py +index 413c0e12f77a..08a7d7d05860 100644 +--- a/salt/modules/yumpkg.py ++++ b/salt/modules/yumpkg.py +@@ -14,6 +14,8 @@ + + .. versionadded:: 3003 + Support for ``tdnf`` on Photon OS. ++.. versionadded:: 3007.0 ++ Support for ``dnf5``` on Fedora 39 + """ + + +@@ -145,7 +147,7 @@ def _get_hold(line, pattern=__HOLD_PATTERN, full=True): + + def _yum(): + """ +- Determine package manager name (yum or dnf), ++ Determine package manager name (yum or dnf[5]), + depending on the executable existence in $PATH. + """ + +@@ -168,7 +170,10 @@ def _check(file): + contextkey = "yum_bin" + if contextkey not in context: + for dir in os.environ.get("PATH", os.defpath).split(os.pathsep): +- if _check(os.path.join(dir, "dnf")): ++ if _check(os.path.join(dir, "dnf5")): ++ context[contextkey] = "dnf5" ++ break ++ elif _check(os.path.join(dir, "dnf")): + context[contextkey] = "dnf" + break + elif _check(os.path.join(dir, "tdnf")): +@@ -245,7 +250,8 @@ def _versionlock_pkg(grains=None): + """ + if grains is None: + grains = __grains__ +- if _yum() == "dnf": ++ ++ if _yum() == "dnf" or _yum() == "dnf5": + if grains["os"].lower() == "fedora": + return ( + "python3-dnf-plugin-versionlock" +@@ -272,10 +278,11 @@ def _check_versionlock(): + + def _get_options(**kwargs): + """ +- Returns a list of options to be used in the yum/dnf command, based on the ++ Returns a list of options to be used in the yum/dnf[5] command, based on the + kwargs passed. + """ + # Get repo options from the kwargs ++ # dnf5 aliases dnf options, so no need to change + fromrepo = kwargs.pop("fromrepo", "") + repo = kwargs.pop("repo", "") + disablerepo = kwargs.pop("disablerepo", "") +@@ -1053,7 +1060,9 @@ def list_upgrades(refresh=True, **kwargs): + + cmd = ["--quiet"] + cmd.extend(options) +- cmd.extend(["list", "upgrades" if _yum() == "dnf" else "updates"]) ++ cmd.extend( ++ ["list", "upgrades" if (_yum() == "dnf" or _yum() == "dnf5") else "updates"] ++ ) + out = _call_yum(cmd, ignore_retcode=True) + if out["retcode"] != 0 and "Error:" in out: + return {} +@@ -1708,7 +1717,8 @@ def _add_common_args(cmd): + if skip_verify: + cmd.append("--nogpgcheck") + if downloadonly: +- cmd.append("--downloadonly") ++ if _yum() != "dnf5": ++ cmd.append("--downloadonly") + + try: + holds = list_holds(full=False) +@@ -1769,6 +1779,8 @@ def _temporarily_unhold(pkgs, targets): + cmd.extend(["--best", "--allowerasing"]) + _add_common_args(cmd) + cmd.append("install" if pkg_type != "advisory" else "update") ++ if _yum() == "dnf5": ++ cmd.extend(["--best", "--allowerasing"]) + cmd.extend(targets) + out = _call_yum(cmd, ignore_retcode=False, redirect_stderr=True) + if out["retcode"] != 0: +@@ -2002,7 +2014,7 @@ def upgrade( + + salt '*' pkg.upgrade security=True exclude='kernel*' + """ +- if _yum() == "dnf" and not obsoletes: ++ if (_yum() == "dnf" or _yum() == "dnf5") and not obsoletes: + # for dnf we can just disable obsoletes + _setopt = [ + opt +@@ -2040,7 +2052,7 @@ def upgrade( + cmd.append("upgrade" if not minimal else "upgrade-minimal") + else: + # do not force the removal of obsolete packages +- if _yum() == "dnf": ++ if _yum() == "dnf" or _yum() == "dnf5": + cmd.append("upgrade" if not minimal else "upgrade-minimal") + else: + # for yum we have to use update instead of upgrade +@@ -2396,7 +2408,7 @@ def unhold(name=None, pkgs=None, sources=None, **kwargs): # pylint: disable=W06 + + ret[target] = {"name": target, "changes": {}, "result": False, "comment": ""} + +- if _yum() == "dnf": ++ if _yum() == "dnf" or _yum() == "dnf5": + search_locks = [x for x in current_locks if x == target] + else: + # To accommodate yum versionlock's lack of support for removing +@@ -3032,7 +3044,7 @@ def mod_repo(repo, basedir=None, **kwargs): + if use_copr: + # Is copr plugin installed? + copr_plugin_name = "" +- if _yum() == "dnf": ++ if _yum() == "dnf" or _yum() == "dnf5": + copr_plugin_name = "dnf-plugins-core" + else: + copr_plugin_name = "yum-plugin-copr" +@@ -3493,7 +3505,7 @@ def services_need_restart(**kwargs): + + salt '*' pkg.services_need_restart + """ +- if _yum() != "dnf": ++ if _yum() == "dnf": + raise CommandExecutionError("dnf is required to list outdated services.") + if not salt.utils.systemd.booted(__context__): + raise CommandExecutionError("systemd is required to list outdated services.") +diff --git a/tests/pytests/unit/modules/test_yumpkg.py b/tests/pytests/unit/modules/test_yumpkg.py +index 1354ee5d2d0d..1b1992daf475 100644 +--- a/tests/pytests/unit/modules/test_yumpkg.py ++++ b/tests/pytests/unit/modules/test_yumpkg.py +@@ -72,7 +72,7 @@ def list_repos_var(): + + + @pytest.fixture( +- ids=["yum", "dnf"], ++ ids=["yum", "dnf", "dnf5"], + params=[ + { + "context": {"yum_bin": "yum"}, +@@ -84,6 +84,11 @@ def list_repos_var(): + "grains": {"os": "Fedora", "osrelease": 27}, + "cmd": ["dnf", "-y", "--best", "--allowerasing"], + }, ++ { ++ "context": {"yum_bin": "dnf5"}, ++ "grains": {"os": "Fedora", "osrelease": 39}, ++ "cmd": ["dnf5", "-y"], ++ }, + ], + ) + def yum_and_dnf(request): +@@ -692,7 +697,7 @@ def test_list_repo_pkgs_with_options(list_repos_var): + except AssertionError: + continue + else: +- pytest.fail("repo '{}' not checked".format(repo)) ++ pytest.fail(f"repo '{repo}' not checked") + + + def test_list_upgrades_dnf(): +@@ -2085,7 +2090,10 @@ def test_59705_version_as_accidental_float_should_become_text( + new, full_pkg_string, yum_and_dnf + ): + name = "fnord" +- expected_cmd = yum_and_dnf + ["install", full_pkg_string] ++ expected_cmd = yum_and_dnf + ["install"] ++ if expected_cmd[0] == "dnf5": ++ expected_cmd += ["--best", "--allowerasing"] ++ expected_cmd += [full_pkg_string] + cmd_mock = MagicMock( + return_value={"pid": 12345, "retcode": 0, "stdout": "", "stderr": ""} + ) + +From dd239d061003b7e9d9a0c22836204acd6df46320 Mon Sep 17 00:00:00 2001 +From: David Murphy < dmurphy@saltstack.com> +Date: Wed, 19 Jul 2023 18:29:51 -0600 +Subject: [PATCH 02/11] Added changelog entry + +--- + changelog/64532.added.md | 1 + + 1 file changed, 1 insertion(+) + create mode 100644 changelog/64532.added.md + +diff --git a/changelog/64532.added.md b/changelog/64532.added.md +new file mode 100644 +index 000000000000..53595d69280d +--- /dev/null ++++ b/changelog/64532.added.md +@@ -0,0 +1 @@ ++Added support for dnf5 and its new command syntax + +From 0349df1f2cdfe396a648eda86639c76efabefc0e Mon Sep 17 00:00:00 2001 +From: David Murphy +Date: Thu, 20 Jul 2023 09:39:11 -0600 +Subject: [PATCH 06/11] Update salt/modules/yumpkg.py + +Co-authored-by: Pedro Algarvio +--- + salt/modules/yumpkg.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/salt/modules/yumpkg.py b/salt/modules/yumpkg.py +index 3ab033361c02..6d4ab469165d 100644 +--- a/salt/modules/yumpkg.py ++++ b/salt/modules/yumpkg.py +@@ -1061,7 +1061,7 @@ def list_upgrades(refresh=True, **kwargs): + cmd = ["--quiet"] + cmd.extend(options) + cmd.extend( +- ["list", "upgrades" if (_yum() == "dnf" or _yum() == "dnf5") else "updates"] ++ ["list", "upgrades" if _yum() in ("dnf", "dnf5") else "updates"] + ) + out = _call_yum(cmd, ignore_retcode=True) + if out["retcode"] != 0 and "Error:" in out: + +From 3a5c478fa455fe8bba198728de304a09a76bb1db Mon Sep 17 00:00:00 2001 +From: David Murphy +Date: Thu, 20 Jul 2023 09:39:23 -0600 +Subject: [PATCH 07/11] Update salt/modules/yumpkg.py + +Co-authored-by: Pedro Algarvio +--- + salt/modules/yumpkg.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/salt/modules/yumpkg.py b/salt/modules/yumpkg.py +index 6d4ab469165d..6ebd9ce4acfb 100644 +--- a/salt/modules/yumpkg.py ++++ b/salt/modules/yumpkg.py +@@ -2014,7 +2014,7 @@ def upgrade( + + salt '*' pkg.upgrade security=True exclude='kernel*' + """ +- if (_yum() == "dnf" or _yum() == "dnf5") and not obsoletes: ++ if _yum() in ("dnf", "dnf5") and not obsoletes: + # for dnf we can just disable obsoletes + _setopt = [ + opt + +From 085e39acac36b839185fcef13d07ebcf9985ba6a Mon Sep 17 00:00:00 2001 +From: David Murphy +Date: Thu, 20 Jul 2023 09:39:41 -0600 +Subject: [PATCH 08/11] Update salt/modules/yumpkg.py + +Co-authored-by: Pedro Algarvio +--- + salt/modules/yumpkg.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/salt/modules/yumpkg.py b/salt/modules/yumpkg.py +index 6ebd9ce4acfb..c67c18d5b848 100644 +--- a/salt/modules/yumpkg.py ++++ b/salt/modules/yumpkg.py +@@ -2052,7 +2052,7 @@ def upgrade( + cmd.append("upgrade" if not minimal else "upgrade-minimal") + else: + # do not force the removal of obsolete packages +- if _yum() == "dnf" or _yum() == "dnf5": ++ if _yum() in ("dnf", "dnf5"): + cmd.append("upgrade" if not minimal else "upgrade-minimal") + else: + # for yum we have to use update instead of upgrade + +From 90162b872d25e31bc3cecc2c6f4c65d38de57481 Mon Sep 17 00:00:00 2001 +From: David Murphy +Date: Thu, 20 Jul 2023 09:39:48 -0600 +Subject: [PATCH 09/11] Update salt/modules/yumpkg.py + +Co-authored-by: Pedro Algarvio +--- + salt/modules/yumpkg.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/salt/modules/yumpkg.py b/salt/modules/yumpkg.py +index c67c18d5b848..c5725cdc8c4d 100644 +--- a/salt/modules/yumpkg.py ++++ b/salt/modules/yumpkg.py +@@ -2408,7 +2408,7 @@ def unhold(name=None, pkgs=None, sources=None, **kwargs): # pylint: disable=W06 + + ret[target] = {"name": target, "changes": {}, "result": False, "comment": ""} + +- if _yum() == "dnf" or _yum() == "dnf5": ++ if _yum() in ("dnf", "dnf5"): + search_locks = [x for x in current_locks if x == target] + else: + # To accommodate yum versionlock's lack of support for removing + +From 1a89a642208fb4d59fd1fdfde9aa67ba737fa5ab Mon Sep 17 00:00:00 2001 +From: David Murphy +Date: Thu, 20 Jul 2023 09:39:59 -0600 +Subject: [PATCH 10/11] Update salt/modules/yumpkg.py + +Co-authored-by: Pedro Algarvio +--- + salt/modules/yumpkg.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/salt/modules/yumpkg.py b/salt/modules/yumpkg.py +index c5725cdc8c4d..a3688c8c57de 100644 +--- a/salt/modules/yumpkg.py ++++ b/salt/modules/yumpkg.py +@@ -3044,7 +3044,7 @@ def mod_repo(repo, basedir=None, **kwargs): + if use_copr: + # Is copr plugin installed? + copr_plugin_name = "" +- if _yum() == "dnf" or _yum() == "dnf5": ++ if _yum() in ("dnf", "dnf5"): + copr_plugin_name = "dnf-plugins-core" + else: + copr_plugin_name = "yum-plugin-copr" + +From 9d4f211b01cada23c66d714d5e58662fa382a9da Mon Sep 17 00:00:00 2001 +From: David Murphy < dmurphy@saltstack.com> +Date: Thu, 20 Jul 2023 09:46:20 -0600 +Subject: [PATCH 11/11] Updates due to reviewer suggestions + +--- + salt/modules/yumpkg.py | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/salt/modules/yumpkg.py b/salt/modules/yumpkg.py +index a3688c8c57de..31129855fc7a 100644 +--- a/salt/modules/yumpkg.py ++++ b/salt/modules/yumpkg.py +@@ -1060,9 +1060,7 @@ def list_upgrades(refresh=True, **kwargs): + + cmd = ["--quiet"] + cmd.extend(options) +- cmd.extend( +- ["list", "upgrades" if _yum() in ("dnf", "dnf5") else "updates"] +- ) ++ cmd.extend(["list", "upgrades" if _yum() in ("dnf", "dnf5") else "updates"]) + out = _call_yum(cmd, ignore_retcode=True) + if out["retcode"] != 0 and "Error:" in out: + return {} +@@ -3505,7 +3503,7 @@ def services_need_restart(**kwargs): + + salt '*' pkg.services_need_restart + """ +- if _yum() == "dnf": ++ if _yum() != "dnf": + raise CommandExecutionError("dnf is required to list outdated services.") + if not salt.utils.systemd.booted(__context__): + raise CommandExecutionError("systemd is required to list outdated services.") +--- salt-3006.1/salt/modules/yumpkg.py~ 2023-07-21 11:04:34.563699567 -0500 ++++ salt-3006.1/salt/modules/yumpkg.py 2023-07-21 11:15:32.708768955 -0500 +@@ -124,12 +124,12 @@ + dnf ==> vim-enhanced-2:7.4.827-1.fc22.* + """ + if full: +- if _yum() == "dnf": ++ if _yum() in ("dnf", "dnf5"): + lock_re = r"({}-\S+)".format(pattern) + else: + lock_re = r"(\d+:{}-\S+)".format(pattern) + else: +- if _yum() == "dnf": ++ if _yum() in ("dnf", "dnf5"): + lock_re = r"({}-\S+)".format(pattern) + else: + lock_re = r"\d+:({}-\S+)".format(pattern) diff --git a/match_hostname.patch b/match_hostname.patch new file mode 100644 index 0000000..706818e --- /dev/null +++ b/match_hostname.patch @@ -0,0 +1,36 @@ +--- a/salt/ext/tornado/netutil.py~ 2023-05-05 12:53:34.000000000 -0500 ++++ b/salt/ext/tornado/netutil.py 2023-07-24 11:27:02.376824349 -0500 +@@ -54,8 +54,8 @@ + elif ssl is None: + ssl_match_hostname = SSLCertificateError = None # type: ignore + else: +- import backports.ssl_match_hostname +- ssl_match_hostname = backports.ssl_match_hostname.match_hostname ++ import urllib3.util.ssl_match_hostname ++ ssl_match_hostname = urllib3.util.ssl_match_hostname + SSLCertificateError = backports.ssl_match_hostname.CertificateError # type: ignore + + if hasattr(ssl, 'SSLContext'): +--- a/salt/ext/tornado/iostream.py~ 2023-05-05 12:53:34.000000000 -0500 ++++ b/salt/ext/tornado/iostream.py 2023-07-24 11:38:00.657632623 -0500 +@@ -38,7 +38,8 @@ + from salt.ext.tornado.concurrent import TracebackFuture + from salt.ext.tornado import ioloop + from salt.ext.tornado.log import gen_log, app_log +-from salt.ext.tornado.netutil import ssl_wrap_socket, ssl_match_hostname, SSLCertificateError, _client_ssl_defaults, _server_ssl_defaults ++from salt.ext.tornado.netutil import ssl_wrap_socket, SSLCertificateError, _client_ssl_defaults, _server_ssl_defaults ++import urllib3.util.ssl_match_hostname + from salt.ext.tornado import stack_context + from salt.ext.tornado.util import errno_from_exception + +--- a/salt/ext/tornado/netutil.py~ 2023-07-24 11:50:02.836988664 -0500 ++++ b/salt/ext/tornado/netutil.py 2023-07-24 11:50:52.217539638 -0500 +@@ -56,7 +56,7 @@ + else: + import urllib3.util.ssl_match_hostname + ssl_match_hostname = urllib3.util.ssl_match_hostname +- SSLCertificateError = backports.ssl_match_hostname.CertificateError # type: ignore ++ SSLCertificateError = urllib3.util.ssl_match_hostname.CertificateError # type: ignore + + if hasattr(ssl, 'SSLContext'): + if hasattr(ssl, 'create_default_context'): diff --git a/salt.spec b/salt.spec index ee23d8e..e2e921f 100644 --- a/salt.spec +++ b/salt.spec @@ -11,7 +11,7 @@ Name: salt Version: 3006.1 -Release: 3%{?dist} +Release: 4%{?dist} Summary: A parallel remote execution system Group: System Environment/Daemons License: ASL 2.0 @@ -41,6 +41,8 @@ Source21: %{name}-syndic.fish Source22: %{name}.sysusers Patch0: contextvars.patch +Patch1: 64675.patch +Patch2: match_hostname.patch BuildArch: noarch %ifarch %{ix86} x86_64 @@ -51,6 +53,7 @@ Requires: pciutils Requires: which Requires: dnf-utils Requires: logrotate +Requires: python3-tornado BuildRequires: systemd-rpm-macros BuildRequires: python3-devel @@ -330,6 +333,10 @@ chown salt:salt %{_sysconfdir}/%{name}/gpgkeys -R %changelog +* Mon Jul 24 2023 Gwyn Ciesla - 3006.1-4 +- Patch for dnf5 support from upstream. +- Fix Python 3.12 issue. + * Wed Jun 28 2023 Python Maint - 3006.1-3 - Rebuilt for Python 3.12