Use rpmdev-vercmp as a fallback for version comparison on RHEL5

Resolves #34390.
This commit is contained in:
Erik Johnson 2016-06-30 14:46:03 -05:00
parent 45b8fb10d7
commit 7cefd4182d

View File

@ -586,20 +586,76 @@ def version_cmp(ver1, ver2):
salt '*' pkg.version_cmp '0.2-001' '0.2.0.1-002'
'''
try:
cmp_func = None
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))
try:
cmp_func = rpm.labelCompare
except AttributeError:
# Catches corner case where someone has a module named "rpm" in
# their pythonpath.
log.debug(
'rpm module imported, but it does not have the '
'labelCompare function. Not using rpm.labelCompare for '
'version comparison.'
)
if cmp_func is None and HAS_RPMUTILS:
try:
cmp_func = rpmUtils.miscutils.compareEVR
except AttributeError:
log.debug('rpmUtils.miscutils.compareEVR is not available')
if cmp_func is None:
if salt.utils.which('rpmdev-vercmp'):
# rpmdev-vercmp always uses epochs, even when zero
def _ensure_epoch(ver):
def _prepend(ver):
return '0:{0}'.format(ver)
try:
if ':' not in ver:
return _prepend(ver)
except TypeError:
return _prepend(ver)
return ver
ver1 = _ensure_epoch(ver1)
ver2 = _ensure_epoch(ver2)
result = __salt__['cmd.run'](['rpmdev-vercmp', ver1, ver2],
python_shell=False,
ignore_retcode=True).strip()
if result.endswith('equal'):
return 0
elif 'is newer' in result:
newer_version = result.split()[0]
if newer_version == ver1:
return 1
elif newer_version == ver2:
return -1
log.warning(
'Failed to interpret results of rpmdev-vercmp output: %s',
result
)
else:
# We'll need to fall back to salt.utils.version_cmp()
log.warning(
'rpmdevtools is not installed, please install it for '
'more accurate version comparisons'
)
else:
cmp_result = 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 CommandExecutionError(
'Comparison result \'{0}\' is invalid'.format(cmp_result)
)
return 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))
log.warning(
'Failed to compare version \'%s\' to \'%s\' using RPM: %s',
ver1, ver2, exc
)
return salt.utils.version_cmp(ver1, ver2)