Merge pull request #28228 from rallytime/bp-27562

Back-port #27562 to 2015.8
This commit is contained in:
Mike Place 2015-10-23 07:34:41 -06:00
commit 0775d159f8

View file

@ -25,6 +25,7 @@ import salt.loader
import salt.utils
import salt.utils.http as http
import salt.syspaths as syspaths
import salt.ext.six as six
from salt.ext.six import string_types
from salt.ext.six.moves import input
from salt.ext.six.moves import zip
@ -155,20 +156,21 @@ class SPMClient(object):
)
if 'dependencies' in formula_def:
if not isinstance(formula_def['dependencies'], list):
formula_def['dependencies'] = [formula_def['dependencies']]
needs = []
for dep in formula_def['dependencies']:
if not isinstance(dep, string_types):
self.repo_metadata = self._get_repo_metadata()
self.avail_pkgs = {}
for repo in self.repo_metadata:
if not isinstance(self.repo_metadata[repo]['packages'], dict):
continue
data = self.pkgdb['{0}.info'.format(self.db_prov)](dep, self.db_conn)
if data is not None:
continue
needs.append(dep)
raise SPMPackageError(
'Cannot install {0}, the following dependencies are needed:\n\n{1}'.format(
formula_def['name'], '\n'.join(needs))
)
for pkg in self.repo_metadata[repo]['packages']:
self.avail_pkgs[pkg] = repo
needs, unavail = self._resolve_deps(formula_def)
if len(unavail) > 0:
raise SPMPackageError(
'Cannot install {0}, the following dependencies are needed:\n\n{1}'.format(
formula_def['name'], '\n'.join(unavail))
)
if pkg_name is None:
msg = 'Installing package from file {0}'.format(pkg_file)
@ -230,6 +232,50 @@ class SPMClient(object):
formula_tar.close()
def _resolve_deps(self, formula_def):
'''
Return a list of packages which need to be installed, to resolve all
dependencies
'''
pkg_info = self._pkgdb_fun('info', formula_def['name'])
if not isinstance(pkg_info, dict):
pkg_info = {}
can_has = {}
cant_has = []
for dep in formula_def.get('dependencies', '').split(','):
dep = dep.strip()
if not dep:
continue
if self._pkgdb_fun('info', dep):
continue
if dep in self.avail_pkgs:
can_has[dep] = self.avail_pkgs[dep]
else:
cant_has.append(dep)
inspected = []
to_inspect = can_has.copy()
while len(to_inspect) > 0:
dep = next(six.iterkeys(to_inspect))
del to_inspect[dep]
# Don't try to resolve the same package more than once
if dep in inspected:
continue
inspected.append(dep)
repo_contents = self.repo_metadata.get(can_has[dep], {})
repo_packages = repo_contents.get('packages', {})
dep_formula = repo_packages.get(dep, {}).get('info', {})
also_can, also_cant = self._resolve_deps(dep_formula)
can_has.update(also_can)
cant_has = sorted(set(cant_has + also_cant))
return can_has, cant_has
def _traverse_repos(self, callback, repo_name=None):
'''
Traverse through all repo files and apply the functionality provided in