Parsing Epoch out of version provided during pkg remove (#57881)

* Parsing Epoch out of version provided during pkg remove

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, and tests

* Added tests for cases with and without arch.
* Epoch information is now skipped in all cases.

* Removes ignore_epoch from pkg state

* Changs entry

Co-authored-by: Gareth J. Greenaway <gareth@wiked.org>
This commit is contained in:
Jochen Breuer 2021-04-22 20:02:07 +02:00 committed by GitHub
parent ec040d656b
commit 2a5fd5e3e3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 96 additions and 4 deletions

1
changelog/57881.changed Normal file
View file

@ -0,0 +1 @@
Parsing Epoch out of version during pkg remove, since yum can't handle that in all of the cases.

View file

@ -2094,11 +2094,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:
@ -2109,7 +2111,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 {}

View file

@ -1014,6 +1014,91 @@ class YumTestCase(TestCase, LoaderModuleMockMixin):
redirect_stderr=True,
)
def test_remove_with_epoch(self):
"""
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(self):
"""
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(self):
"""
Tests that we properly identify a version containing an epoch as an