salt/parsing-epoch-out-of-version-provided-during-pkg-rem.patch

160 lines
6.2 KiB
Diff

From 3973f51a948c0d4a81ca5992c9b06e71ebae443c Mon Sep 17 00:00:00 2001
From: Jochen Breuer <jbreuer@suse.de>
Date: Mon, 3 May 2021 17:20:54 +0200
Subject: [PATCH] Parsing Epoch out of version provided during pkg remove
(bsc#1173692)
yum doesn't seem to like the epoch information provided within the
version. Therefore it's removed before passing it to yum.
* Introducing `ignore_epoch` to pkg.remove
Just like pkg.install pkg.remove now also has ignore_epoch. With
this it is possible to ignore the epoch information completely
during version comparison.
* No epoch regardless of arch
* Added tests for cases with and without arch.
* Epoch information is now skipped in all cases.
* Removes ignore_epoch from pkg state
---
changelog/57881.changed | 1 +
salt/modules/yumpkg.py | 14 ++--
tests/pytests/unit/modules/test_yumpkg.py | 79 +++++++++++++++++++++++
3 files changed, 90 insertions(+), 4 deletions(-)
create mode 100644 changelog/57881.changed
diff --git a/changelog/57881.changed b/changelog/57881.changed
new file mode 100644
index 0000000000..e2ae2f4653
--- /dev/null
+++ b/changelog/57881.changed
@@ -0,0 +1 @@
+Parsing Epoch out of version during pkg remove, since yum can't handle that in all of the cases.
diff --git a/salt/modules/yumpkg.py b/salt/modules/yumpkg.py
index c800dafa82..dd81c6f1e9 100644
--- a/salt/modules/yumpkg.py
+++ b/salt/modules/yumpkg.py
@@ -2087,11 +2087,13 @@ def remove(name=None, pkgs=None, **kwargs): # pylint: disable=W0613
old = list_pkgs()
targets = []
for target in pkg_params:
+ version_to_remove = pkg_params[target]
+ installed_versions = old[target].split(",")
+
# 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 not pkg_params[target]:
+ if target in old and not version_to_remove:
targets.append(target)
- elif target in old and pkg_params[target] in old[target].split(","):
+ elif target in old and version_to_remove in installed_versions:
arch = ""
pkgname = target
try:
@@ -2102,7 +2104,11 @@ def remove(name=None, pkgs=None, **kwargs): # pylint: disable=W0613
if archpart in salt.utils.pkg.rpm.ARCHES:
arch = "." + archpart
pkgname = namepart
- targets.append("{}-{}{}".format(pkgname, pkg_params[target], arch))
+ # Since we don't always have the arch info, epoch information has to parsed out. But
+ # a version check was already performed, so we are removing the right version.
+ targets.append(
+ "{}-{}{}".format(pkgname, version_to_remove.split(":", 1)[-1], arch)
+ )
if not targets:
return {}
diff --git a/tests/pytests/unit/modules/test_yumpkg.py b/tests/pytests/unit/modules/test_yumpkg.py
index cae47788ff..7e3ed517ea 100644
--- a/tests/pytests/unit/modules/test_yumpkg.py
+++ b/tests/pytests/unit/modules/test_yumpkg.py
@@ -1046,6 +1046,85 @@ def test_install_with_options():
)
+def test_remove_with_epoch():
+ """
+ Tests that we properly identify a version containing an epoch for
+ deinstallation.
+ You can deinstall pkgs only without the epoch if no arch is provided:
+ .. code-block:: bash
+ yum remove PackageKit-yum-1.1.10-2.el7.centos
+ """
+ name = "foo"
+ installed = "8:3.8.12-4.n.el7"
+ list_pkgs_mock = MagicMock(
+ side_effect=lambda **kwargs: {
+ name: [installed] if kwargs.get("versions_as_list", False) else installed
+ }
+ )
+ cmd_mock = MagicMock(
+ return_value={"pid": 12345, "retcode": 0, "stdout": "", "stderr": ""}
+ )
+ salt_mock = {
+ "cmd.run_all": cmd_mock,
+ "lowpkg.version_cmp": rpm.version_cmp,
+ "pkg_resource.parse_targets": MagicMock(
+ return_value=({name: installed}, "repository")
+ ),
+ }
+ full_pkg_string = "-".join((name, installed[2:]))
+ with patch.object(yumpkg, "list_pkgs", list_pkgs_mock), patch(
+ "salt.utils.systemd.has_scope", MagicMock(return_value=False)
+ ), patch.dict(yumpkg.__salt__, salt_mock):
+
+ with patch.dict(yumpkg.__grains__, {"os": "CentOS", "osrelease": 7}):
+ expected = ["yum", "-y", "remove", full_pkg_string]
+ yumpkg.remove(name)
+ call = cmd_mock.mock_calls[0][1][0]
+ assert call == expected, call
+
+
+def test_remove_with_epoch_and_arch_info():
+ """
+ Tests that we properly identify a version containing an epoch and arch
+ deinstallation.
+ You can deinstall pkgs with or without epoch in combination with the arch.
+ Here we test for the absence of the epoch, but the presence for the arch:
+ .. code-block:: bash
+ yum remove PackageKit-yum-1.1.10-2.el7.centos.x86_64
+ """
+ arch = "x86_64"
+ name = "foo"
+ name_and_arch = name + "." + arch
+ installed = "8:3.8.12-4.n.el7"
+ list_pkgs_mock = MagicMock(
+ side_effect=lambda **kwargs: {
+ name_and_arch: [installed]
+ if kwargs.get("versions_as_list", False)
+ else installed
+ }
+ )
+ cmd_mock = MagicMock(
+ return_value={"pid": 12345, "retcode": 0, "stdout": "", "stderr": ""}
+ )
+ salt_mock = {
+ "cmd.run_all": cmd_mock,
+ "lowpkg.version_cmp": rpm.version_cmp,
+ "pkg_resource.parse_targets": MagicMock(
+ return_value=({name_and_arch: installed}, "repository")
+ ),
+ }
+ full_pkg_string = "-".join((name, installed[2:]))
+ with patch.object(yumpkg, "list_pkgs", list_pkgs_mock), patch(
+ "salt.utils.systemd.has_scope", MagicMock(return_value=False)
+ ), patch.dict(yumpkg.__salt__, salt_mock):
+
+ with patch.dict(yumpkg.__grains__, {"os": "CentOS", "osrelease": 7}):
+ expected = ["yum", "-y", "remove", full_pkg_string + "." + arch]
+ yumpkg.remove(name)
+ call = cmd_mock.mock_calls[0][1][0]
+ assert call == expected, call
+
+
def test_install_with_epoch():
"""
Tests that we properly identify a version containing an epoch as an
--
2.33.0