mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge pull request #28228 from rallytime/bp-27562
Back-port #27562 to 2015.8
This commit is contained in:
commit
0775d159f8
1 changed files with 59 additions and 13 deletions
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue