diff --git a/3005.1-implement-zypper-removeptf-573.patch b/3005.1-implement-zypper-removeptf-573.patch new file mode 100644 index 0000000..f271c04 --- /dev/null +++ b/3005.1-implement-zypper-removeptf-573.patch @@ -0,0 +1,236 @@ +From a5027f623a0a2e7f49109af9e2fa3ce409a31a64 Mon Sep 17 00:00:00 2001 +From: Michael Calmer +Date: Mon, 23 Jan 2023 14:33:26 +0100 +Subject: [PATCH] 3005.1 implement zypper removeptf (#573) + +* handle ptf packages inside of normal pkg.remove function + +* add testcase for remove and removeptf + +* add changelog + +* adapt old tests to changed function + +* Update Docs + +Co-authored-by: Megan Wilhite + +Co-authored-by: Megan Wilhite +--- + changelog/63442.added | 1 + + salt/modules/zypperpkg.py | 38 +++++++- + tests/pytests/unit/modules/test_zypperpkg.py | 92 +++++++++++++++++++- + tests/unit/modules/test_zypperpkg.py | 1 + + 4 files changed, 130 insertions(+), 2 deletions(-) + create mode 100644 changelog/63442.added + +diff --git a/changelog/63442.added b/changelog/63442.added +new file mode 100644 +index 0000000000..ad81b2f9d5 +--- /dev/null ++++ b/changelog/63442.added +@@ -0,0 +1 @@ ++implement removal of ptf packages in zypper pkg module +diff --git a/salt/modules/zypperpkg.py b/salt/modules/zypperpkg.py +index 5d745c432d..2888bb219f 100644 +--- a/salt/modules/zypperpkg.py ++++ b/salt/modules/zypperpkg.py +@@ -2058,17 +2058,21 @@ def _uninstall(inclusion_detection, name=None, pkgs=None, root=None): + except MinionError as exc: + raise CommandExecutionError(exc) + ++ ptfpackages = _find_ptf_packages(pkg_params.keys(), root=root) + includes = _detect_includes(pkg_params.keys(), inclusion_detection) + old = list_pkgs(root=root, includes=includes) + targets = [] + for target in pkg_params: ++ if target in ptfpackages: ++ # ptfpackages needs special handling ++ continue + # Check if package version set to be removed is actually installed: + # old[target] contains a comma-separated list of installed versions + if target in old and pkg_params[target] in old[target].split(","): + targets.append(target + "-" + pkg_params[target]) + elif target in old and not pkg_params[target]: + targets.append(target) +- if not targets: ++ if not targets and not ptfpackages: + return {} + + systemd_scope = _systemd_scope() +@@ -2080,6 +2084,13 @@ def _uninstall(inclusion_detection, name=None, pkgs=None, root=None): + ) + targets = targets[500:] + ++ # handle ptf packages ++ while ptfpackages: ++ __zypper__(systemd_scope=systemd_scope, root=root).call( ++ "removeptf", "--allow-downgrade", *ptfpackages[:500] ++ ) ++ ptfpackages = ptfpackages[500:] ++ + _clean_cache() + new = list_pkgs(root=root, includes=includes) + ret = salt.utils.data.compare_dicts(old, new) +@@ -2168,6 +2179,11 @@ def remove( + salt '*' pkg.remove + salt '*' pkg.remove ,, + salt '*' pkg.remove pkgs='["foo", "bar"]' ++ ++ .. versionchanged:: 3007 ++ Can now remove also PTF packages which require a different handling in the backend. ++ ++ Can now remove also PTF packages which require a different handling in the backend. + """ + return _uninstall(inclusion_detection, name=name, pkgs=pkgs, root=root) + +@@ -2643,6 +2659,26 @@ def _get_visible_patterns(root=None): + return patterns + + ++def _find_ptf_packages(pkgs, root=None): ++ """ ++ Find ptf packages in "pkgs" and return them as list ++ """ ++ ptfs = [] ++ cmd = ["rpm"] ++ if root: ++ cmd.extend(["--root", root]) ++ cmd.extend(["-q", "--qf", "%{NAME}: [%{PROVIDES} ]\n"]) ++ cmd.extend(pkgs) ++ output = __salt__["cmd.run"](cmd) ++ for line in output.splitlines(): ++ if not line.strip(): ++ continue ++ pkg, provides = line.split(":", 1) ++ if "ptf()" in provides: ++ ptfs.append(pkg) ++ return ptfs ++ ++ + def _get_installed_patterns(root=None): + """ + List all installed patterns. +diff --git a/tests/pytests/unit/modules/test_zypperpkg.py b/tests/pytests/unit/modules/test_zypperpkg.py +index 84dc7a10b4..a0d8e0084e 100644 +--- a/tests/pytests/unit/modules/test_zypperpkg.py ++++ b/tests/pytests/unit/modules/test_zypperpkg.py +@@ -10,7 +10,7 @@ import pytest + import salt.modules.pkg_resource as pkg_resource + import salt.modules.zypperpkg as zypper + from salt.exceptions import CommandExecutionError, SaltInvocationError +-from tests.support.mock import MagicMock, mock_open, patch ++from tests.support.mock import MagicMock, mock_open, call, patch + + + @pytest.fixture +@@ -527,3 +527,93 @@ def test_dist_upgrade_failure(): + + assert exc.exception.info["changes"] == {} + assert exc.exception.info["result"]["stdout"] == zypper_output ++ ++ ++def test_remove_multiple_pkgs_with_ptf(): ++ call_spy = MagicMock() ++ zypper_mock = MagicMock() ++ zypper_mock.stdout = "" ++ zypper_mock.stderr = "" ++ zypper_mock.exit_code = 0 ++ zypper_mock.call = call_spy ++ ++ rpm_output = textwrap.dedent( ++ """ ++ vim: vi vim vim(x86-64) vim-base vim-enhanced vim-python vim_client ++ ptf-12345: ptf() ptf-12345 ++ """ ++ ) ++ rpm_mock = MagicMock(side_effect=[rpm_output]) ++ ++ with patch( ++ "salt.modules.zypperpkg.__zypper__", MagicMock(return_value=zypper_mock) ++ ), patch.object( ++ zypper, ++ "list_pkgs", ++ MagicMock(side_effect=[{"vim": "0.18.0", "ptf-12345": "1"}, {}]), ++ ), patch.dict( ++ zypper.__salt__, {"cmd.run": rpm_mock} ++ ): ++ expected_calls = [ ++ call( ++ "remove", ++ "vim", ++ ), ++ call( ++ "removeptf", ++ "--allow-downgrade", ++ "ptf-12345", ++ ), ++ ] ++ ++ result = zypper.remove(name="vim,ptf-12345") ++ call_spy.assert_has_calls(expected_calls, any_order=False) ++ assert result["vim"]["new"] == "", result ++ assert result["vim"]["old"] == "0.18.0", result ++ assert result["ptf-12345"]["new"] == "", result ++ assert result["ptf-12345"]["old"] == "1", result ++ ++ ++def test_remove_ptf(): ++ call_spy = MagicMock() ++ zypper_mock = MagicMock() ++ zypper_mock.stdout = "" ++ zypper_mock.stderr = "" ++ zypper_mock.exit_code = 0 ++ zypper_mock.call = call_spy ++ ++ rpm_mock = MagicMock( ++ side_effect=[ ++ "vim: vi vim vim(x86-64) vim-base vim-enhanced vim-python vim_client", ++ "ptf-12345: ptf() ptf-12345", ++ ] ++ ) ++ ++ with patch( ++ "salt.modules.zypperpkg.__zypper__", MagicMock(return_value=zypper_mock) ++ ), patch.object( ++ zypper, ++ "list_pkgs", ++ MagicMock(side_effect=[{"vim": "0.18.0"}, {}, {"ptf-12345": "1"}, {}]), ++ ), patch.dict( ++ zypper.__salt__, {"cmd.run": rpm_mock} ++ ): ++ expected_call_vim = [ ++ "remove", ++ "vim", ++ ] ++ expected_call_ptf = [ ++ "removeptf", ++ "--allow-downgrade", ++ "ptf-12345", ++ ] ++ ++ result = zypper.remove(name="vim") ++ call_spy.assert_called_with(*expected_call_vim) ++ assert result["vim"]["new"] == "", result ++ assert result["vim"]["old"] == "0.18.0", result ++ ++ result = zypper.remove(name="ptf-12345") ++ call_spy.assert_called_with(*expected_call_ptf) ++ assert result["ptf-12345"]["new"] == "", result ++ assert result["ptf-12345"]["old"] == "1", result +diff --git a/tests/unit/modules/test_zypperpkg.py b/tests/unit/modules/test_zypperpkg.py +index bcd001cd85..db766363ec 100644 +--- a/tests/unit/modules/test_zypperpkg.py ++++ b/tests/unit/modules/test_zypperpkg.py +@@ -1470,6 +1470,7 @@ class ZypperTestCase(TestCase, LoaderModuleMockMixin): + # If config.get starts being used elsewhere, we'll need to write a + # side_effect function. + patches = { ++ "cmd.run": MagicMock(return_value="vim: vi vim\npico: pico"), + "cmd.run_all": MagicMock(return_value=cmd_out), + "pkg_resource.parse_targets": MagicMock(return_value=parsed_targets), + "pkg_resource.stringify": MagicMock(), +-- +2.37.3 + + diff --git a/_lastrevision b/_lastrevision index fc9f216..c4c75ad 100644 --- a/_lastrevision +++ b/_lastrevision @@ -1 +1 @@ -02c119f814533eed60bd687a8d17286ef75dd94c \ No newline at end of file +e66649e03c92d249899960aa629533eaeee31fa1 \ No newline at end of file diff --git a/fixes-pkg.version_cmp-on-openeuler-systems-and-a-few.patch b/fixes-pkg.version_cmp-on-openeuler-systems-and-a-few.patch new file mode 100644 index 0000000..3d66c74 --- /dev/null +++ b/fixes-pkg.version_cmp-on-openeuler-systems-and-a-few.patch @@ -0,0 +1,103 @@ +From 62b3e3491f283a5b5ac243e1f5904ad17e0353bc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ra=C3=BAl=20Osuna?= + <17827278+raulillo82@users.noreply.github.com> +Date: Tue, 31 Jan 2023 13:13:32 +0100 +Subject: [PATCH] Fixes pkg.version_cmp on openEuler systems and a few + other OS flavors (#576) + +* Fix bug/issue #540 + +* Fix bug/issue #540 + +* Add tests for __virtual__ function + +* Minor changes to align with upstream +--- + changelog/540.fixed | 1 + + salt/modules/rpm_lowpkg.py | 12 +++++-- + tests/pytests/unit/modules/test_rpm_lowpkg.py | 31 +++++++++++++++++++ + 3 files changed, 42 insertions(+), 2 deletions(-) + create mode 100644 changelog/540.fixed + +diff --git a/changelog/540.fixed b/changelog/540.fixed +new file mode 100644 +index 0000000000..50cb42bf40 +--- /dev/null ++++ b/changelog/540.fixed +@@ -0,0 +1 @@ ++Fix pkg.version_cmp on openEuler and a few other os flavors. +diff --git a/salt/modules/rpm_lowpkg.py b/salt/modules/rpm_lowpkg.py +index c8e984c021..01cd575bc7 100644 +--- a/salt/modules/rpm_lowpkg.py ++++ b/salt/modules/rpm_lowpkg.py +@@ -62,14 +62,22 @@ def __virtual__(): + " grains.", + ) + +- enabled = ("amazon", "xcp", "xenserver", "virtuozzolinux") ++ enabled = ( ++ "amazon", ++ "xcp", ++ "xenserver", ++ "virtuozzolinux", ++ "virtuozzo", ++ "issabel pbx", ++ "openeuler", ++ ) + + if os_family in ["redhat", "suse"] or os_grain in enabled: + return __virtualname__ + return ( + False, + "The rpm execution module failed to load: only available on redhat/suse type" +- " systems or amazon, xcp or xenserver.", ++ " systems or amazon, xcp, xenserver, virtuozzolinux, virtuozzo, issabel pbx or openeuler.", + ) + + +diff --git a/tests/pytests/unit/modules/test_rpm_lowpkg.py b/tests/pytests/unit/modules/test_rpm_lowpkg.py +index f19afa854e..e07f71eb61 100644 +--- a/tests/pytests/unit/modules/test_rpm_lowpkg.py ++++ b/tests/pytests/unit/modules/test_rpm_lowpkg.py +@@ -35,6 +35,37 @@ def _called_with_root(mock): + def configure_loader_modules(): + return {rpm: {"rpm": MagicMock(return_value=MagicMock)}} + ++def test___virtual___openeuler(): ++ patch_which = patch("salt.utils.path.which", return_value=True) ++ with patch.dict( ++ rpm.__grains__, {"os": "openEuler", "os_family": "openEuler"} ++ ), patch_which: ++ assert rpm.__virtual__() == "lowpkg" ++ ++ ++def test___virtual___issabel_pbx(): ++ patch_which = patch("salt.utils.path.which", return_value=True) ++ with patch.dict( ++ rpm.__grains__, {"os": "Issabel Pbx", "os_family": "IssabeL PBX"} ++ ), patch_which: ++ assert rpm.__virtual__() == "lowpkg" ++ ++ ++def test___virtual___virtuozzo(): ++ patch_which = patch("salt.utils.path.which", return_value=True) ++ with patch.dict( ++ rpm.__grains__, {"os": "virtuozzo", "os_family": "VirtuoZZO"} ++ ), patch_which: ++ assert rpm.__virtual__() == "lowpkg" ++ ++ ++def test___virtual___with_no_rpm(): ++ patch_which = patch("salt.utils.path.which", return_value=False) ++ ret = rpm.__virtual__() ++ assert isinstance(ret, tuple) ++ assert ret[0] is False ++ ++ + + # 'list_pkgs' function tests: 2 + +-- +2.37.3 + + diff --git a/salt.changes b/salt.changes index 066fd4f..17309c1 100644 --- a/salt.changes +++ b/salt.changes @@ -1,3 +1,28 @@ +------------------------------------------------------------------- +Fri Mar 17 12:05:55 UTC 2023 - Alexander Graul + +- Require python3-jmespath runtime dependency (bsc#1209233) +- Fix problem with detecting PTF packages (bsc#1208691) + +- Added: + * skip-package-names-without-colon-bsc-1208691-578.patch + +------------------------------------------------------------------- +Tue Jan 31 12:17:25 UTC 2023 - Pablo Suárez Hernández + +- Fixes pkg.version_cmp on openEuler systems and a few other OS flavors + +- Added: + * fixes-pkg.version_cmp-on-openeuler-systems-and-a-few.patch + +------------------------------------------------------------------- +Mon Jan 23 13:44:58 UTC 2023 - Pablo Suárez Hernández + +- Make pkg.remove function from zypperpkg module to handle also PTF packages + +- Added: + * 3005.1-implement-zypper-removeptf-573.patch + ------------------------------------------------------------------- Tue Jan 17 16:32:12 UTC 2023 - Pablo Suárez Hernández diff --git a/salt.spec b/salt.spec index d67c2d1..4bd9926 100644 --- a/salt.spec +++ b/salt.spec @@ -303,6 +303,13 @@ Patch77: fixes-for-python-3.10-502.patch Patch78: allow-entrypoint-compatibility-for-importlib-metadat.patch # PATCH-FIX-OPENSUSE: https://github.com/openSUSE/salt/pull/571 Patch79: control-the-collection-of-lvm-grains-via-config.patch +# PATCH-FIX_UPSTREAM: https://github.com/saltstack/salt/pull/63460 +Patch80: 3005.1-implement-zypper-removeptf-573.patch +# PATCH-FIX_UPSTREAM: https://github.com/saltstack/salt/pull/62249 +Patch81: fixes-pkg.version_cmp-on-openeuler-systems-and-a-few.patch +# PATCH-FIX_UPSTREAM: https://github.com/saltstack/salt/pull/63460 +# PATCH-FIX_OPENSUSE: https://github.com/openSUSE/salt/pull/578 +Patch82: skip-package-names-without-colon-bsc-1208691-578.patch ### IMPORTANT: The line below is used as a snippet marker. Do not touch it. ### SALT PATCHES LIST END @@ -449,7 +456,7 @@ Requires: dnf %if 0%{?rhel} == 6 Requires: yum-plugin-security %endif -%else +%else # SUSE Requires: python3-Jinja2 Requires: python3-MarkupSafe Requires: python3-msgpack-python > 0.3 @@ -459,7 +466,8 @@ Requires: python3-M2Crypto Requires: python3-pycrypto >= 2.6.1 %endif Requires: python3-pyzmq >= 2.2.0 -%endif +%endif # end of RHEL / SUSE specific section +Requires: python3-jmespath Requires: python3-PyYAML Requires: python3-psutil Requires: python3-requests >= 1.0.0 diff --git a/skip-package-names-without-colon-bsc-1208691-578.patch b/skip-package-names-without-colon-bsc-1208691-578.patch new file mode 100644 index 0000000..ab6ed8d --- /dev/null +++ b/skip-package-names-without-colon-bsc-1208691-578.patch @@ -0,0 +1,26 @@ +From 6d122245f15a206dbfa92703b954d535c5c34dd4 Mon Sep 17 00:00:00 2001 +From: Alexander Graul +Date: Mon, 27 Feb 2023 11:35:41 +0100 +Subject: [PATCH] Skip package names without colon (bsc#1208691) (#578) + +Fixes a problem in `_find_ptf_packages()` when passing multiple packages to `zypperpkg.remove` / `zypperpkg.purge`. The problem occurs when a passed package is not installed, in that case the output of the `rpm` subprocess is not parsed correctly. +--- + salt/modules/zypperpkg.py | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/salt/modules/zypperpkg.py b/salt/modules/zypperpkg.py +index cd057ec637..64373e59fb 100644 +--- a/salt/modules/zypperpkg.py ++++ b/salt/modules/zypperpkg.py +@@ -2758,6 +2758,8 @@ def _find_ptf_packages(pkgs, root=None): + for line in output.splitlines(): + if not line.strip(): + continue ++ if ":" not in line: ++ continue + pkg, provides = line.split(":", 1) + if "ptf()" in provides: + ptfs.append(pkg) +-- +2.39.2 +