File 0004-Fix-pkg.latest-prevent-crash-on-multiple-package-ins.patch of Package salt.3314
From e21ddab93f22d1b2e1ad94368527f41102b69f16 Mon Sep 17 00:00:00 2001
From: Bo Maryniuk <bo@suse.de>
Date: Fri, 22 Jan 2016 18:37:12 +0100
Subject: [PATCH 04/22] Fix pkg.latest - prevent crash on multiple package
installation
Fix PEP8: line continuation
Replace old fashion string memcopy with the list
Fix PEP8: line continuation
Bugfix: crash on "key not found" error
Fix formatting
Check the version of the package, instead of the package name
Get version as an explicit parameter
Use regexp type for the string.
Avoid backslashes where they are not needed
Remove unnecessary complexity and string increment
Add a new line before the last return
Add error handling
Cleanup formatting
Bugfix: do not treat SLS id as a package name if an empty 'pkgs' list specified.
Put 'kwargs' on its own line according to the common pattern
---
salt/modules/zypper.py | 43 +++++++++++++---------------------
salt/states/pkg.py | 62 ++++++++++++++++++++++++--------------------------
2 files changed, 46 insertions(+), 59 deletions(-)
diff --git a/salt/modules/zypper.py b/salt/modules/zypper.py
index dddcc2f..63b38af 100644
--- a/salt/modules/zypper.py
+++ b/salt/modules/zypper.py
@@ -598,6 +598,7 @@ def install(name=None,
pkgs=None,
sources=None,
downloadonly=None,
+ version=None,
**kwargs):
'''
Install the passed package(s), add refresh=True to run 'zypper refresh'
@@ -666,23 +667,20 @@ def install(name=None,
'new': '<new-version>'}}
'''
try:
- pkg_params, pkg_type = __salt__['pkg_resource.parse_targets'](
- name, pkgs, sources, **kwargs
- )
+ pkg_params, pkg_type = __salt__['pkg_resource.parse_targets'](name, pkgs, sources, **kwargs)
except MinionError as exc:
raise CommandExecutionError(exc)
if pkg_params is None or len(pkg_params) == 0:
return {}
- version_num = kwargs.get('version')
+ version_num = version
if version_num:
if pkgs is None and sources is None:
# Allow "version" to work for single package target
pkg_params = {name: version_num}
else:
- log.warning('\'version\' parameter will be ignored for multiple '
- 'package targets')
+ log.warning("'version' parameter will be ignored for multiple package targets")
if pkg_type == 'repository':
targets = []
@@ -691,18 +689,13 @@ def install(name=None,
if version_num is None:
targets.append(param)
else:
- match = re.match('^([<>])?(=)?([^<>=]+)$', version_num)
+ match = re.match(r'^([<>])?(=)?([^<>=]+)$', version_num)
if match:
gt_lt, equal, verstr = match.groups()
- prefix = gt_lt or ''
- prefix += equal or ''
- # If no prefix characters were supplied, use '='
- prefix = prefix or '='
- targets.append('{0}{1}{2}'.format(param, prefix, verstr))
+ targets.append('{0}{1}{2}'.format(param, ((gt_lt or '') + (equal or '')) or '=', verstr))
log.debug(targets)
else:
- msg = ('Invalid version string {0!r} for package '
- '{1!r}'.format(version_num, name))
+ msg = ('Invalid version string {0!r} for package {1!r}'.format(version_num, name))
problems.append(msg)
if problems:
for problem in problems:
@@ -731,19 +724,14 @@ def install(name=None,
while targets:
cmd = cmd_install + targets[:500]
targets = targets[500:]
-
- out = __salt__['cmd.run'](
- cmd,
- output_loglevel='trace',
- python_shell=False
- )
- for line in out.splitlines():
- match = re.match(
- "^The selected package '([^']+)'.+has lower version",
- line
- )
- if match:
- downgrades.append(match.group(1))
+ call = __salt__['cmd.run_all'](cmd, output_loglevel='trace', python_shell=False)
+ if call['retcode'] != 0:
+ raise CommandExecutionError(call['stderr']) # Fixme: This needs a proper report mechanism.
+ else:
+ for line in call['stdout'].splitlines():
+ match = re.match(r"^The selected package '([^']+)'.+has lower version", line)
+ if match:
+ downgrades.append(match.group(1))
while downgrades:
cmd = cmd_install + ['--force'] + downgrades[:500]
@@ -752,6 +740,7 @@ def install(name=None,
__salt__['cmd.run'](cmd, output_loglevel='trace', python_shell=False)
__context__.pop('pkg.list_pkgs', None)
new = list_pkgs()
+
return salt.utils.compare_dicts(old, new)
diff --git a/salt/states/pkg.py b/salt/states/pkg.py
index 65ba779..d7c4503 100644
--- a/salt/states/pkg.py
+++ b/salt/states/pkg.py
@@ -1373,8 +1373,7 @@ def latest(
'''
rtag = __gen_rtag()
refresh = bool(
- salt.utils.is_true(refresh)
- or (os.path.isfile(rtag) and refresh is not False)
+ salt.utils.is_true(refresh) or (os.path.isfile(rtag) and refresh is not False)
)
if kwargs.get('sources'):
@@ -1392,7 +1391,15 @@ def latest(
'comment': 'Invalidly formatted "pkgs" parameter. See '
'minion log.'}
else:
- desired_pkgs = [name]
+ if isinstance(pkgs, list) and len(pkgs) == 0:
+ return {
+ 'name': name,
+ 'changes': {},
+ 'result': True,
+ 'comment': 'No packages to install provided'
+ }
+ else:
+ desired_pkgs = [name]
cur = __salt__['pkg.version'](*desired_pkgs, **kwargs)
try:
@@ -1431,33 +1438,29 @@ def latest(
log.error(msg)
problems.append(msg)
else:
- if salt.utils.compare_versions(ver1=cur[pkg],
- oper='!=',
- ver2=avail[pkg],
- cmp_func=cmp_func):
+ if salt.utils.compare_versions(ver1=cur[pkg], oper='!=', ver2=avail[pkg], cmp_func=cmp_func):
targets[pkg] = avail[pkg]
else:
if not cur[pkg] or __salt__['portage_config.is_changed_uses'](pkg):
targets[pkg] = avail[pkg]
else:
for pkg in desired_pkgs:
- if not avail[pkg]:
- if not cur[pkg]:
+ if pkg not in avail:
+ if not cur.get(pkg):
msg = 'No information found for \'{0}\'.'.format(pkg)
log.error(msg)
problems.append(msg)
- elif not cur[pkg] \
- or salt.utils.compare_versions(ver1=cur[pkg],
- oper='<',
- ver2=avail[pkg],
- cmp_func=cmp_func):
+ elif not cur.get(pkg) \
+ or salt.utils.compare_versions(ver1=cur[pkg], oper='<', ver2=avail[pkg], cmp_func=cmp_func):
targets[pkg] = avail[pkg]
if problems:
- return {'name': name,
- 'changes': {},
- 'result': False,
- 'comment': ' '.join(problems)}
+ return {
+ 'name': name,
+ 'changes': {},
+ 'result': False,
+ 'comment': ' '.join(problems)
+ }
if targets:
# Find up-to-date packages
@@ -1471,9 +1474,7 @@ def latest(
if __opts__['test']:
to_be_upgraded = ', '.join(sorted(targets))
- comment = 'The following packages are set to be ' \
- 'installed/upgraded: ' \
- '{0}'.format(to_be_upgraded)
+ comment = ['The following packages are set to be installed/upgraded: {0}'.format(to_be_upgraded)]
if up_to_date:
up_to_date_nb = len(up_to_date)
if up_to_date_nb <= 10:
@@ -1482,19 +1483,16 @@ def latest(
'{0} ({1})'.format(name, cur[name])
for name in up_to_date_sorted
)
- comment += (
- ' The following packages are already '
- 'up-to-date: {0}'
- ).format(up_to_date_details)
+ comment.append('The following packages are already up-to-date: {0}'.format(up_to_date_details))
else:
- comment += ' {0} packages are already up-to-date'.format(
- up_to_date_nb
- )
+ comment.append('{0} packages are already up-to-date'.format(up_to_date_nb))
- return {'name': name,
- 'changes': {},
- 'result': None,
- 'comment': comment}
+ return {
+ 'name': name,
+ 'changes': {},
+ 'result': None,
+ 'comment': ' '.join(comment)
+ }
# Build updated list of pkgs to exclude non-targeted ones
targeted_pkgs = list(targets.keys()) if pkgs else None
--
2.1.4