Add pkg.list_repo_pkgs to zypper.py

This commit is contained in:
Erik Johnson 2018-03-14 23:33:51 -05:00
parent ee3bff6e32
commit 214f2d6ad3
No known key found for this signature in database
GPG Key ID: 5E5583C437808F3F

View File

@ -706,6 +706,123 @@ def list_pkgs(versions_as_list=False, **kwargs):
return ret
def list_repo_pkgs(*args, **kwargs):
'''
.. versionadded:: 2017.7.5
Returns all available packages. Optionally, package names (and name globs)
can be passed and the results will be filtered to packages matching those
names. This is recommended as it speeds up the function considerably.
This function can be helpful in discovering the version or repo to specify
in a :mod:`pkg.installed <salt.states.pkg.installed>` state.
The return data will be a dictionary mapping package names to a list of
version numbers, ordered from newest to oldest. If ``byrepo`` is set to
``True``, then the return dictionary will contain repository names at the
top level, and each repository will map packages to lists of version
numbers. For example:
.. code-block:: python
# With byrepo=False (default)
{
'bash': ['4.3-83.3.1',
'4.3-82.6'],
'vim': ['7.4.326-12.1']
}
{
'OSS': {
'bash': ['4.3-82.6'],
'vim': ['7.4.326-12.1']
},
'OSS Update': {
'bash': ['4.3-83.3.1']
}
}
fromrepo : None
Only include results from the specified repo(s). Multiple repos can be
specified, comma-separated.
byrepo : False
When ``True``, the return data for each package will be organized by
repository.
CLI Examples:
.. code-block:: bash
salt '*' pkg.list_repo_pkgs
salt '*' pkg.list_repo_pkgs foo bar baz
salt '*' pkg.list_repo_pkgs 'python2-*' byrepo=True
salt '*' pkg.list_repo_pkgs 'python2-*' fromrepo='OSS Updates'
'''
byrepo = kwargs.pop('byrepo', False)
fromrepo = kwargs.pop('fromrepo', '') or ''
ret = {}
targets = [
arg if isinstance(arg, six.string_types) else six.text_type(arg)
for arg in args
]
def _is_match(pkgname):
'''
When package names are passed to a zypper search, they will be matched
anywhere in the package name. This makes sure that only exact or
fnmatch matches are identified.
'''
if not args:
# No package names passed, everyone's a winner!
return True
for target in targets:
if fnmatch.fnmatch(pkgname, target):
return True
return False
for node in __zypper__.xml.call('se', '-s', *targets).getElementsByTagName('solvable'):
pkginfo = dict(node.attributes.items())
try:
if pkginfo['kind'] != 'package':
continue
reponame = pkginfo['repository']
if fromrepo and reponame != fromrepo:
continue
pkgname = pkginfo['name']
pkgversion = pkginfo['edition']
except KeyError:
continue
else:
if _is_match(pkgname):
repo_dict = ret.setdefault(reponame, {})
version_list = repo_dict.setdefault(pkgname, set())
version_list.add(pkgversion)
if byrepo:
for reponame in ret:
# Sort versions newest to oldest
for pkgname in ret[reponame]:
sorted_versions = sorted(
[LooseVersion(x) for x in ret[reponame][pkgname]],
reverse=True
)
ret[reponame][pkgname] = [x.vstring for x in sorted_versions]
return ret
else:
byrepo_ret = {}
for reponame in ret:
for pkgname in ret[reponame]:
byrepo_ret.setdefault(pkgname, []).extend(ret[reponame][pkgname])
for pkgname in byrepo_ret:
sorted_versions = sorted(
[LooseVersion(x) for x in byrepo_ret[pkgname]],
reverse=True
)
byrepo_ret[pkgname] = [x.vstring for x in sorted_versions]
return byrepo_ret
def _get_configured_repos():
'''
Get all the info about repositories from the configurations.