SHA256
1
0
forked from pool/salt
salt/0007-Force-sort-the-RPM-output-to-ensure-latest-version-o.patch
Klaus Kämpf 56c946e70f Accepting request 391560 from systemsmanagement:saltstack:testing
- Prevent crash if pygit2 package requests recompilation.
  Add:
  * 0013-Prevent-crash-if-pygit2-package-is-requesting-re-com.patch
- Align OS grains from older SLES with the current one (bsc#975757)
  Add:
  * 0014-align-OS-grains-from-older-SLES-with-current-one-326.patch

- remove patches which produce duplicate functions:
  Remove:
  * 0004-implement-version_cmp-for-zypper.patch
  * 0005-pylint-changes.patch
  * 0006-Check-if-rpm-python-can-be-imported.patch
- remove patches which add and revert the same file
  Remove:
  * 0007-Initial-Zypper-Unit-Tests-and-bugfixes.patch
  * 0009-Bugfix-on-SLE11-series-base-product-reported-as-addi.patch
- rename patches:
  0008-do-not-generate-a-date-in-a-comment-to-prevent-rebui.patch to
     0004-do-not-generate-a-date-in-a-comment-to-prevent-rebui.patch
  0010-Use-SHA256-hash-type-by-default.patch to
     0005-Use-SHA256-hash-type-by-default.patch
  0011-Update-to-2015.8.8.2.patch to
     0006-Update-to-2015.8.8.2.patch
  0012-Force-sort-the-RPM-output-to-ensure-latest-version-o.patch to
     0007-Force-sort-the-RPM-output-to-ensure-latest-version-o.patch
  0013-Cleaner-deprecation-process-with-decorators.patch  to
     0008-Cleaner-deprecation-process-with-decorators.patch
- fix sorting by latest package
  Add:
  * 0009-fix-sorting-by-latest-version-when-called-with-an-at.patch
- Prevent metadata download when getting installed products
  Add:
  * 0010-Prevent-metadata-download-when-getting-installed-pro.patch
- Check if EOL is available in a particular product (bsc#975093)
  Add:
  * 0011-Check-if-EOL-is-available-in-a-particular-product-bs.patch
- Bugfix: salt-key crashes if tries to generate keys 
  to the directory w/o write access (bsc#969320)
  Add:
  * 0012-Bugfix-salt-key-crashes-if-tries-to-generate-keys-to.patch

- Deprecation process using decorators and re-implementation
  of status.update function.
  Add:
  * 0013-Cleaner-deprecation-process-with-decorators.patch

- Reverted the fake 2015.8.8.2 patch, with the right one,
- this patch only contains:
  - https://github.com/saltstack/salt/pull/32135 
  - https://github.com/saltstack/salt/pull/32023 
  - https://github.com/saltstack/salt/pull/32117

- Ensure that in case of multi-packages installed on the system,
  the latest is reported by pkg.info_installed (bsc#972490)
  Add:
  * 0012-Force-sort-the-RPM-output-to-ensure-latest-version-o.patch

- Update to the fake 2015.8.8.2 release
  upstream released a bunch of fixes on top of 2015.8.8, without creating a new
  tag and proper release. This commit includes all the changes between tag
  v2015.8.8 and commit ID 596444e2b447b7378dbcdfeb9fc9610b90057745 which
  introduces the fake 2015.8.8.2 release.
  see https://docs.saltstack.com/en/latest/topics/releases/2015.8.8.html#salt-2015-8-8-2

- Update to 2015.8.8
  see https://docs.saltstack.com/en/latest/topics/releases/2015.8.8.html
  Patches renamed:
  * 0004-implement-version_cmp-for-zypper.patch
  * 0005-pylint-changes.patch
  * 0006-Check-if-rpm-python-can-be-imported.patch
  * 0007-Initial-Zypper-Unit-Tests-and-bugfixes.patch
  * 0008-do-not-generate-a-date-in-a-comment-to-prevent-rebui.patch
  * 0009-Bugfix-on-SLE11-series-base-product-reported-as-addi.patch
  * 0010-Use-SHA256-hash-type-by-default.patch
  Patches removed:
  * 0004-Fix-pkg.latest-prevent-crash-on-multiple-package-ins.patch
  * 0005-Fix-package-status-filtering-on-latest-version-and-i.patch
  * 0006-add_key-reject_key-do-not-crash-w-Permission-denied-.patch
  * 0007-Force-kill-websocket-s-child-processes-faster-than-d.patch
  * 0008-Fix-types-in-the-output-data-and-return-just-a-list-.patch
  * 0009-The-functions-in-the-state-module-that-return-a-retc.patch
  * 0010-add-handling-for-OEM-products.patch
  * 0011-improve-doc-for-list_pkgs.patch
  * 0012-implement-version_cmp-for-zypper.patch
  * 0013-pylint-changes.patch
  * 0014-Check-if-rpm-python-can-be-imported.patch
  * 0015-call-zypper-with-option-non-interactive-everywhere.patch
  * 0016-write-a-zypper-command-builder-function.patch
  * 0017-Fix-crash-with-scheduler-and-runners-31106.patch
  * 0018-unify-behavior-of-refresh.patch
  * 0019-add-refresh-option-to-more-functions.patch
  * 0020-simplify-checking-the-refresh-paramater.patch
  * 0021-do-not-change-kwargs-in-refresh-while-checking-a-val.patch
  * 0022-fix-argument-handling-for-pkg.download.patch
  * 0023-Initial-Zypper-Unit-Tests-and-bugfixes.patch
  * 0024-proper-checking-if-zypper-exit-codes-and-handling-of.patch
  * 0025-adapt-tests-to-new-zypper_check_result-output.patch
  * 0026-do-not-generate-a-date-in-a-comment-to-prevent-rebui.patch
  * 0027-make-suse-check-consistent-with-rh_service.patch
  * 0028-fix-numerical-check-of-osrelease.patch
  * 0029-Make-use-of-checksum-configurable-defaults-to-MD5-SH.patch
  * 0030-Bugfix-on-SLE11-series-base-product-reported-as-addi.patch
  * 0031-Only-use-LONGSIZE-in-rpm.info-if-available.-Otherwis.patch
  * 0032-Add-error-check-when-retcode-is-0-but-stderr-is-pres.patch
  * 0033-fixing-init-system-dectection-on-sles-11-refs-31617.patch
  * 0034-Fix-git_pillar-race-condition.patch
  * 0035-Fix-the-always-false-behavior-on-checking-state.patch
  * 0036-Use-SHA256-hash-type-by-default.patch

OBS-URL: https://build.opensuse.org/request/show/391560
OBS-URL: https://build.opensuse.org/package/show/systemsmanagement:saltstack/salt?expand=0&rev=66
2016-04-28 07:26:14 +00:00

351 lines
12 KiB
Diff

From e3a599712daafb88b6b77ebf6c7684fdd10ffedf Mon Sep 17 00:00:00 2001
From: Bo Maryniuk <bo@suse.de>
Date: Wed, 30 Mar 2016 12:14:21 +0200
Subject: [PATCH 07/12] Force-sort the RPM output to ensure latest version of
the multi-package on top of the list.
- Remove version_cmp from the yumpkg and use just a lowpkg alias
- Remove version_cmp from Zypper module and use just lowpkg alias
- Merge yumpkg's and zypper's version_cmp for a common use
- Sort installed pkgs data by version_cmp
- Move "string to EVR" function to the utilities
- Remove suse/redhat checks, refactor code.
- Fix condition from returning None on 0
- Remove tests from the zypper_test that belongs to rpm_test
- Add lowpkg tests for version comparison
- Fix lint
- Fix the documentation
---
salt/modules/rpm.py | 60 +++++++++++++++++++++++++++++++++++++--
salt/modules/yumpkg.py | 28 ++----------------
salt/modules/zypper.py | 58 +------------------------------------
salt/utils/__init__.py | 35 +++++++++++++++++++++++
tests/unit/modules/rpm_test.py | 21 ++++++++++++++
tests/unit/modules/zypper_test.py | 22 --------------
6 files changed, 117 insertions(+), 107 deletions(-)
diff --git a/salt/modules/rpm.py b/salt/modules/rpm.py
index 5d60dd2..6026f18 100644
--- a/salt/modules/rpm.py
+++ b/salt/modules/rpm.py
@@ -17,6 +17,19 @@ import salt.utils.pkg.rpm
# pylint: disable=import-error,redefined-builtin
from salt.ext.six.moves import shlex_quote as _cmd_quote
from salt.ext.six.moves import zip
+
+try:
+ import rpm
+ HAS_RPM = True
+except ImportError:
+ HAS_RPM = False
+
+try:
+ import rpmUtils.miscutils
+ HAS_RPMUTILS = True
+except ImportError:
+ HAS_RPMUTILS = False
+
# pylint: enable=import-error,redefined-builtin
from salt.exceptions import CommandExecutionError, SaltInvocationError
@@ -491,7 +504,7 @@ def info(*packages, **attr):
else:
out = call['stdout']
- ret = dict()
+ _ret = list()
for pkg_info in re.split(r"----*", out):
pkg_info = pkg_info.strip()
if not pkg_info:
@@ -538,6 +551,49 @@ def info(*packages, **attr):
if attr and 'description' in attr or not attr:
pkg_data['description'] = os.linesep.join(descr)
if pkg_name:
- ret[pkg_name] = pkg_data
+ pkg_data['name'] = pkg_name
+ _ret.append(pkg_data)
+
+ # Force-sort package data by version,
+ # pick only latest versions
+ # (in case multiple packages installed, e.g. kernel)
+ ret = dict()
+ for pkg_data in reversed(sorted(_ret, cmp=lambda a_vrs, b_vrs: version_cmp(a_vrs['version'], b_vrs['version']))):
+ pkg_name = pkg_data.pop('name')
+ if pkg_name not in ret:
+ ret[pkg_name] = pkg_data.copy()
return ret
+
+
+def version_cmp(ver1, ver2):
+ '''
+ .. versionadded:: 2015.8.9
+
+ Do a cmp-style comparison on two packages. Return -1 if ver1 < ver2, 0 if
+ ver1 == ver2, and 1 if ver1 > ver2. Return None if there was a problem
+ making the comparison.
+
+ CLI Example:
+
+ .. code-block:: bash
+
+ salt '*' pkg.version_cmp '0.2-001' '0.2.0.1-002'
+ '''
+ try:
+ if HAS_RPM:
+ cmp_func = rpm.labelCompare
+ elif HAS_RPMUTILS:
+ cmp_func = rpmUtils.miscutils.compareEVR
+ else:
+ cmp_func = None
+ cmp_result = cmp_func is None and 2 or cmp_func(salt.utils.str_version_to_evr(ver1),
+ salt.utils.str_version_to_evr(ver2))
+ if cmp_result not in (-1, 0, 1):
+ raise Exception("Comparison result '{0}' is invalid".format(cmp_result))
+
+ return cmp_result
+ except Exception as exc:
+ log.warning("Failed to compare version '{0}' to '{1}' using RPM: {2}".format(ver1, ver2, exc))
+
+ return salt.utils.version_cmp(ver1, ver2)
diff --git a/salt/modules/yumpkg.py b/salt/modules/yumpkg.py
index 1bfc38d..1cde676 100644
--- a/salt/modules/yumpkg.py
+++ b/salt/modules/yumpkg.py
@@ -40,12 +40,6 @@ try:
except ImportError:
from salt.ext.six.moves import configparser
HAS_YUM = False
-
-try:
- import rpmUtils.miscutils
- HAS_RPMUTILS = True
-except ImportError:
- HAS_RPMUTILS = False
# pylint: enable=import-error,redefined-builtin
# Import salt libs
@@ -665,26 +659,8 @@ def version_cmp(pkg1, pkg2):
salt '*' pkg.version_cmp '0.2-001' '0.2.0.1-002'
'''
- if HAS_RPMUTILS:
- try:
- cmp_result = rpmUtils.miscutils.compareEVR(
- rpmUtils.miscutils.stringToVersion(pkg1),
- rpmUtils.miscutils.stringToVersion(pkg2)
- )
- if cmp_result not in (-1, 0, 1):
- raise Exception(
- 'cmp result \'{0}\' is invalid'.format(cmp_result)
- )
- return cmp_result
- except Exception as exc:
- log.warning(
- 'Failed to compare version \'%s\' to \'%s\' using '
- 'rpmUtils: %s', pkg1, pkg2, exc
- )
- # Fall back to distutils.version.LooseVersion (should only need to do
- # this for RHEL5, or if an exception is raised when attempting to compare
- # using rpmUtils)
- return salt.utils.version_cmp(pkg1, pkg2)
+
+ return __salt__['lowpkg.version_cmp'](pkg1, pkg2)
def list_pkgs(versions_as_list=False, **kwargs):
diff --git a/salt/modules/zypper.py b/salt/modules/zypper.py
index 27b00d5..63c473c 100644
--- a/salt/modules/zypper.py
+++ b/salt/modules/zypper.py
@@ -17,12 +17,6 @@ import os
import salt.ext.six as six
from salt.ext.six.moves import configparser
from salt.ext.six.moves.urllib.parse import urlparse as _urlparse
-
-try:
- import rpm
- HAS_RPM = True
-except ImportError:
- HAS_RPM = False
# pylint: enable=import-error,redefined-builtin,no-name-in-module
from xml.dom import minidom as dom
@@ -347,40 +341,6 @@ def version(*names, **kwargs):
return __salt__['pkg_resource.version'](*names, **kwargs) or {}
-def _string_to_evr(verstring):
- '''
- Split the version string into epoch, version and release and
- return this as tuple.
-
- epoch is always not empty.
- version and release can be an empty string if such a component
- could not be found in the version string.
-
- "2:1.0-1.2" => ('2', '1.0', '1.2)
- "1.0" => ('0', '1.0', '')
- "" => ('0', '', '')
- '''
- if verstring in [None, '']:
- return ('0', '', '')
- idx_e = verstring.find(':')
- if idx_e != -1:
- try:
- epoch = str(int(verstring[:idx_e]))
- except ValueError:
- # look, garbage in the epoch field, how fun, kill it
- epoch = '0' # this is our fallback, deal
- else:
- epoch = '0'
- idx_r = verstring.find('-')
- if idx_r != -1:
- version = verstring[idx_e + 1:idx_r]
- release = verstring[idx_r + 1:]
- else:
- version = verstring[idx_e + 1:]
- release = ''
- return (epoch, version, release)
-
-
def version_cmp(ver1, ver2):
'''
.. versionadded:: 2015.5.4
@@ -395,23 +355,7 @@ def version_cmp(ver1, ver2):
salt '*' pkg.version_cmp '0.2-001' '0.2.0.1-002'
'''
- if HAS_RPM:
- try:
- cmp_result = rpm.labelCompare(
- _string_to_evr(ver1),
- _string_to_evr(ver2)
- )
- if cmp_result not in (-1, 0, 1):
- raise Exception(
- 'cmp result \'{0}\' is invalid'.format(cmp_result)
- )
- return cmp_result
- except Exception as exc:
- log.warning(
- 'Failed to compare version \'{0}\' to \'{1}\' using '
- 'rpmUtils: {2}'.format(ver1, ver2, exc)
- )
- return salt.utils.version_cmp(ver1, ver2)
+ return __salt__['lowpkg.version_cmp'](ver1, ver2)
def list_pkgs(versions_as_list=False, **kwargs):
diff --git a/salt/utils/__init__.py b/salt/utils/__init__.py
index f83a677..8956a15 100644
--- a/salt/utils/__init__.py
+++ b/salt/utils/__init__.py
@@ -2881,3 +2881,38 @@ def split_input(val):
return [x.strip() for x in val.split(',')]
except AttributeError:
return [x.strip() for x in str(val).split(',')]
+
+
+def str_version_to_evr(verstring):
+ '''
+ Split the package version string into epoch, version and release.
+ Return this as tuple.
+
+ The epoch is always not empty. The version and the release can be an empty
+ string if such a component could not be found in the version string.
+
+ "2:1.0-1.2" => ('2', '1.0', '1.2)
+ "1.0" => ('0', '1.0', '')
+ "" => ('0', '', '')
+ '''
+ if verstring in [None, '']:
+ return '0', '', ''
+
+ idx_e = verstring.find(':')
+ if idx_e != -1:
+ try:
+ epoch = str(int(verstring[:idx_e]))
+ except ValueError:
+ # look, garbage in the epoch field, how fun, kill it
+ epoch = '0' # this is our fallback, deal
+ else:
+ epoch = '0'
+ idx_r = verstring.find('-')
+ if idx_r != -1:
+ version = verstring[idx_e + 1:idx_r]
+ release = verstring[idx_r + 1:]
+ else:
+ version = verstring[idx_e + 1:]
+ release = ''
+
+ return epoch, version, release
diff --git a/tests/unit/modules/rpm_test.py b/tests/unit/modules/rpm_test.py
index 8bfce9b..f180736 100644
--- a/tests/unit/modules/rpm_test.py
+++ b/tests/unit/modules/rpm_test.py
@@ -95,6 +95,27 @@ class RpmTestCase(TestCase):
self.assertDictEqual(rpm.owner('/usr/bin/python', '/usr/bin/vim'),
ret)
+ @patch('salt.modules.rpm.HAS_RPM', True)
+ def test_version_cmp_rpm(self):
+ '''
+ Test package version is called RPM version if RPM-Python is installed
+
+ :return:
+ '''
+ rpm.rpm = MagicMock(return_value=MagicMock)
+ with patch('salt.modules.rpm.rpm.labelCompare', MagicMock(return_value=0)):
+ self.assertEqual(0, rpm.version_cmp('1', '2')) # mock returns 0, which means RPM was called
+
+ @patch('salt.modules.rpm.HAS_RPM', False)
+ def test_version_cmp_fallback(self):
+ '''
+ Test package version is called RPM version if RPM-Python is installed
+
+ :return:
+ '''
+ rpm.rpm = MagicMock(return_value=MagicMock)
+ with patch('salt.modules.rpm.rpm.labelCompare', MagicMock(return_value=0)):
+ self.assertEqual(-1, rpm.version_cmp('1', '2')) # mock returns -1, a python implementation was called
if __name__ == '__main__':
from integration import run_tests
diff --git a/tests/unit/modules/zypper_test.py b/tests/unit/modules/zypper_test.py
index 5c4eb67..67cf52a 100644
--- a/tests/unit/modules/zypper_test.py
+++ b/tests/unit/modules/zypper_test.py
@@ -301,28 +301,6 @@ class ZypperTestCase(TestCase):
self.assertFalse(zypper.upgrade_available(pkg_name))
self.assertTrue(zypper.upgrade_available('vim'))
- @patch('salt.modules.zypper.HAS_RPM', True)
- def test_version_cmp_rpm(self):
- '''
- Test package version is called RPM version if RPM-Python is installed
-
- :return:
- '''
- with patch('salt.modules.zypper.rpm', MagicMock(return_value=MagicMock)):
- with patch('salt.modules.zypper.rpm.labelCompare', MagicMock(return_value=0)):
- self.assertEqual(0, zypper.version_cmp('1', '2')) # mock returns 0, which means RPM was called
-
- @patch('salt.modules.zypper.HAS_RPM', False)
- def test_version_cmp_fallback(self):
- '''
- Test package version is called RPM version if RPM-Python is installed
-
- :return:
- '''
- with patch('salt.modules.zypper.rpm', MagicMock(return_value=MagicMock)):
- with patch('salt.modules.zypper.rpm.labelCompare', MagicMock(return_value=0)):
- self.assertEqual(-1, zypper.version_cmp('1', '2')) # mock returns -1, a python implementation was called
-
def test_list_pkgs(self):
'''
Test packages listing.
--
2.1.4