Changed package manager detection (#59201)

* Changed package manager detection

* Added os import inside _yum function

* Added changelog

* Added patching __context__ dict

* Added condition for DNF installed on CentOS7

* Added _versionlock_pkg function

* Changed ret variable name

* Added second test install

* Conditional package change check
This commit is contained in:
Jerzy Drozdz 2021-01-06 20:58:55 +01:00 committed by GitHub
parent 50cb40320f
commit 3c28048b37
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 86 additions and 49 deletions

1
changelog/59201.changed Normal file
View file

@ -0,0 +1 @@
Changed package manager detection in yumpkg module

View file

@ -73,6 +73,8 @@ def __virtual__():
enabled = ("amazon", "xcp", "xenserver", "virtuozzolinux", "virtuozzo")
if os_family == "redhat" or os_grain in enabled:
if _yum() is None:
return (False, "DNF nor YUM found")
return __virtualname__
return (False, "Module yumpkg: no yum based system detected")
@ -134,20 +136,35 @@ def _get_hold(line, pattern=__HOLD_PATTERN, full=True):
def _yum():
"""
Determine package manager name (yum or dnf),
depending on the system version.
depending on the executable existence in $PATH.
"""
# Do import due to function clonning to kernelpkg_linux_yum mod
import os
def _check(file):
return (
os.path.exists(file)
and os.access(file, os.F_OK | os.X_OK)
and not os.path.isdir(file)
)
# allow calling function outside execution module
try:
context = __context__
except NameError:
context = {}
contextkey = "yum_bin"
if contextkey not in __context__:
if (
"fedora" in __grains__["os"].lower() and int(__grains__["osrelease"]) >= 22
) or (
__grains__["os"].lower() in ("redhat", "centos")
and int(__grains__["osmajorrelease"]) >= 8
):
__context__[contextkey] = "dnf"
else:
__context__[contextkey] = "yum"
return __context__[contextkey]
if contextkey not in context:
for dir in os.environ.get("PATH", os.defpath).split(os.pathsep):
if _check(os.path.join(dir, "dnf")):
context[contextkey] = "dnf"
break
elif _check(os.path.join(dir, "yum")):
context[contextkey] = "yum"
break
return context.get(contextkey)
def _call_yum(args, **kwargs):
@ -209,28 +226,35 @@ def _yum_pkginfo(output):
yield pkginfo
def _versionlock_pkg(grains=None):
"""
Determine versionlock plugin package name
"""
if grains is None:
grains = __grains__
if _yum() == "dnf":
if grains["os"].lower() == "fedora":
return (
"python3-dnf-plugin-versionlock"
if int(grains.get("osrelease")) >= 26
else "python3-dnf-plugins-extras-versionlock"
)
if int(grains.get("osmajorrelease")) >= 8:
return "python3-dnf-plugin-versionlock"
return "python2-dnf-plugin-versionlock"
else:
return (
"yum-versionlock"
if int(grains.get("osmajorrelease")) == 5
else "yum-plugin-versionlock"
)
def _check_versionlock():
"""
Ensure that the appropriate versionlock plugin is present
"""
if _yum() == "dnf":
if (
"fedora" in __grains__["os"].lower()
and int(__grains__.get("osrelease")) >= 26
) or (
__grains__.get("os").lower() in ("redhat", "centos")
and int(__grains__.get("osmajorrelease")) >= 8
):
vl_plugin = "python3-dnf-plugin-versionlock"
else:
vl_plugin = "python3-dnf-plugins-extras-versionlock"
else:
vl_plugin = (
"yum-versionlock"
if __grains__.get("osmajorrelease") == "5"
else "yum-plugin-versionlock"
)
vl_plugin = _versionlock_pkg()
if vl_plugin not in list_pkgs():
raise SaltInvocationError(
"Cannot proceed, {} is not installed.".format(vl_plugin)

View file

@ -635,10 +635,12 @@ class PkgTest(ModuleCase, SaltReturnAssertsMixin):
"""
versionlock_pkg = None
if grains["os_family"] == "RedHat":
from salt.modules.yumpkg import _versionlock_pkg
pkgs = {
p
for p in self.run_function("pkg.list_repo_pkgs")
if "yum-plugin-versionlock" in p
if _versionlock_pkg(grains) in p
}
if not pkgs:
self.skipTest("No versionlock package found in repositories")
@ -661,19 +663,23 @@ class PkgTest(ModuleCase, SaltReturnAssertsMixin):
target = self._PKG_TARGETS[0]
# First we ensure that the package is installed
ret = self.run_state("pkg.installed", name=target, hold=False, refresh=False,)
self.assertSaltTrueReturn(ret)
target_ret = self.run_state(
"pkg.installed", name=target, hold=False, refresh=False,
)
self.assertSaltTrueReturn(target_ret)
if versionlock_pkg and "-versionlock is not installed" in str(ret):
self.skipTest("{} `{}` is installed".format(ret, versionlock_pkg))
if versionlock_pkg and "-versionlock is not installed" in str(target_ret):
self.skipTest("{} `{}` is installed".format(target_ret, versionlock_pkg))
try:
tag = "pkg_|-{0}_|-{0}_|-installed".format(target)
self.assertSaltTrueReturn(ret)
self.assertIn(tag, ret)
self.assertIn("changes", ret[tag])
self.assertIn(target, ret[tag]["changes"])
self.assertIn("held", ret[tag]["comment"])
self.assertSaltTrueReturn(target_ret)
self.assertIn(tag, target_ret)
self.assertIn("changes", target_ret[tag])
# On Centos 7 package is already installed, no change happened
if target_ret[tag].get("changes"):
self.assertIn(target, target_ret[tag]["changes"])
self.assertIn("held", target_ret[tag]["comment"])
finally:
# Clean up, unhold package and remove
ret = self.run_state("pkg.removed", name=target)

View file

@ -981,7 +981,9 @@ class YumTestCase(TestCase, LoaderModuleMockMixin):
# Test yum
expected = ["yum", "-y", "install", full_pkg_string]
with patch.dict(yumpkg.__grains__, {"os": "CentOS", "osrelease": 7}):
with patch.dict(yumpkg.__context__, {"yum_bin": "yum"}), patch.dict(
yumpkg.__grains__, {"os": "CentOS", "osrelease": 7}
):
yumpkg.install("foo", version=new)
call = cmd_mock.mock_calls[0][1][0]
assert call == expected, call
@ -997,7 +999,9 @@ class YumTestCase(TestCase, LoaderModuleMockMixin):
]
yumpkg.__context__.pop("yum_bin")
cmd_mock.reset_mock()
with patch.dict(yumpkg.__grains__, {"os": "Fedora", "osrelease": 27}):
with patch.dict(yumpkg.__context__, {"yum_bin": "dnf"}), patch.dict(
yumpkg.__grains__, {"os": "Fedora", "osrelease": 27}
):
yumpkg.install("foo", version=new)
call = cmd_mock.mock_calls[0][1][0]
assert call == expected, call
@ -1224,7 +1228,7 @@ class YumTestCase(TestCase, LoaderModuleMockMixin):
# Test Fedora 20
cmd = MagicMock(return_value={"retcode": 0})
with patch.dict(
with patch.dict(yumpkg.__context__, {"yum_bin": "yum"}), patch.dict(
yumpkg.__grains__, {"os": "Fedora", "osrelease": 20}
), patch.object(
yumpkg, "list_pkgs", MagicMock(return_value=list_pkgs_mock)
@ -1257,9 +1261,13 @@ class YumTestCase(TestCase, LoaderModuleMockMixin):
yumpkg.__context__.pop("yum_bin")
cmd = MagicMock(return_value={"retcode": 0})
with patch.dict(yumpkg.__grains__, {"osmajorrelease": 8}), patch.object(
with patch.dict(yumpkg.__context__, {"yum_bin": "dnf"}), patch.dict(
yumpkg.__grains__, {"osmajorrelease": 8}
), patch.object(
yumpkg, "list_pkgs", MagicMock(return_value=list_pkgs_mock)
), patch.object(yumpkg, "list_holds", MagicMock(return_value=[])), patch.dict(
), patch.object(
yumpkg, "list_holds", MagicMock(return_value=[])
), patch.dict(
yumpkg.__salt__, {"cmd.run_all": cmd}
), patch(
"salt.utils.systemd.has_scope", MagicMock(return_value=False)
@ -1273,9 +1281,8 @@ class YumTestCase(TestCase, LoaderModuleMockMixin):
)
# Test Fedora 26+
yumpkg.__context__.pop("yum_bin")
cmd = MagicMock(return_value={"retcode": 0})
with patch.dict(
with patch.dict(yumpkg.__context__, {"yum_bin": "dnf"}), patch.dict(
yumpkg.__grains__, {"os": "Fedora", "osrelease": 26}
), patch.object(
yumpkg, "list_pkgs", MagicMock(return_value=list_pkgs_mock)
@ -1300,9 +1307,8 @@ class YumTestCase(TestCase, LoaderModuleMockMixin):
"python3-dnf-plugins-extras-versionlock": "0:1.0.0-0.n.el8",
}
yumpkg.__context__.pop("yum_bin")
cmd = MagicMock(return_value={"retcode": 0})
with patch.dict(
with patch.dict(yumpkg.__context__, {"yum_bin": "dnf"}), patch.dict(
yumpkg.__grains__, {"os": "Fedora", "osrelease": 25}
), patch.object(
yumpkg, "list_pkgs", MagicMock(return_value=list_pkgs_mock)