Add kernelpkg.remove function for YUM-based systems

This commit is contained in:
Adam Mendlik 2017-08-15 15:11:02 -06:00
parent 9a1a2ada5b
commit 5c4a5ca59a
3 changed files with 110 additions and 4 deletions

View File

@ -6,11 +6,13 @@ from __future__ import absolute_import
import functools
import logging
# Import Salt libs
from salt.ext import six
try:
# Import Salt libs
from salt.ext import six
from salt.utils.versions import LooseVersion as _LooseVersion
from salt.exceptions import CommandExecutionError
import salt.utils.systemd
import salt.modules.yumpkg
HAS_REQUIRED_LIBS = True
except ImportError:
HAS_REQUIRED_LIBS = False
@ -20,6 +22,9 @@ log = logging.getLogger(__name__)
# Define the module's virtual name
__virtualname__ = 'kernelpkg'
# Import functions from yumpkg
_yum = salt.utils.namespaced_function(salt.modules.yumpkg._yum, globals())
def __virtual__():
'''
@ -186,6 +191,54 @@ def upgrade_available():
return _LooseVersion(latest_available()) > _LooseVersion(latest_installed())
def remove(release):
'''
Remove a specific version of the kernel.
release
The release number of an installed kernel. This must be the entire release
number as returned by :py:func:`~salt.modules.kernelpkg.list_installed`,
not the package name.
'''
if release not in list_installed():
raise CommandExecutionError('Kernel release \'{0}\' is not installed'.format(release))
if release == active():
raise CommandExecutionError('Active kernel cannot be removed')
target = '{0}-{1}'.format(_package_name(), release)
log.info('Removing kernel package {0}'.format(target))
old = __salt__['pkg.list_pkgs']()
# Build the command string
cmd = []
if salt.utils.systemd.has_scope(__context__) \
and __salt__['config.get']('systemd.scope', True):
cmd.extend(['systemd-run', '--scope'])
cmd.extend([_yum(), '-y', 'remove', target])
# Execute the command
out = __salt__['cmd.run_all'](
cmd,
output_loglevel='trace',
python_shell=False
)
# Look for the changes in installed packages
__context__.pop('pkg.list_pkgs', None)
new = __salt__['pkg.list_pkgs']()
ret = salt.utils.compare_dicts(old, new)
# Look for command execution errors
if out['retcode'] != 0:
raise CommandExecutionError(
'Error occurred removing package(s)',
info={'errors': [out['stderr']], 'changes': ret}
)
return {'removed': [target]}
def _package_name():
'''
Return static string for the package name

View File

@ -10,6 +10,7 @@ from __future__ import absolute_import
# Salt testing libs
try:
from tests.support.mock import MagicMock, patch
from salt.exceptions import CommandExecutionError
except ImportError:
pass
@ -171,3 +172,25 @@ class KernelPkgTestCase(object):
with patch.object(self._kernelpkg, 'latest_available', return_value=self.KERNEL_LIST[0]):
with patch.object(self._kernelpkg, 'latest_installed', return_value=self.KERNEL_LIST[-1]):
self.assertFalse(self._kernelpkg.upgrade_available())
def test_remove_active(self):
'''
Test - remove kernel package
'''
mock = MagicMock(return_value={'retcode': 0, 'stderr': []})
with patch.dict(self._kernelpkg.__salt__, {'cmd.run_all': mock}):
with patch.object(self._kernelpkg, 'active', return_value=self.KERNEL_LIST[-1]):
with patch.object(self._kernelpkg, 'list_installed', return_value=self.KERNEL_LIST):
self.assertRaises(CommandExecutionError, self._kernelpkg.remove, release=self.KERNEL_LIST[-1])
self._kernelpkg.__salt__['cmd.run_all'].assert_not_called()
def test_remove_invalid(self):
'''
Test - remove kernel package
'''
mock = MagicMock(return_value={'retcode': 0, 'stderr': []})
with patch.dict(self._kernelpkg.__salt__, {'cmd.run_all': mock}):
with patch.object(self._kernelpkg, 'active', return_value=self.KERNEL_LIST[-1]):
with patch.object(self._kernelpkg, 'list_installed', return_value=self.KERNEL_LIST):
self.assertRaises(CommandExecutionError, self._kernelpkg.remove, release='invalid')
self._kernelpkg.__salt__['cmd.run_all'].assert_not_called()

View File

@ -19,6 +19,7 @@ try:
from tests.unit.modules.test_kernelpkg import KernelPkgTestCase
import salt.modules.kernelpkg_linux_yum as kernelpkg
import salt.modules.yumpkg as pkg
from salt.exceptions import CommandExecutionError
HAS_MODULES = True
except ImportError:
HAS_MODULES = False
@ -32,18 +33,22 @@ class YumKernelPkgTestCase(KernelPkgTestCase, TestCase, LoaderModuleMockMixin):
KERNEL_LIST = ['3.10.0-327.el7', '3.11.0-327.el7', '4.9.1-100.el7']
LATEST = KERNEL_LIST[-1]
OS_ARCH = 'x86_64'
OS_NAME = 'RedHat'
def setup_loader_modules(self):
return {
kernelpkg: {
'__grains__': {
'os': self.OS_NAME,
'kernelrelease': '{0}.{1}'.format(self.KERNEL_LIST[0], self.OS_ARCH)
},
'__salt__': {
'pkg.normalize_name': pkg.normalize_name,
'pkg.upgrade': MagicMock(return_value={}),
'pkg.list_pkgs': MagicMock(return_value={}),
'pkg.version': MagicMock(return_value=self.KERNEL_LIST),
'system.reboot': MagicMock(return_value=None)
'system.reboot': MagicMock(return_value=None),
'config.get': MagicMock(return_value=True)
}
},
pkg: {
@ -68,3 +73,28 @@ class YumKernelPkgTestCase(KernelPkgTestCase, TestCase, LoaderModuleMockMixin):
mock = MagicMock(return_value=None)
with patch.dict(self._kernelpkg.__salt__, {'pkg.version': mock}):
self.assertListEqual(self._kernelpkg.list_installed(), [])
def test_remove_success(self):
'''
Test - remove kernel package
'''
mock = MagicMock(return_value={'retcode': 0, 'stderr': []})
with patch.dict(self._kernelpkg.__salt__, {'cmd.run_all': mock}):
with patch.object(self._kernelpkg, 'active', return_value=self.KERNEL_LIST[-1]):
with patch.object(self._kernelpkg, 'list_installed', return_value=self.KERNEL_LIST):
result = self._kernelpkg.remove(release=self.KERNEL_LIST[0])
self._kernelpkg.__salt__['cmd.run_all'].assert_called_once()
self.assertIn('removed', result)
target = '{0}-{1}'.format(self._kernelpkg._package_name(), self.KERNEL_LIST[0])
self.assertListEqual(result['removed'], [target])
def test_remove_error(self):
'''
Test - remove kernel package
'''
mock = MagicMock(return_value={'retcode': -1, 'stderr': []})
with patch.dict(self._kernelpkg.__salt__, {'cmd.run_all': mock}):
with patch.object(self._kernelpkg, 'active', return_value=self.KERNEL_LIST[-1]):
with patch.object(self._kernelpkg, 'list_installed', return_value=self.KERNEL_LIST):
self.assertRaises(CommandExecutionError, self._kernelpkg.remove, release=self.KERNEL_LIST[0])
self._kernelpkg.__salt__['cmd.run_all'].assert_called_once()