256 lines
9.3 KiB
Diff
256 lines
9.3 KiB
Diff
|
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
|
||
|
|