mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge pull request #6574 from terminalmage/issue5270
Abstract version comparison and fix version specification in pip.installed states
This commit is contained in:
commit
9f2018fff4
18 changed files with 182 additions and 447 deletions
|
@ -150,8 +150,13 @@ def latest_version(*names, **kwargs):
|
|||
# If there are no installed versions that are greater than or equal
|
||||
# to the install candidate, then the candidate is an upgrade, so
|
||||
# add it to the return dict
|
||||
if not any([compare(pkg1=x, oper='>=', pkg2=candidate)
|
||||
for x in installed]):
|
||||
if not any(
|
||||
(salt.utils.compare_versions(ver1=x,
|
||||
oper='>=',
|
||||
ver2=candidate,
|
||||
cmp_func=version_cmp)
|
||||
for x in installed)
|
||||
):
|
||||
ret[name] = candidate
|
||||
|
||||
# Return a string if only one package name passed
|
||||
|
@ -629,7 +634,7 @@ def upgrade_available(name):
|
|||
return latest_version(name) != ''
|
||||
|
||||
|
||||
def perform_cmp(pkg1='', pkg2=''):
|
||||
def version_cmp(pkg1, pkg2):
|
||||
'''
|
||||
Do a cmp-style comparison on two packages. Return -1 if pkg1 < pkg2, 0 if
|
||||
pkg1 == pkg2, and 1 if pkg1 > pkg2. Return None if there was a problem
|
||||
|
@ -637,8 +642,7 @@ def perform_cmp(pkg1='', pkg2=''):
|
|||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.perform_cmp '0.2.4-0ubuntu1' '0.2.4.1-0ubuntu1'
|
||||
salt '*' pkg.perform_cmp pkg1='0.2.4-0ubuntu1' pkg2='0.2.4.1-0ubuntu1'
|
||||
salt '*' pkg.version_cmp '0.2.4-0ubuntu1' '0.2.4.1-0ubuntu1'
|
||||
'''
|
||||
try:
|
||||
for oper, ret in (('lt', -1), ('eq', 0), ('gt', 1)):
|
||||
|
@ -651,18 +655,6 @@ def perform_cmp(pkg1='', pkg2=''):
|
|||
return None
|
||||
|
||||
|
||||
def compare(pkg1='', oper='==', pkg2=''):
|
||||
'''
|
||||
Compare two version strings.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.compare '0.2.4-0' '<' '0.2.4.1-0'
|
||||
salt '*' pkg.compare pkg1='0.2.4-0' oper='<' pkg2='0.2.4.1-0'
|
||||
'''
|
||||
return __salt__['pkg_resource.compare'](pkg1=pkg1, oper=oper, pkg2=pkg2)
|
||||
|
||||
|
||||
def _split_repo_str(repo):
|
||||
split = sourceslist.SourceEntry(repo)
|
||||
return split.type, split.uri, split.dist, split.comps
|
||||
|
|
|
@ -278,29 +278,3 @@ def upgrade_available(pkg):
|
|||
salt '*' pkg.upgrade_available <package name>
|
||||
'''
|
||||
return pkg in list_upgrades()
|
||||
|
||||
|
||||
def perform_cmp(pkg1='', pkg2=''):
|
||||
'''
|
||||
Do a cmp-style comparison on two packages. Return -1 if pkg1 < pkg2, 0 if
|
||||
pkg1 == pkg2, and 1 if pkg1 > pkg2. Return None if there was a problem
|
||||
making the comparison.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.perform_cmp '0.2.4-0' '0.2.4.1-0'
|
||||
salt '*' pkg.perform_cmp pkg1='0.2.4-0' pkg2='0.2.4.1-0'
|
||||
'''
|
||||
return __salt__['pkg_resource.perform_cmp'](pkg1=pkg1, pkg2=pkg2)
|
||||
|
||||
|
||||
def compare(pkg1='', oper='==', pkg2=''):
|
||||
'''
|
||||
Compare two version strings.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.compare '0.2.4-0' '<' '0.2.4.1-0'
|
||||
salt '*' pkg.compare pkg1='0.2.4-0' oper='<' pkg2='0.2.4.1-0'
|
||||
'''
|
||||
return __salt__['pkg_resource.compare'](pkg1=pkg1, oper=oper, pkg2=pkg2)
|
||||
|
|
|
@ -132,7 +132,11 @@ def latest_version(*names, **kwargs):
|
|||
installed = _cpv_to_version(_vartree().dep_bestmatch(name))
|
||||
avail = _cpv_to_version(_porttree().dep_bestmatch(name))
|
||||
if avail:
|
||||
if not installed or compare(pkg1=installed, oper='<', pkg2=avail):
|
||||
if not installed \
|
||||
or salt.utils.compare_versions(ver1=installed,
|
||||
oper='<',
|
||||
ver2=avail,
|
||||
cmp_func=version_cmp):
|
||||
ret[name] = avail
|
||||
|
||||
# Return a string if only one package name passed
|
||||
|
@ -221,8 +225,8 @@ def porttree_matches(name):
|
|||
'''
|
||||
matches = []
|
||||
for category in _porttree().dbapi.categories:
|
||||
if _porttree().dbapi.cp_list(category+"/"+name):
|
||||
matches.append(category+"/"+name)
|
||||
if _porttree().dbapi.cp_list(category + "/" + name):
|
||||
matches.append(category + "/" + name)
|
||||
return matches
|
||||
|
||||
|
||||
|
@ -276,7 +280,8 @@ def refresh_db():
|
|||
if 'makeconf.features_contains'in __salt__ and __salt__['makeconf.features_contains']('webrsync-gpg'):
|
||||
# GPG sign verify is supported only for "webrsync"
|
||||
cmd = 'emerge-webrsync -q'
|
||||
if salt.utils.which('emerge-delta-webrsync'): # We prefer 'delta-webrsync' to 'webrsync'
|
||||
# We prefer 'delta-webrsync' to 'webrsync'
|
||||
if salt.utils.which('emerge-delta-webrsync'):
|
||||
cmd = 'emerge-delta-webrsync -q'
|
||||
return __salt__['cmd.retcode'](cmd) == 0
|
||||
else:
|
||||
|
@ -284,7 +289,8 @@ def refresh_db():
|
|||
return True
|
||||
# We fall back to "webrsync" if "rsync" fails for some reason
|
||||
cmd = 'emerge-webrsync -q'
|
||||
if salt.utils.which('emerge-delta-webrsync'): # We prefer 'delta-webrsync' to 'webrsync'
|
||||
# We prefer 'delta-webrsync' to 'webrsync'
|
||||
if salt.utils.which('emerge-delta-webrsync'):
|
||||
cmd = 'emerge-delta-webrsync -q'
|
||||
return __salt__['cmd.retcode'](cmd) == 0
|
||||
|
||||
|
@ -413,7 +419,7 @@ def install(name=None,
|
|||
for param, version_num in pkg_params.iteritems():
|
||||
original_param = param
|
||||
param = _p_to_cp(param)
|
||||
if param == None:
|
||||
if param is None:
|
||||
raise portage.dep.InvalidAtom(original_param)
|
||||
|
||||
if version_num is None:
|
||||
|
@ -442,12 +448,12 @@ def install(name=None,
|
|||
__salt__['portage_config.append_use_flags'](target[1:-1])
|
||||
new = __salt__['portage_config.get_flags_from_package_conf']('use', target[1:-1])
|
||||
if old != new:
|
||||
changes[param+'-USE'] = {'old': old, 'new': new}
|
||||
changes[param + '-USE'] = {'old': old, 'new': new}
|
||||
target = target[:target.rfind('[')] + '"'
|
||||
|
||||
if keyword != None:
|
||||
if keyword is not None:
|
||||
__salt__['portage_config.append_to_package_conf']('accept_keywords', target[1:-1], ['~ARCH'])
|
||||
changes[param+'-ACCEPT_KEYWORD'] = {'old': '', 'new': '~ARCH'}
|
||||
changes[param + '-ACCEPT_KEYWORD'] = {'old': '', 'new': '~ARCH'}
|
||||
|
||||
targets.append(target)
|
||||
else:
|
||||
|
@ -571,7 +577,7 @@ def remove(name=None, slot=None, fromrepo=None, pkgs=None, **kwargs):
|
|||
targets = ['{0}:{1}'.format(fullatom, slot)]
|
||||
if fromrepo is not None:
|
||||
targets = ['{0}::{1}'.format(fullatom, fromrepo)]
|
||||
targets = [ fullatom ]
|
||||
targets = [fullatom]
|
||||
else:
|
||||
targets = [x for x in pkg_params if x in old]
|
||||
|
||||
|
@ -656,7 +662,7 @@ def depclean(name=None, slot=None, fromrepo=None, pkgs=None):
|
|||
targets = ['{0}:{1}'.format(fullatom, slot)]
|
||||
if fromrepo is not None:
|
||||
targets = ['{0}::{1}'.format(fullatom, fromrepo)]
|
||||
targets = [ fullatom ]
|
||||
targets = [fullatom]
|
||||
else:
|
||||
targets = [x for x in pkg_params if x in old]
|
||||
|
||||
|
@ -667,7 +673,7 @@ def depclean(name=None, slot=None, fromrepo=None, pkgs=None):
|
|||
return __salt__['pkg_resource.find_changes'](old, new)
|
||||
|
||||
|
||||
def perform_cmp(pkg1='', pkg2=''):
|
||||
def version_cmp(pkg1, pkg2):
|
||||
'''
|
||||
Do a cmp-style comparison on two packages. Return -1 if pkg1 < pkg2, 0 if
|
||||
pkg1 == pkg2, and 1 if pkg1 > pkg2. Return None if there was a problem
|
||||
|
@ -675,8 +681,7 @@ def perform_cmp(pkg1='', pkg2=''):
|
|||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.perform_cmp '0.2.4-0' '0.2.4.1-0'
|
||||
salt '*' pkg.perform_cmp pkg1='0.2.4-0' pkg2='0.2.4.1-0'
|
||||
salt '*' pkg.version_cmp '0.2.4-0' '0.2.4.1-0'
|
||||
'''
|
||||
regex = r'^~?([^:\[]+):?[^\[]*\[?.*$'
|
||||
ver1 = re.match(regex, pkg1)
|
||||
|
@ -687,18 +692,6 @@ def perform_cmp(pkg1='', pkg2=''):
|
|||
return None
|
||||
|
||||
|
||||
def compare(pkg1='', oper='==', pkg2=''):
|
||||
'''
|
||||
Compare two version strings.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.compare '0.2.4-0' '<' '0.2.4.1-0'
|
||||
salt '*' pkg.compare pkg1='0.2.4-0' oper='<' pkg2='0.2.4.1-0'
|
||||
'''
|
||||
return __salt__['pkg_resource.compare'](pkg1=pkg1, oper=oper, pkg2=pkg2)
|
||||
|
||||
|
||||
def version_clean(version):
|
||||
'''
|
||||
Clean the version string removing extra data.
|
||||
|
@ -752,7 +745,8 @@ def check_extra_requirements(pkgname, pkgver):
|
|||
|
||||
des_uses = set(portage.dep.dep_getusedeps(atom))
|
||||
cur_use = cur_use.split()
|
||||
if len([ x for x in des_uses.difference(cur_use) if x[0]!='-' or x[1:] in cur_use ]) > 0:
|
||||
if len([x for x in des_uses.difference(cur_use)
|
||||
if x[0] != '-' or x[1:] in cur_use]) > 0:
|
||||
return False
|
||||
|
||||
if keyword:
|
||||
|
|
|
@ -391,32 +391,6 @@ def rehash():
|
|||
__salt__['cmd.run_all']('rehash')
|
||||
|
||||
|
||||
def perform_cmp(pkg1='', pkg2=''):
|
||||
'''
|
||||
Do a cmp-style comparison on two packages. Return -1 if pkg1 < pkg2, 0 if
|
||||
pkg1 == pkg2, and 1 if pkg1 > pkg2. Return None if there was a problem
|
||||
making the comparison.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.perform_cmp '0.2.4-0' '0.2.4.1-0'
|
||||
salt '*' pkg.perform_cmp pkg1='0.2.4-0' pkg2='0.2.4.1-0'
|
||||
'''
|
||||
return __salt__['pkg_resource.perform_cmp'](pkg1=pkg1, pkg2=pkg2)
|
||||
|
||||
|
||||
def compare(pkg1='', oper='==', pkg2=''):
|
||||
'''
|
||||
Compare two version strings.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.compare '0.2.4-0' '<' '0.2.4.1-0'
|
||||
salt '*' pkg.compare pkg1='0.2.4-0' oper='<' pkg2='0.2.4.1-0'
|
||||
'''
|
||||
return __salt__['pkg_resource.compare'](pkg1=pkg1, oper=oper, pkg2=pkg2)
|
||||
|
||||
|
||||
def file_list(*packages):
|
||||
'''
|
||||
List the files that belong to a package. Not specifying any packages will
|
||||
|
|
|
@ -222,29 +222,3 @@ def purge(name=None, pkgs=None, **kwargs):
|
|||
salt '*' pkg.purge pkgs='["foo", "bar"]'
|
||||
'''
|
||||
return remove(name=name, pkgs=pkgs)
|
||||
|
||||
|
||||
def perform_cmp(pkg1='', pkg2=''):
|
||||
'''
|
||||
Do a cmp-style comparison on two packages. Return -1 if pkg1 < pkg2, 0 if
|
||||
pkg1 == pkg2, and 1 if pkg1 > pkg2. Return None if there was a problem
|
||||
making the comparison.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.perform_cmp '0.2.4' '0.2.4.1'
|
||||
salt '*' pkg.perform_cmp pkg1='0.2.4' pkg2='0.2.4.1'
|
||||
'''
|
||||
return __salt__['pkg_resource.perform_cmp'](pkg1=pkg1, pkg2=pkg2)
|
||||
|
||||
|
||||
def compare(pkg1='', oper='==', pkg2=''):
|
||||
'''
|
||||
Compare two version strings.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.compare '0.2.4' '<' '0.2.4.1'
|
||||
salt '*' pkg.compare pkg1='0.2.4' oper='<' pkg2='0.2.4.1'
|
||||
'''
|
||||
return __salt__['pkg_resource.compare'](pkg1=pkg1, oper=oper, pkg2=pkg2)
|
||||
|
|
|
@ -396,32 +396,6 @@ def purge(name=None, pkgs=None, **kwargs):
|
|||
return _uninstall(action='purge', name=name, pkgs=pkgs)
|
||||
|
||||
|
||||
def perform_cmp(pkg1='', pkg2=''):
|
||||
'''
|
||||
Do a cmp-style comparison on two packages. Return -1 if pkg1 < pkg2, 0 if
|
||||
pkg1 == pkg2, and 1 if pkg1 > pkg2. Return None if there was a problem
|
||||
making the comparison.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.perform_cmp '0.2.4-0' '0.2.4.1-0'
|
||||
salt '*' pkg.perform_cmp pkg1='0.2.4-0' pkg2='0.2.4.1-0'
|
||||
'''
|
||||
return __salt__['pkg_resource.perform_cmp'](pkg1=pkg1, pkg2=pkg2)
|
||||
|
||||
|
||||
def compare(pkg1='', oper='==', pkg2=''):
|
||||
'''
|
||||
Compare two version strings.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.compare '0.2.4-0' '<' '0.2.4.1-0'
|
||||
salt '*' pkg.compare pkg1='0.2.4-0' oper='<' pkg2='0.2.4.1-0'
|
||||
'''
|
||||
return __salt__['pkg_resource.compare'](pkg1=pkg1, oper=oper, pkg2=pkg2)
|
||||
|
||||
|
||||
def file_list(*packages):
|
||||
'''
|
||||
List the files that belong to a package. Not specifying any packages will
|
||||
|
|
|
@ -3,7 +3,6 @@ Resources needed by pkg providers
|
|||
'''
|
||||
|
||||
# Import python libs
|
||||
import distutils.version # pylint: disable=E0611
|
||||
import fnmatch
|
||||
import logging
|
||||
import os
|
||||
|
@ -419,62 +418,10 @@ def find_changes(old=None, new=None):
|
|||
return pkgs
|
||||
|
||||
|
||||
def perform_cmp(pkg1='', pkg2=''):
|
||||
'''
|
||||
Compares two version strings using distutils.version.LooseVersion. This is
|
||||
a fallback for providers which don't have a version comparison utility
|
||||
built into them. Return -1 if version1 < version2, 0 if version1 ==
|
||||
version2, and 1 if version1 > version2. Return None if there was a problem
|
||||
making the comparison.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg_resource.perform_cmp
|
||||
'''
|
||||
try:
|
||||
if distutils.version.LooseVersion(pkg1) < \
|
||||
distutils.version.LooseVersion(pkg2):
|
||||
return -1
|
||||
elif distutils.version.LooseVersion(pkg1) == \
|
||||
distutils.version.LooseVersion(pkg2):
|
||||
return 0
|
||||
elif distutils.version.LooseVersion(pkg1) > \
|
||||
distutils.version.LooseVersion(pkg2):
|
||||
return 1
|
||||
except Exception as e:
|
||||
log.exception(e)
|
||||
return None
|
||||
|
||||
|
||||
def compare(pkg1='', oper='==', pkg2=''):
|
||||
'''
|
||||
Package version comparison function.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg_resource.compare
|
||||
'''
|
||||
cmp_map = {'<': (-1,), '<=': (-1, 0), '==': (0,),
|
||||
'>=': (0, 1), '>': (1,)}
|
||||
if oper not in ['!='] + cmp_map.keys():
|
||||
log.error('Invalid operator "{0}" for package '
|
||||
'comparison'.format(oper))
|
||||
return False
|
||||
|
||||
cmp_result = __salt__['pkg.perform_cmp'](pkg1, pkg2)
|
||||
if cmp_result is None:
|
||||
return False
|
||||
|
||||
if oper == '!=':
|
||||
return cmp_result not in cmp_map['==']
|
||||
else:
|
||||
return cmp_result in cmp_map[oper]
|
||||
|
||||
|
||||
def version_clean(version):
|
||||
'''
|
||||
Clean the version string removing extra data.
|
||||
This function will simply try to call "pkg.version_clean".
|
||||
This function will simply try to call ``pkg.version_clean``.
|
||||
|
||||
CLI Example::
|
||||
|
||||
|
|
|
@ -423,32 +423,6 @@ def rehash():
|
|||
__salt__['cmd.run']('rehash')
|
||||
|
||||
|
||||
def perform_cmp(pkg1='', pkg2=''):
|
||||
'''
|
||||
Do a cmp-style comparison on two packages. Return -1 if pkg1 < pkg2, 0 if
|
||||
pkg1 == pkg2, and 1 if pkg1 > pkg2. Return None if there was a problem
|
||||
making the comparison.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.perform_cmp '0.2.4-0' '0.2.4.1-0'
|
||||
salt '*' pkg.perform_cmp pkg1='0.2.4-0' pkg2='0.2.4.1-0'
|
||||
'''
|
||||
return __salt__['pkg_resource.perform_cmp'](pkg1=pkg1, pkg2=pkg2)
|
||||
|
||||
|
||||
def compare(pkg1='', oper='==', pkg2=''):
|
||||
'''
|
||||
Compare two version strings.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.compare '0.2.4-0' '<' '0.2.4.1-0'
|
||||
salt '*' pkg.compare pkg1='0.2.4-0' oper='<' pkg2='0.2.4.1-0'
|
||||
'''
|
||||
return __salt__['pkg_resource.compare'](pkg1=pkg1, oper=oper, pkg2=pkg2)
|
||||
|
||||
|
||||
def file_list(package):
|
||||
'''
|
||||
List the files that belong to a package.
|
||||
|
|
|
@ -857,29 +857,3 @@ def updating(pkg_name, filedate=None, filename=None):
|
|||
|
||||
cmd = 'pkg updating {0} {1}'.format(opts, pkg_name)
|
||||
return __salt__['cmd.run'](cmd)
|
||||
|
||||
|
||||
def perform_cmp(pkg1='', pkg2=''):
|
||||
'''
|
||||
Do a cmp-style comparison on two packages. Return -1 if pkg1 < pkg2, 0 if
|
||||
pkg1 == pkg2, and 1 if pkg1 > pkg2. Return None if there was a problem
|
||||
making the comparison.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.perform_cmp '0.2.4-0' '0.2.4.1-0'
|
||||
salt '*' pkg.perform_cmp pkg1='0.2.4-0' pkg2='0.2.4.1-0'
|
||||
'''
|
||||
return __salt__['pkg_resource.perform_cmp'](pkg1=pkg1, pkg2=pkg2)
|
||||
|
||||
|
||||
def compare(pkg1='', oper='==', pkg2=''):
|
||||
'''
|
||||
Compare two version strings.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.compare '0.2.4-0' '<' '0.2.4.1-0'
|
||||
salt '*' pkg.compare pkg1='0.2.4-0' oper='<' pkg2='0.2.4.1-0'
|
||||
'''
|
||||
return __salt__['pkg_resource.compare'](pkg1=pkg1, oper=oper, pkg2=pkg2)
|
||||
|
|
|
@ -194,7 +194,9 @@ def latest_version(*names, **kwargs):
|
|||
if name in names:
|
||||
cver = pkgs.get(name, '')
|
||||
nver = version_rev.split(',')[0]
|
||||
if not cver or compare(pkg1=cver, oper='<', pkg2=nver):
|
||||
if not cver or salt.utils.compare_versions(ver1=cver,
|
||||
oper='<',
|
||||
ver2=nver):
|
||||
# Remove revision for version comparison
|
||||
ret[name] = version_rev
|
||||
|
||||
|
@ -326,29 +328,3 @@ def purge(name=None, pkgs=None, **kwargs):
|
|||
salt '*' pkg.purge pkgs='["foo", "bar"]'
|
||||
'''
|
||||
return remove(name=name, pkgs=pkgs)
|
||||
|
||||
|
||||
def perform_cmp(pkg1='', pkg2=''):
|
||||
'''
|
||||
Do a cmp-style comparison on two packages. Return -1 if pkg1 < pkg2, 0 if
|
||||
pkg1 == pkg2, and 1 if pkg1 > pkg2. Return None if there was a problem
|
||||
making the comparison.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.perform_cmp '0.2.4-0' '0.2.4.1-0'
|
||||
salt '*' pkg.perform_cmp pkg1='0.2.4-0' pkg2='0.2.4.1-0'
|
||||
'''
|
||||
return __salt__['pkg_resource.perform_cmp'](pkg1=pkg1, pkg2=pkg2)
|
||||
|
||||
|
||||
def compare(pkg1='', oper='==', pkg2=''):
|
||||
'''
|
||||
Compare two version strings.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.compare '0.2.4-0' '<' '0.2.4.1-0'
|
||||
salt '*' pkg.compare pkg1='0.2.4-0' oper='<' pkg2='0.2.4.1-0'
|
||||
'''
|
||||
return __salt__['pkg_resource.compare'](pkg1=pkg1, oper=oper, pkg2=pkg2)
|
||||
|
|
|
@ -436,29 +436,3 @@ def purge(name=None, pkgs=None, **kwargs):
|
|||
salt '*' pkg.purge pkgs='["foo", "bar"]'
|
||||
'''
|
||||
return remove(name=name, pkgs=pkgs, **kwargs)
|
||||
|
||||
|
||||
def perform_cmp(pkg1='', pkg2=''):
|
||||
'''
|
||||
Do a cmp-style comparison on two packages. Return -1 if pkg1 < pkg2, 0 if
|
||||
pkg1 == pkg2, and 1 if pkg1 > pkg2. Return None if there was a problem
|
||||
making the comparison.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.perform_cmp '0.2.4-0' '0.2.4.1-0'
|
||||
salt '*' pkg.perform_cmp pkg1='0.2.4-0' pkg2='0.2.4.1-0'
|
||||
'''
|
||||
return __salt__['pkg_resource.perform_cmp'](pkg1=pkg1, pkg2=pkg2)
|
||||
|
||||
|
||||
def compare(pkg1='', oper='==', pkg2=''):
|
||||
'''
|
||||
Compare two version strings.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.compare '0.2.4-0' '<' '0.2.4.1-0'
|
||||
salt '*' pkg.compare pkg1='0.2.4-0' oper='<' pkg2='0.2.4.1-0'
|
||||
'''
|
||||
return __salt__['pkg_resource.compare'](pkg1=pkg1, oper=oper, pkg2=pkg2)
|
||||
|
|
|
@ -706,29 +706,3 @@ def _get_latest_pkg_version(pkginfo):
|
|||
return pkginfo.keys().pop()
|
||||
pkgkeys = pkginfo.keys()
|
||||
return sorted(pkgkeys, cmp=_reverse_cmp_pkg_versions).pop()
|
||||
|
||||
|
||||
def perform_cmp(pkg1='', pkg2=''):
|
||||
'''
|
||||
Do a cmp-style comparison on two packages. Return -1 if pkg1 < pkg2, 0 if
|
||||
pkg1 == pkg2, and 1 if pkg1 > pkg2. Return None if there was a problem
|
||||
making the comparison.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.perform_cmp '0.2.4-0' '0.2.4.1-0'
|
||||
salt '*' pkg.perform_cmp pkg1='0.2.4-0' pkg2='0.2.4.1-0'
|
||||
'''
|
||||
return __salt__['pkg_resource.perform_cmp'](pkg1=pkg1, pkg2=pkg2)
|
||||
|
||||
|
||||
def compare(pkg1='', oper='==', pkg2=''):
|
||||
'''
|
||||
Compare two version strings.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.compare '0.2.4-0' '<' '0.2.4.1-0'
|
||||
salt '*' pkg.compare pkg1='0.2.4-0' oper='<' pkg2='0.2.4.1-0'
|
||||
'''
|
||||
return __salt__['pkg_resource.compare'](pkg1=pkg1, oper=oper, pkg2=pkg2)
|
||||
|
|
|
@ -1039,32 +1039,6 @@ def _parse_repo_file(filename):
|
|||
return (header, repos)
|
||||
|
||||
|
||||
def perform_cmp(pkg1='', pkg2=''):
|
||||
'''
|
||||
Do a cmp-style comparison on two packages. Return -1 if pkg1 < pkg2, 0 if
|
||||
pkg1 == pkg2, and 1 if pkg1 > pkg2. Return None if there was a problem
|
||||
making the comparison.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.perform_cmp '0.2.4-0' '0.2.4.1-0'
|
||||
salt '*' pkg.perform_cmp pkg1='0.2.4-0' pkg2='0.2.4.1-0'
|
||||
'''
|
||||
return __salt__['pkg_resource.perform_cmp'](pkg1=pkg1, pkg2=pkg2)
|
||||
|
||||
|
||||
def compare(pkg1='', oper='==', pkg2=''):
|
||||
'''
|
||||
Compare two version strings.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.compare '0.2.4-0' '<' '0.2.4.1-0'
|
||||
salt '*' pkg.compare pkg1='0.2.4-0' oper='<' pkg2='0.2.4.1-0'
|
||||
'''
|
||||
return __salt__['pkg_resource.compare'](pkg1=pkg1, oper=oper, pkg2=pkg2)
|
||||
|
||||
|
||||
def file_list(*packages):
|
||||
'''
|
||||
List the files that belong to a package. Not specifying any packages will
|
||||
|
|
|
@ -505,29 +505,3 @@ def purge(name=None, pkgs=None, **kwargs):
|
|||
salt '*' pkg.purge pkgs='["foo", "bar"]'
|
||||
'''
|
||||
return remove(name=name, pkgs=pkgs)
|
||||
|
||||
|
||||
def perform_cmp(pkg1='', pkg2=''):
|
||||
'''
|
||||
Do a cmp-style comparison on two packages. Return -1 if pkg1 < pkg2, 0 if
|
||||
pkg1 == pkg2, and 1 if pkg1 > pkg2. Return None if there was a problem
|
||||
making the comparison.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.perform_cmp '0.2.4-0' '0.2.4.1-0'
|
||||
salt '*' pkg.perform_cmp pkg1='0.2.4-0' pkg2='0.2.4.1-0'
|
||||
'''
|
||||
return __salt__['pkg_resource.perform_cmp'](pkg1=pkg1, pkg2=pkg2)
|
||||
|
||||
|
||||
def compare(pkg1='', oper='==', pkg2=''):
|
||||
'''
|
||||
Compare two version strings.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.compare '0.2.4-0' '<' '0.2.4.1-0'
|
||||
salt '*' pkg.compare pkg1='0.2.4-0' oper='<' pkg2='0.2.4.1-0'
|
||||
'''
|
||||
return __salt__['pkg_resource.compare'](pkg1=pkg1, oper=oper, pkg2=pkg2)
|
||||
|
|
|
@ -419,29 +419,3 @@ def purge(name=None, pkgs=None, **kwargs):
|
|||
salt '*' pkg.purge pkgs='["foo", "bar"]'
|
||||
'''
|
||||
return _uninstall(action='purge', name=name, pkgs=pkgs)
|
||||
|
||||
|
||||
def perform_cmp(pkg1='', pkg2=''):
|
||||
'''
|
||||
Do a cmp-style comparison on two packages. Return -1 if pkg1 < pkg2, 0 if
|
||||
pkg1 == pkg2, and 1 if pkg1 > pkg2. Return None if there was a problem
|
||||
making the comparison.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.perform_cmp '0.2.4-0' '0.2.4.1-0'
|
||||
salt '*' pkg.perform_cmp pkg1='0.2.4-0' pkg2='0.2.4.1-0'
|
||||
'''
|
||||
return __salt__['pkg_resource.perform_cmp'](pkg1=pkg1, pkg2=pkg2)
|
||||
|
||||
|
||||
def compare(pkg1='', oper='==', pkg2=''):
|
||||
'''
|
||||
Compare two version strings.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.compare '0.2.4-0' '<' '0.2.4.1-0'
|
||||
salt '*' pkg.compare pkg1='0.2.4-0' oper='<' pkg2='0.2.4.1-0'
|
||||
'''
|
||||
return __salt__['pkg_resource.compare'](pkg1=pkg1, oper=oper, pkg2=pkg2)
|
||||
|
|
|
@ -19,6 +19,7 @@ requisite to a pkg.installed state for the package which provides pip
|
|||
'''
|
||||
|
||||
# Import python libs
|
||||
import re
|
||||
import urlparse
|
||||
|
||||
# Import salt libs
|
||||
|
@ -33,6 +34,34 @@ def __virtual__():
|
|||
return 'pip' if 'pip.list' in __salt__ else False
|
||||
|
||||
|
||||
def _find_key(prefix, pip_list):
|
||||
'''
|
||||
Does a case-insensitive match in the pip_list for the desired package.
|
||||
'''
|
||||
try:
|
||||
match = next(
|
||||
iter(x for x in pip_list if x.lower() == prefix.lower())
|
||||
)
|
||||
except StopIteration:
|
||||
return None
|
||||
else:
|
||||
return match
|
||||
|
||||
|
||||
def _fulfills_version_spec(version, version_spec):
|
||||
'''
|
||||
Check version number against version specification info and return a
|
||||
boolean value based on whether or not the version number meets the
|
||||
specified version.
|
||||
'''
|
||||
for oper, spec in (version_spec[0:2], version_spec[2:4]):
|
||||
if oper is None:
|
||||
continue
|
||||
if not salt.utils.compare_versions(ver1=version, oper=oper, ver2=spec):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def installed(name,
|
||||
pip_bin=None,
|
||||
requirements=None,
|
||||
|
@ -87,17 +116,38 @@ def installed(name,
|
|||
elif env and not bin_env:
|
||||
bin_env = env
|
||||
|
||||
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
||||
|
||||
scheme, netloc, path, query, fragment = urlparse.urlsplit(name)
|
||||
if scheme and netloc:
|
||||
# parse as VCS url
|
||||
prefix = path.lstrip('/').split('@', 1)[0]
|
||||
if scheme.startswith("git+"):
|
||||
prefix = prefix.rstrip(".git")
|
||||
if scheme.startswith('git+'):
|
||||
prefix = prefix.rstrip('.git')
|
||||
else:
|
||||
# Pull off any requirements specifiers
|
||||
prefix = name.split('=')[0].split('<')[0].split('>')[0].strip()
|
||||
# Split the passed string into the prefix and version
|
||||
try:
|
||||
version_spec = list(re.match(
|
||||
(r'([^=<>]+)(?:(?:([<>]=?|==?)([^<>=,]+))'
|
||||
r'(?:,([<>]=?|==?)([^<>=]+))?)?$'),
|
||||
name
|
||||
).groups())
|
||||
prefix = version_spec.pop(0)
|
||||
except AttributeError:
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Invalidly-formatted package {0}'.format(name)
|
||||
return ret
|
||||
else:
|
||||
# Check to see if '=' was used instead of '=='. version_spec will
|
||||
# contain two sets of comparison operators and version numbers, so
|
||||
# we are checking elements 0 and 2 of this list.
|
||||
if any((version_spec[x] == '=' for x in (0, 2))):
|
||||
ret['result'] = False
|
||||
ret['comment'] = ('Invalid version specification in '
|
||||
'package {0}. \'=\' is not supported, use '
|
||||
'\'==\' instead.'.format(name))
|
||||
return ret
|
||||
|
||||
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
||||
if runas is not None:
|
||||
# The user is using a deprecated argument, warn!
|
||||
msg = (
|
||||
|
@ -107,41 +157,48 @@ def installed(name,
|
|||
salt.utils.warn_until((0, 18), msg)
|
||||
ret.setdefault('warnings', []).append(msg)
|
||||
|
||||
# "There can only be one"
|
||||
if runas is not None and user:
|
||||
raise CommandExecutionError(
|
||||
'The \'runas\' and \'user\' arguments are mutually exclusive. '
|
||||
'Please use \'user\' as \'runas\' is being deprecated.'
|
||||
)
|
||||
# Support deprecated 'runas' arg
|
||||
elif runas is not None and not user:
|
||||
user = runas
|
||||
# "There can only be one"
|
||||
if user:
|
||||
raise CommandExecutionError(
|
||||
'The \'runas\' and \'user\' arguments are mutually exclusive. '
|
||||
'Please use \'user\' as \'runas\' is being deprecated.'
|
||||
)
|
||||
# Support deprecated 'runas' arg
|
||||
else:
|
||||
user = runas
|
||||
|
||||
try:
|
||||
pip_list = __salt__['pip.list'](prefix, bin_env, user=user, cwd=cwd)
|
||||
pip_list = __salt__['pip.list'](prefix, bin_env=bin_env,
|
||||
user=user, cwd=cwd)
|
||||
prefix_realname = _find_key(prefix, pip_list)
|
||||
except (CommandNotFoundError, CommandExecutionError) as err:
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Error installing \'{0}\': {1}'.format(name, err)
|
||||
return ret
|
||||
|
||||
if ignore_installed is False and prefix.lower() in (p.lower()
|
||||
for p in pip_list):
|
||||
if force_reinstall is False and upgrade is False:
|
||||
ret['result'] = True
|
||||
ret['comment'] = 'Package already installed'
|
||||
return ret
|
||||
if ignore_installed is False and prefix_realname is not None:
|
||||
if force_reinstall is False and not upgrade:
|
||||
# Check desired version (if any) against currently-installed
|
||||
if (
|
||||
any(version_spec) and
|
||||
_fulfills_version_spec(pip_list[prefix_realname],
|
||||
version_spec)
|
||||
) or (not any(version_spec)):
|
||||
ret['result'] = True
|
||||
ret['comment'] = ('Python package {0} already '
|
||||
'installed'.format(name))
|
||||
return ret
|
||||
|
||||
if __opts__['test']:
|
||||
ret['result'] = None
|
||||
ret['comment'] = 'Python package {0} is set to be installed'.format(
|
||||
name)
|
||||
ret['comment'] = \
|
||||
'Python package {0} is set to be installed'.format(name)
|
||||
return ret
|
||||
|
||||
# Replace commas (used for version ranges) with semicolons (which are not
|
||||
# supported) in name so it does not treat them as multiple packages. Comma
|
||||
# will be re-added in pip.install call. Wrap in double quotes to allow for
|
||||
# version ranges
|
||||
name = '"' + name.replace(',', ';') + '"'
|
||||
# will be re-added in pip.install call.
|
||||
name = name.replace(',', ';')
|
||||
|
||||
if repo:
|
||||
name = repo
|
||||
|
@ -153,7 +210,7 @@ def installed(name,
|
|||
name = ''
|
||||
|
||||
pip_install_call = __salt__['pip.install'](
|
||||
pkgs=name,
|
||||
pkgs='"{0}"'.format(name),
|
||||
requirements=requirements,
|
||||
bin_env=bin_env,
|
||||
log=log,
|
||||
|
|
|
@ -65,13 +65,16 @@ def __gen_rtag():
|
|||
return os.path.join(__opts__['cachedir'], 'pkg_refresh')
|
||||
|
||||
|
||||
def _fulfills_version_spec(versions, oper, desired_version):
|
||||
def _fulfills_version_spec(version, oper, desired_version):
|
||||
'''
|
||||
Returns True if any of the installed versions match the specified version,
|
||||
otherwise returns False
|
||||
'''
|
||||
for ver in versions:
|
||||
if __salt__['pkg.compare'](pkg1=ver, oper=oper, pkg2=desired_version):
|
||||
if salt.utils.compare_versions(ver1=version,
|
||||
oper=oper,
|
||||
ver2=desired_version,
|
||||
cmp_func=__salt__.get('version_cmp')):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
@ -170,7 +173,7 @@ def _find_install_targets(name=None, version=None, pkgs=None, sources=None):
|
|||
comparison = gt_lt or ''
|
||||
comparison += eq or ''
|
||||
# A comparison operator of "=" is redundant, but possible.
|
||||
# Change it to "==" so that it works in pkg.compare.
|
||||
# Change it to "==" so that the version comparison works
|
||||
if comparison in ['=', '']:
|
||||
comparison = '=='
|
||||
if not _fulfills_version_spec(cver, comparison, verstr):
|
||||
|
@ -215,7 +218,7 @@ def _verify_install(desired, new_pkgs):
|
|||
comparison = gt_lt or ''
|
||||
comparison += eq or ''
|
||||
# A comparison operator of "=" is redundant, but possible.
|
||||
# Change it to "==" so that it works in pkg.compare.
|
||||
# Change it to "==" so that the version comparison works.
|
||||
if comparison in ('=', ''):
|
||||
comparison = '=='
|
||||
if _fulfills_version_spec(cver, comparison, verstr):
|
||||
|
@ -557,10 +560,12 @@ def latest(
|
|||
msg = 'No information found for "{0}".'.format(pkg)
|
||||
log.error(msg)
|
||||
problems.append(msg)
|
||||
elif not cur[pkg] or \
|
||||
__salt__['pkg.compare'](pkg1=cur[pkg],
|
||||
oper='<',
|
||||
pkg2=avail[pkg]):
|
||||
elif not cur[pkg] \
|
||||
or salt.utils.compare_versions(
|
||||
ver1=cur[pkg],
|
||||
oper='<',
|
||||
ver2=avail[pkg],
|
||||
cmp_func=__salt__.get('version_cmp')):
|
||||
targets[pkg] = avail[pkg]
|
||||
|
||||
if problems:
|
||||
|
@ -608,7 +613,8 @@ def latest(
|
|||
|
||||
if changes:
|
||||
# Find failed and successful updates
|
||||
failed = [x for x in targets if changes[x]['new'] != targets[x]]
|
||||
failed = [x for x in targets
|
||||
if not changes.get(x) or changes[x]['new'] != targets[x]]
|
||||
successful = [x for x in targets if x not in failed]
|
||||
|
||||
comments = []
|
||||
|
|
|
@ -5,6 +5,7 @@ from __future__ import absolute_import
|
|||
|
||||
# Import python libs
|
||||
import datetime
|
||||
import distutils.version # pylint: disable=E0611
|
||||
import fnmatch
|
||||
import hashlib
|
||||
import imp
|
||||
|
@ -1389,3 +1390,51 @@ def warn_until(version_info,
|
|||
|
||||
if _dont_call_warnings is False:
|
||||
warnings.warn(message, category, stacklevel=stacklevel)
|
||||
|
||||
|
||||
def version_cmp(pkg1, pkg2):
|
||||
'''
|
||||
Compares two version strings using distutils.version.LooseVersion. This is
|
||||
a fallback for providers which don't have a version comparison utility
|
||||
built into them. Return -1 if version1 < version2, 0 if version1 ==
|
||||
version2, and 1 if version1 > version2. Return None if there was a problem
|
||||
making the comparison.
|
||||
'''
|
||||
try:
|
||||
if distutils.version.LooseVersion(pkg1) < \
|
||||
distutils.version.LooseVersion(pkg2):
|
||||
return -1
|
||||
elif distutils.version.LooseVersion(pkg1) == \
|
||||
distutils.version.LooseVersion(pkg2):
|
||||
return 0
|
||||
elif distutils.version.LooseVersion(pkg1) > \
|
||||
distutils.version.LooseVersion(pkg2):
|
||||
return 1
|
||||
except Exception as e:
|
||||
log.exception(e)
|
||||
return None
|
||||
|
||||
|
||||
def compare_versions(ver1='', oper='==', ver2='', cmp_func=None):
|
||||
'''
|
||||
Compares two version numbers. Accepts a custom function to perform the
|
||||
cmp-style version comparison, otherwise uses version_cmp().
|
||||
'''
|
||||
cmp_map = {'<': (-1,), '<=': (-1, 0), '==': (0,),
|
||||
'>=': (0, 1), '>': (1,)}
|
||||
if oper not in ['!='] + cmp_map.keys():
|
||||
log.error('Invalid operator "{0}" for version '
|
||||
'comparison'.format(oper))
|
||||
return False
|
||||
|
||||
if cmp_func is None:
|
||||
cmp_func = version_cmp
|
||||
|
||||
cmp_result = cmp_func(ver1, ver2)
|
||||
if cmp_result is None:
|
||||
return False
|
||||
|
||||
if oper == '!=':
|
||||
return cmp_result not in cmp_map['==']
|
||||
else:
|
||||
return cmp_result in cmp_map[oper]
|
||||
|
|
Loading…
Add table
Reference in a new issue