mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 00:55:19 +00:00
Merge pull request #13366 from terminalmage/refine-pkg-hold
Refine hold/unhold behavior in pkg.installed state
This commit is contained in:
commit
b807af5cbe
@ -585,6 +585,8 @@ def upgrade(refresh=True, dist_upgrade=True, **kwargs):
|
||||
|
||||
def hold(name=None, pkgs=None, sources=None, *kwargs):
|
||||
'''
|
||||
.. versionadded:: Helium
|
||||
|
||||
Set package in 'hold' state, meaning it will not be upgraded.
|
||||
|
||||
name
|
||||
@ -604,49 +606,60 @@ def hold(name=None, pkgs=None, sources=None, *kwargs):
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' pkg.hold pkgs='["foo", "bar"]'
|
||||
|
||||
.. versionadded:: Helium
|
||||
|
||||
'''
|
||||
|
||||
if not name and not pkgs and not sources:
|
||||
return 'Error: name, pkgs or sources needs to be specified.'
|
||||
raise SaltInvocationError(
|
||||
'One of name, pkgs, or sources must be specified.'
|
||||
)
|
||||
if pkgs and sources:
|
||||
raise SaltInvocationError(
|
||||
'Only one of pkgs or sources can be specified.'
|
||||
)
|
||||
|
||||
if name and not pkgs:
|
||||
pkgs = []
|
||||
pkgs.append(name)
|
||||
elif name and sources:
|
||||
pkgs = []
|
||||
targets = []
|
||||
if pkgs:
|
||||
targets.extend(pkgs)
|
||||
elif sources:
|
||||
for source in sources:
|
||||
pkgs += source.keys()
|
||||
targets.append(next(iter(source)))
|
||||
else:
|
||||
targets.append(name)
|
||||
|
||||
ret = {}
|
||||
for pkg in pkgs:
|
||||
if isinstance(pkg, dict):
|
||||
pkg = pkg.keys()[0]
|
||||
for target in targets:
|
||||
if isinstance(target, dict):
|
||||
target = next(iter(target))
|
||||
|
||||
ret[pkg] = {'name': pkg, 'changes': {}, 'result': False, 'comment': ''}
|
||||
state = get_selections(pattern=pkg, state=hold)
|
||||
ret[target] = {'name': target,
|
||||
'changes': {},
|
||||
'result': False,
|
||||
'comment': ''}
|
||||
|
||||
state = get_selections(pattern=target, state='hold')
|
||||
if not state:
|
||||
ret[pkg]['comment'] = 'Package {0} not currently held.'.format(pkg)
|
||||
ret[target]['comment'] = ('Package {0} not currently held.'
|
||||
.format(target))
|
||||
elif not salt.utils.is_true(state.get('hold', False)):
|
||||
if 'test' in kwargs and kwargs['test']:
|
||||
ret[pkg].update(result=None)
|
||||
ret[pkg]['comment'] = 'Package {0} is set to be held.'.format(pkg)
|
||||
ret[target].update(result=None)
|
||||
ret[target]['comment'] = ('Package {0} is set to be held.'
|
||||
.format(target))
|
||||
else:
|
||||
result = set_selections(
|
||||
selection={'hold': [pkg]}
|
||||
)
|
||||
ret[pkg].update(changes=result[pkg], result=True)
|
||||
ret[pkg]['comment'] = 'Package {0} is now being held.'.format(pkg)
|
||||
result = set_selections(selection={'hold': [target]})
|
||||
ret[target].update(changes=result[target], result=True)
|
||||
ret[target]['comment'] = ('Package {0} is now being held.'
|
||||
.format(target))
|
||||
else:
|
||||
ret[pkg].update(result=True)
|
||||
ret[pkg]['comment'] = 'Package {0} is already set to be held.'.format(pkg)
|
||||
ret[target].update(result=True)
|
||||
ret[target]['comment'] = ('Package {0} is already set to be held.'
|
||||
.format(target))
|
||||
return ret
|
||||
|
||||
|
||||
def unhold(name=None, pkgs=None, sources=None, **kwargs):
|
||||
'''
|
||||
.. versionadded:: Helium
|
||||
|
||||
Set package current in 'hold' state to install state,
|
||||
meaning it will be upgraded.
|
||||
|
||||
@ -667,46 +680,53 @@ def unhold(name=None, pkgs=None, sources=None, **kwargs):
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' pkg.unhold pkgs='["foo", "bar"]'
|
||||
|
||||
.. versionadded:: Helium
|
||||
|
||||
'''
|
||||
|
||||
if not name and not pkgs and not sources:
|
||||
return 'Error: name, pkgs or sources needs to be specified.'
|
||||
raise SaltInvocationError(
|
||||
'One of name, pkgs, or sources must be specified.'
|
||||
)
|
||||
if pkgs and sources:
|
||||
raise SaltInvocationError(
|
||||
'Only one of pkgs or sources can be specified.'
|
||||
)
|
||||
|
||||
if name and not pkgs:
|
||||
pkgs = []
|
||||
pkgs.append(name)
|
||||
elif name and sources:
|
||||
pkgs = []
|
||||
targets = []
|
||||
if pkgs:
|
||||
targets.extend(pkgs)
|
||||
elif sources:
|
||||
for source in sources:
|
||||
pkgs += source.keys()
|
||||
targets.append(next(iter(source)))
|
||||
else:
|
||||
targets.append(name)
|
||||
|
||||
ret = {}
|
||||
for pkg in pkgs:
|
||||
if isinstance(pkg, dict):
|
||||
pkg = pkg.keys()[0]
|
||||
for target in targets:
|
||||
if isinstance(target, dict):
|
||||
target = next(iter(target))
|
||||
|
||||
ret[pkg] = {'changes': {}, 'result': False, 'comment': ''}
|
||||
state = get_selections(pattern=pkg)
|
||||
ret[target] = {'name': target,
|
||||
'changes': {},
|
||||
'result': False,
|
||||
'comment': ''}
|
||||
|
||||
state = get_selections(pattern=target)
|
||||
if not state:
|
||||
ret[pkg]['comment'] = 'Package {0} does not have a state.'.format(pkg)
|
||||
ret[target]['comment'] = ('Package {0} does not have a state.'
|
||||
.format(target))
|
||||
elif salt.utils.is_true(state.get('hold', False)):
|
||||
if 'test' in kwargs and kwargs['test']:
|
||||
ret[pkg].update(result=None)
|
||||
ret['comment'] = 'Package {0} is set not to be held.'.format(pkg)
|
||||
ret[target].update(result=None)
|
||||
ret['comment'] = ('Package {0} is set not to be held.'
|
||||
.format(target))
|
||||
else:
|
||||
result = set_selections(
|
||||
selection={'install': [pkg]}
|
||||
)
|
||||
ret[pkg].update(changes=result[pkg], result=True)
|
||||
ret[pkg]['comment'] = 'Package {0} is no longer being held.'.format(pkg)
|
||||
result = set_selections(selection={'install': [target]})
|
||||
ret[target].update(changes=result[target], result=True)
|
||||
ret[target]['comment'] = ('Package {0} is no longer being '
|
||||
'held.'.format(target))
|
||||
else:
|
||||
ret[pkg].update(result=True)
|
||||
ret[pkg]['comment'] = 'Package {0} is already set not to be held.'.format(pkg)
|
||||
|
||||
log.debug('in unhold {0}'.format(ret))
|
||||
ret[target].update(result=True)
|
||||
ret[target]['comment'] = ('Package {0} is already set not to be '
|
||||
'held.'.format(target))
|
||||
return ret
|
||||
|
||||
|
||||
|
@ -1026,6 +1026,8 @@ def purge(name=None, pkgs=None, **kwargs): # pylint: disable=W0613
|
||||
|
||||
def hold(name=None, pkgs=None, sources=None, **kwargs): # pylint: disable=W0613
|
||||
'''
|
||||
.. versionadded:: Helium
|
||||
|
||||
Hold packages with ``yum -q versionlock``.
|
||||
|
||||
name
|
||||
@ -1037,9 +1039,6 @@ def hold(name=None, pkgs=None, sources=None, **kwargs): # pylint: disable=W0613
|
||||
A list of packages to hold. Must be passed as a python list. The
|
||||
``name`` parameter will be ignored if this option is passed.
|
||||
|
||||
.. versionadded:: Helium
|
||||
|
||||
|
||||
Returns a dict containing the changes.
|
||||
|
||||
CLI Example:
|
||||
@ -1049,54 +1048,68 @@ def hold(name=None, pkgs=None, sources=None, **kwargs): # pylint: disable=W0613
|
||||
salt '*' pkg.hold <package name>
|
||||
salt '*' pkg.hold pkgs='["foo", "bar"]'
|
||||
'''
|
||||
if 'yum-plugin-versionlock' not in list_pkgs():
|
||||
raise SaltInvocationError(
|
||||
'Packages cannot be held, yum-plugin-versionlock is not installed.'
|
||||
)
|
||||
if not name and not pkgs and not sources:
|
||||
return 'Error: name or pkgs needs to be specified.'
|
||||
raise SaltInvocationError(
|
||||
'One of name, pkgs, or sources must be specified.'
|
||||
)
|
||||
if pkgs and sources:
|
||||
raise SaltInvocationError(
|
||||
'Only one of pkgs or sources can be specified.'
|
||||
)
|
||||
|
||||
if name and not pkgs and not sources:
|
||||
pkgs = []
|
||||
pkgs.append(name)
|
||||
elif name and sources:
|
||||
pkgs = []
|
||||
targets = []
|
||||
if pkgs:
|
||||
targets.extend(pkgs)
|
||||
elif sources:
|
||||
for source in sources:
|
||||
pkgs += source.keys()
|
||||
|
||||
current_pkgs = list_pkgs()
|
||||
if 'yum-plugin-versionlock' not in current_pkgs:
|
||||
ret = {}
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Packages cannot be held, yum-plugin-versionlock needs to be installed.'
|
||||
return ret
|
||||
targets.append(next(iter(source)))
|
||||
else:
|
||||
targets.append(name)
|
||||
|
||||
current_locks = get_locked_packages()
|
||||
ret = {}
|
||||
for pkg in pkgs:
|
||||
if isinstance(pkg, dict):
|
||||
pkg = pkg.keys()[0]
|
||||
for target in targets:
|
||||
if isinstance(target, dict):
|
||||
target = next(iter(target))
|
||||
|
||||
ret[pkg] = {'name': pkg, 'changes': {}, 'result': False, 'comment': ''}
|
||||
if pkg not in current_locks:
|
||||
ret[target] = {'name': target,
|
||||
'changes': {},
|
||||
'result': False,
|
||||
'comment': ''}
|
||||
|
||||
if target not in current_locks:
|
||||
if 'test' in kwargs and kwargs['test']:
|
||||
ret[pkg].update(result=None)
|
||||
ret[pkg]['comment'] = 'Package {0} is set to be held.'.format(pkg)
|
||||
ret[target].update(result=None)
|
||||
ret[target]['comment'] = ('Package {0} is set to be held.'
|
||||
.format(target))
|
||||
else:
|
||||
cmd = 'yum -q versionlock {0}'.format(pkg)
|
||||
cmd = 'yum -q versionlock {0}'.format(target)
|
||||
out = __salt__['cmd.run_all'](cmd)
|
||||
|
||||
if out['retcode'] == 0:
|
||||
ret[pkg].update(result=True)
|
||||
ret[pkg]['comment'] = 'Package {0} is now being held.'.format(pkg)
|
||||
ret[pkg]['changes']['new'] = 'hold'
|
||||
ret[pkg]['changes']['old'] = ''
|
||||
ret[target].update(result=True)
|
||||
ret[target]['comment'] = ('Package {0} is now being held.'
|
||||
.format(target))
|
||||
ret[target]['changes']['new'] = 'hold'
|
||||
ret[target]['changes']['old'] = ''
|
||||
else:
|
||||
ret[pkg]['comment'] = 'Package {0} was unable to be held.'.format(pkg)
|
||||
ret[target]['comment'] = ('Package {0} was unable to be held.'
|
||||
.format(target))
|
||||
else:
|
||||
ret[pkg].update(result=True)
|
||||
ret[pkg]['comment'] = 'Package {0} is already set to be held.'.format(pkg)
|
||||
ret[target].update(result=True)
|
||||
ret[target]['comment'] = ('Package {0} is already set to be held.'
|
||||
.format(target))
|
||||
return ret
|
||||
|
||||
|
||||
def unhold(name=None, pkgs=None, sources=None, **kwargs): # pylint: disable=W0613
|
||||
'''
|
||||
.. versionadded:: Helium
|
||||
|
||||
Hold packages with ``yum -q versionlock``.
|
||||
|
||||
name
|
||||
@ -1108,9 +1121,6 @@ def unhold(name=None, pkgs=None, sources=None, **kwargs): # pylint: disable=W06
|
||||
A list of packages to unhold. Must be passed as a python list. The
|
||||
``name`` parameter will be ignored if this option is passed.
|
||||
|
||||
.. versionadded:: Helium
|
||||
|
||||
|
||||
Returns a dict containing the changes.
|
||||
|
||||
CLI Example:
|
||||
@ -1120,52 +1130,64 @@ def unhold(name=None, pkgs=None, sources=None, **kwargs): # pylint: disable=W06
|
||||
salt '*' pkg.unhold <package name>
|
||||
salt '*' pkg.unhold pkgs='["foo", "bar"]'
|
||||
'''
|
||||
if 'yum-plugin-versionlock' not in list_pkgs():
|
||||
raise SaltInvocationError(
|
||||
'Packages cannot be unheld, yum-plugin-versionlock is not installed.'
|
||||
)
|
||||
if not name and not pkgs and not sources:
|
||||
return 'Error: name, pkgs or sources needs to be specified.'
|
||||
raise SaltInvocationError(
|
||||
'One of name, pkgs, or sources must be specified.'
|
||||
)
|
||||
if pkgs and sources:
|
||||
raise SaltInvocationError(
|
||||
'Only one of pkgs or sources can be specified.'
|
||||
)
|
||||
|
||||
if name and not pkgs:
|
||||
pkgs = []
|
||||
pkgs.append(name)
|
||||
elif name and sources:
|
||||
pkgs = []
|
||||
targets = []
|
||||
if pkgs:
|
||||
targets.extend(pkgs)
|
||||
elif sources:
|
||||
for source in sources:
|
||||
pkgs += source.keys()
|
||||
|
||||
current_pkgs = list_pkgs()
|
||||
if 'yum-plugin-versionlock' not in current_pkgs:
|
||||
ret = {}
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Error: Package yum-plugin-versionlock needs to be installed.'
|
||||
return ret
|
||||
targets.append(next(iter(source)))
|
||||
else:
|
||||
targets.append(name)
|
||||
|
||||
current_locks = get_locked_packages(full=True)
|
||||
ret = {}
|
||||
for pkg in pkgs:
|
||||
if isinstance(pkg, dict):
|
||||
pkg = pkg.keys()[0]
|
||||
for target in targets:
|
||||
if isinstance(target, dict):
|
||||
target = next(iter(target))
|
||||
|
||||
ret[pkg] = {'name': pkg, 'changes': {}, 'result': False, 'comment': ''}
|
||||
ret[target] = {'name': target,
|
||||
'changes': {},
|
||||
'result': False,
|
||||
'comment': ''}
|
||||
|
||||
search_locks = [lock for lock in current_locks if lock.startswith(pkg)]
|
||||
search_locks = [lock for lock in current_locks
|
||||
if lock.startswith(target)]
|
||||
if search_locks:
|
||||
if 'test' in kwargs and kwargs['test']:
|
||||
ret[pkg].update(result=None)
|
||||
ret[pkg]['comment'] = 'Package {0} is set to be unheld.'.format(pkg)
|
||||
ret[target].update(result=None)
|
||||
ret[target]['comment'] = ('Package {0} is set to be unheld.'
|
||||
.format(target))
|
||||
else:
|
||||
_pkgs = ' '.join('"0:' + item + '"' for item in search_locks)
|
||||
cmd = 'yum -q versionlock delete {0}'.format(_pkgs)
|
||||
_targets = ' '.join('"0:' + item + '"' for item in search_locks)
|
||||
cmd = 'yum -q versionlock delete {0}'.format(_targets)
|
||||
out = __salt__['cmd.run_all'](cmd)
|
||||
|
||||
if out['retcode'] == 0:
|
||||
ret[pkg].update(result=True)
|
||||
ret[pkg]['comment'] = 'Package {0} is no longer held.'.format(pkg)
|
||||
ret[pkg]['changes']['new'] = ''
|
||||
ret[pkg]['changes']['old'] = 'hold'
|
||||
ret[target].update(result=True)
|
||||
ret[target]['comment'] = ('Package {0} is no longer held.'
|
||||
.format(target))
|
||||
ret[target]['changes']['new'] = ''
|
||||
ret[target]['changes']['old'] = 'hold'
|
||||
else:
|
||||
ret[pkg]['comment'] = 'Package {0} was unable to be unheld.'.format(pkg)
|
||||
ret[target]['comment'] = ('Package {0} was unable to be '
|
||||
'unheld.'.format(target))
|
||||
else:
|
||||
ret[pkg].update(result=True)
|
||||
ret[pkg]['comment'] = 'Package {0} is not being held.'.format(pkg)
|
||||
ret[target].update(result=True)
|
||||
ret[target]['comment'] = ('Package {0} is not being held.'
|
||||
.format(target))
|
||||
return ret
|
||||
|
||||
|
||||
|
@ -44,7 +44,9 @@ from salt.output import nested
|
||||
from salt.utils import namespaced_function as _namespaced_function
|
||||
from salt.utils.odict import OrderedDict
|
||||
from salt._compat import string_types
|
||||
from salt.exceptions import CommandExecutionError, MinionError
|
||||
from salt.exceptions import (
|
||||
CommandExecutionError, MinionError, SaltInvocationError
|
||||
)
|
||||
from salt.modules.pkg_resource import _repack_pkgs
|
||||
|
||||
_repack_pkgs = _namespaced_function(_repack_pkgs, globals())
|
||||
@ -184,7 +186,7 @@ def _find_install_targets(name=None,
|
||||
'changes': {},
|
||||
'result': True,
|
||||
'comment': 'Version {0} of package {1!r} is already '
|
||||
'installed'.format(version, name)}
|
||||
'installed.'.format(version, name)}
|
||||
|
||||
# if cver is not an empty string, the package is already installed
|
||||
elif cver and version is None and not pkg_verify:
|
||||
@ -193,7 +195,7 @@ def _find_install_targets(name=None,
|
||||
'changes': {},
|
||||
'result': True,
|
||||
'comment': 'Package {0} is already '
|
||||
'installed'.format(name)}
|
||||
'installed.'.format(name)}
|
||||
|
||||
version_spec = False
|
||||
# Find out which packages will be targeted in the call to pkg.install
|
||||
@ -655,28 +657,42 @@ def installed(
|
||||
# check that the hold function is available
|
||||
if 'pkg.hold' in __salt__:
|
||||
if 'hold' in kwargs:
|
||||
if kwargs['hold']:
|
||||
hold_ret = __salt__['pkg.hold'](name=name, pkgs=pkgs, sources=sources)
|
||||
else:
|
||||
hold_ret = __salt__['pkg.unhold'](name=name, pkgs=pkgs, sources=sources)
|
||||
try:
|
||||
if kwargs['hold']:
|
||||
hold_ret = __salt__['pkg.hold'](
|
||||
name=name, pkgs=pkgs, sources=sources
|
||||
)
|
||||
else:
|
||||
hold_ret = __salt__['pkg.unhold'](
|
||||
name=name, pkgs=pkgs, sources=sources
|
||||
)
|
||||
except (CommandExecutionError, SaltInvocationError) as exc:
|
||||
return {'name': name,
|
||||
'changes': {},
|
||||
'result': False,
|
||||
'comment': exc.message}
|
||||
|
||||
if 'result' in hold_ret and not hold_ret['result']:
|
||||
return {'name': name,
|
||||
'changes': {},
|
||||
'result': False,
|
||||
'comment': 'An error was encountered while holding/unholding '
|
||||
'package(s): {0}'.format(hold_ret['comment'])}
|
||||
'comment': 'An error was encountered while '
|
||||
'holding/unholding package(s): {0}'
|
||||
.format(hold_ret['comment'])}
|
||||
else:
|
||||
modified_hold = [hold_ret[x] for x in hold_ret.keys() if hold_ret[x]['changes']]
|
||||
not_modified_hold = [hold_ret[x] for x in hold_ret.keys() if not hold_ret[x]['changes'] and hold_ret[x]['result']]
|
||||
failed_hold = [hold_ret[x] for x in hold_ret.keys() if not hold_ret[x]['result']]
|
||||
modified_hold = [hold_ret[x] for x in hold_ret
|
||||
if hold_ret[x]['changes']]
|
||||
not_modified_hold = [hold_ret[x] for x in hold_ret
|
||||
if not hold_ret[x]['changes']
|
||||
and hold_ret[x]['result']]
|
||||
failed_hold = [hold_ret[x] for x in hold_ret
|
||||
if not hold_ret[x]['result']]
|
||||
|
||||
if modified_hold:
|
||||
for i in modified_hold:
|
||||
result['comment'] += ' {0}'.format(i['comment'])
|
||||
result['result'] = i['result']
|
||||
change_name = i['name']
|
||||
result['changes'][change_name] = i['changes']
|
||||
result['changes'][i['name']] = i['changes']
|
||||
|
||||
if not_modified_hold:
|
||||
for i in not_modified_hold:
|
||||
@ -759,31 +775,47 @@ def installed(
|
||||
'changes': {},
|
||||
'result': False,
|
||||
'comment': 'An error was encountered while installing '
|
||||
'package(s): {0}'.format(exc)}
|
||||
|
||||
if 'pkg.hold' in __salt__:
|
||||
if 'hold' in kwargs:
|
||||
if kwargs['hold']:
|
||||
hold_ret = __salt__['pkg.hold'](name=name, pkgs=pkgs, sources=sources)
|
||||
else:
|
||||
hold_ret = __salt__['pkg.unhold'](name=name, pkgs=pkgs, sources=sources)
|
||||
|
||||
if 'result' in hold_ret and not hold_ret['result']:
|
||||
return {'name': name,
|
||||
'changes': {},
|
||||
'result': False,
|
||||
'comment': 'An error was encountered while holding/unholding '
|
||||
'package(s): {0}'.format(hold_ret['comment'])}
|
||||
else:
|
||||
modified_hold = [hold_ret[x] for x in hold_ret.keys() if hold_ret[x]['changes']]
|
||||
not_modified_hold = [hold_ret[x] for x in hold_ret.keys() if not hold_ret[x]['changes'] and hold_ret[x]['result']]
|
||||
failed_hold = [hold_ret[x] for x in hold_ret.keys() if not hold_ret[x]['result']]
|
||||
'package(s): {0}'.format(exc)}
|
||||
|
||||
if isinstance(pkg_ret, dict):
|
||||
changes['installed'].update(pkg_ret)
|
||||
elif isinstance(pkg_ret, string_types):
|
||||
comment.append(pkg_ret)
|
||||
|
||||
if 'pkg.hold' in __salt__:
|
||||
if 'hold' in kwargs:
|
||||
try:
|
||||
if kwargs['hold']:
|
||||
hold_ret = __salt__['pkg.hold'](
|
||||
name=name, pkgs=pkgs, sources=sources
|
||||
)
|
||||
else:
|
||||
hold_ret = __salt__['pkg.unhold'](
|
||||
name=name, pkgs=pkgs, sources=sources
|
||||
)
|
||||
except (CommandExecutionError, SaltInvocationError) as exc:
|
||||
comment.append(exc.message)
|
||||
return {'name': name,
|
||||
'changes': changes,
|
||||
'result': False,
|
||||
'comment': ' '.join(comment)}
|
||||
else:
|
||||
if 'result' in hold_ret and not hold_ret['result']:
|
||||
return {'name': name,
|
||||
'changes': {},
|
||||
'result': False,
|
||||
'comment': 'An error was encountered while '
|
||||
'holding/unholding package(s): {0}'
|
||||
.format(hold_ret['comment'])}
|
||||
else:
|
||||
modified_hold = [hold_ret[x] for x in hold_ret
|
||||
if hold_ret[x]['changes']]
|
||||
not_modified_hold = [hold_ret[x] for x in hold_ret
|
||||
if not hold_ret[x]['changes']
|
||||
and hold_ret[x]['result']]
|
||||
failed_hold = [hold_ret[x] for x in hold_ret
|
||||
if not hold_ret[x]['result']]
|
||||
|
||||
if to_unpurge:
|
||||
changes['purge_desired'] = __salt__['lowpkg.unpurge'](*to_unpurge)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user