def _find_install_targets(name=None, version=None, pkgs=None, sources=None, **kwargs): ''' Inspect the arguments to pkg.installed and discover what packages need to be installed. Return a dict of desired packages ''' if all((pkgs, sources)): return {'name': name, 'changes': {}, 'result': False, 'comment': 'Only one of "pkgs" and "sources" is permitted.'} cur_pkgs = __salt__['pkg.list_pkgs'](versions_as_list=True) if any((pkgs, sources)): if pkgs: desired = _repack_pkgs(pkgs) elif sources: desired = __salt__['pkg_resource.pack_sources'](sources) if not desired: # Badly-formatted SLS return {'name': name, 'changes': {}, 'result': False, 'comment': 'Invalidly formatted "{0}" parameter. See ' 'minion log.'.format('pkgs' if pkgs else 'sources')} else: if salt.utils.is_windows(): pkginfo = _get_package_info(name) if not pkginfo: return {'name': name, 'changes': {}, 'result': False, 'comment': 'Package {0} not found in the ' 'repository.'.format(name)} if version is None: version = _get_latest_pkg_version(pkginfo) desired = {name: version} cver = cur_pkgs.get(name, []) if version and version in cver: # The package is installed and is the correct version return {'name': name, 'changes': {}, 'result': True, 'comment': ('Version {0} of package "{1}" is already ' 'installed').format(version, name)} # if cver is not an empty string, the package is already installed elif cver and version is None: # The package is installed return {'name': name, 'changes': {}, 'result': True, 'comment': 'Package {0} is already installed'.format(name)} version_spec = False # Find out which packages will be targeted in the call to pkg.install if sources: targets = [x for x in desired if x not in cur_pkgs] else: # Perform platform-specific pre-flight checks problems = _preflight_check(desired, **kwargs) comments = [] if problems.get('no_suggest'): comments.append( 'The following package(s) were not found, and no possible ' 'matches were found in the package db: ' '{0}'.format(', '.join(sorted(problems['no_suggest']))) ) if problems.get('suggest'): for pkgname, suggestions in problems['suggest'].iteritems(): comments.append( 'Package {0!r} not found (possible matches: {1})' .format(pkgname, ', '.join(suggestions)) ) if comments: if len(comments) > 1: comments.append('') return {'name': name, 'changes': {}, 'result': False, 'comment': '. '.join(comments).rstrip()} # Check current versions against desired versions targets = {} problems = [] for pkgname, pkgver in desired.iteritems(): cver = cur_pkgs.get(pkgname, []) # Package not yet installed, so add to targets if not cver: targets[pkgname] = pkgver continue elif not __salt__['pkg_resource.check_extra_requirements'](pkgname, pkgver): targets[pkgname] = pkgver continue # No version specified and pkg is installed, do not add to targets elif __salt__['pkg_resource.version_clean'](pkgver) is None: continue version_spec = True match = re.match('^([<>])?(=)?([^<>=]+)$', pkgver) if not match: msg = 'Invalid version specification "{0}" for package ' \ '"{1}".'.format(pkgver, pkgname) problems.append(msg) else: gt_lt, eq, verstr = match.groups() comparison = gt_lt or '' comparison += eq or '' # A comparison operator of "=" is redundant, but possible. # Change it to "==" so that the version comparison works if comparison in ['=', '']: comparison = '==' if not _fulfills_version_spec(cver, comparison, verstr): # Current version did not match desired, add to targets targets[pkgname] = pkgver if problems: return {'name': name, 'changes': {}, 'result': False, 'comment': ' '.join(problems)} if not targets: # All specified packages are installed msg = 'All specified packages are already installed{0}.'.format( ' and are at the desired version' if version_spec else '') return {'name': name, 'changes': {}, 'result': True, 'comment': msg} return desired, targets
def _find_install_targets(name=None, version=None, pkgs=None, sources=None, **kwargs): """ Inspect the arguments to pkg.installed and discover what packages need to be installed. Return a dict of desired packages """ if all((pkgs, sources)): return { "name": name, "changes": {}, "result": False, "comment": 'Only one of "pkgs" and "sources" is permitted.', } cur_pkgs = __salt__["pkg.list_pkgs"](versions_as_list=True, **kwargs) if any((pkgs, sources)): if pkgs: desired = _repack_pkgs(pkgs) elif sources: desired = __salt__["pkg_resource.pack_sources"](sources) if not desired: # Badly-formatted SLS return { "name": name, "changes": {}, "result": False, "comment": "Invalidly formatted {0!r} parameter. See " "minion log.".format("pkgs" if pkgs else "sources"), } else: if salt.utils.is_windows(): pkginfo = _get_package_info(name) if not pkginfo: return { "name": name, "changes": {}, "result": False, "comment": "Package {0} not found in the " "repository.".format(name), } if version is None: version = _get_latest_pkg_version(pkginfo) desired = {name: version} cver = cur_pkgs.get(name, []) if version and version in cver: # The package is installed and is the correct version return { "name": name, "changes": {}, "result": True, "comment": ("Version {0} of package {1!r} is already " "installed").format(version, name), } # if cver is not an empty string, the package is already installed elif cver and version is None: # The package is installed return { "name": name, "changes": {}, "result": True, "comment": "Package {0} is already installed".format(name), } version_spec = False # Find out which packages will be targeted in the call to pkg.install if sources: targets = [x for x in desired if x not in cur_pkgs] else: # Perform platform-specific pre-flight checks problems = _preflight_check(desired, **kwargs) comments = [] if problems.get("no_suggest"): comments.append( "The following package(s) were not found, and no possible " "matches were found in the package db: " "{0}".format(", ".join(sorted(problems["no_suggest"]))) ) if problems.get("suggest"): for pkgname, suggestions in problems["suggest"].iteritems(): comments.append( "Package {0!r} not found (possible matches: {1})".format(pkgname, ", ".join(suggestions)) ) if comments: if len(comments) > 1: comments.append("") return {"name": name, "changes": {}, "result": False, "comment": ". ".join(comments).rstrip()} # Check current versions against desired versions targets = {} problems = [] for pkgname, pkgver in desired.iteritems(): cver = cur_pkgs.get(pkgname, []) # Package not yet installed, so add to targets if not cver: targets[pkgname] = pkgver continue elif not __salt__["pkg_resource.check_extra_requirements"](pkgname, pkgver): targets[pkgname] = pkgver continue # No version specified and pkg is installed, do not add to targets elif __salt__["pkg_resource.version_clean"](pkgver) is None: continue version_spec = True match = re.match("^([<>])?(=)?([^<>=]+)$", pkgver) if not match: msg = "Invalid version specification {0!r} for package " "{1!r}.".format(pkgver, pkgname) problems.append(msg) else: gt_lt, eq, verstr = match.groups() comparison = gt_lt or "" comparison += eq or "" # A comparison operator of "=" is redundant, but possible. # Change it to "==" so that the version comparison works if comparison in ["=", ""]: comparison = "==" if not _fulfills_version_spec(cver, comparison, verstr): # Current version did not match desired, add to targets targets[pkgname] = pkgver if problems: return {"name": name, "changes": {}, "result": False, "comment": " ".join(problems)} if not targets: # All specified packages are installed msg = "All specified packages are already installed{0}.".format( " and are at the desired version" if version_spec else "" ) return {"name": name, "changes": {}, "result": True, "comment": msg} return desired, targets
def _find_install_targets(name=None, version=None, pkgs=None, sources=None, skip_suggestions=False, **kwargs): ''' Inspect the arguments to pkg.installed and discover what packages need to be installed. Return a dict of desired packages ''' if all((pkgs, sources)): return { 'name': name, 'changes': {}, 'result': False, 'comment': 'Only one of "pkgs" and "sources" is permitted.' } cur_pkgs = __salt__['pkg.list_pkgs'](versions_as_list=True, **kwargs) if any((pkgs, sources)): if pkgs: desired = _repack_pkgs(pkgs) elif sources: desired = __salt__['pkg_resource.pack_sources'](sources) if not desired: # Badly-formatted SLS return { 'name': name, 'changes': {}, 'result': False, 'comment': 'Invalidly formatted {0!r} parameter. See ' 'minion log.'.format('pkgs' if pkgs else 'sources') } to_unpurge = _find_unpurge_targets(desired) else: if salt.utils.is_windows(): pkginfo = _get_package_info(name) if not pkginfo: return { 'name': name, 'changes': {}, 'result': False, 'comment': 'Package {0} not found in the ' 'repository.'.format(name) } if version is None: version = _get_latest_pkg_version(pkginfo) _normalize_name = __salt__.get('pkg.normalize_name', lambda pkgname: pkgname) desired = {_normalize_name(name): version} to_unpurge = _find_unpurge_targets(desired) cver = cur_pkgs.get(name, []) if name not in to_unpurge: if version and version in cver: # The package is installed and is the correct version return { 'name': name, 'changes': {}, 'result': True, 'comment': 'Version {0} of package {1!r} is already ' 'installed'.format(version, name) } # if cver is not an empty string, the package is already installed elif cver and version is None: # The package is installed return { 'name': name, 'changes': {}, 'result': True, 'comment': 'Package {0} is already ' 'installed'.format(name) } version_spec = False # Find out which packages will be targeted in the call to pkg.install if sources: targets = [x for x in desired if x not in cur_pkgs] else: # Check for alternate package names if strict processing is not # enforced. # Takes extra time. Disable for improved performance if not skip_suggestions: # Perform platform-specific pre-flight checks problems = _preflight_check(desired, **kwargs) comments = [] if problems.get('no_suggest'): comments.append( 'The following package(s) were not found, and no possible ' 'matches were found in the package db: ' '{0}'.format(', '.join(sorted(problems['no_suggest'])))) if problems.get('suggest'): for pkgname, suggestions in problems['suggest'].iteritems(): comments.append( 'Package {0!r} not found (possible matches: {1})'. format(pkgname, ', '.join(suggestions))) if comments: if len(comments) > 1: comments.append('') return { 'name': name, 'changes': {}, 'result': False, 'comment': '. '.join(comments).rstrip() } # Check current versions against desired versions targets = {} problems = [] for pkgname, pkgver in desired.iteritems(): cver = cur_pkgs.get(pkgname, []) # Package not yet installed, so add to targets if not cver: targets[pkgname] = pkgver continue elif not __salt__['pkg_resource.check_extra_requirements'](pkgname, pkgver): targets[pkgname] = pkgver continue # No version specified and pkg is installed, do not add to targets elif __salt__['pkg_resource.version_clean'](pkgver) is None: continue version_spec = True match = re.match('^([<>])?(=)?([^<>=]+)$', pkgver) if not match: msg = 'Invalid version specification {0!r} for package ' \ '{1!r}.'.format(pkgver, pkgname) problems.append(msg) else: gt_lt, eq, verstr = match.groups() comparison = gt_lt or '' comparison += eq or '' # A comparison operator of "=" is redundant, but possible. # Change it to "==" so that the version comparison works if comparison in ['=', '']: comparison = '==' if not _fulfills_version_spec(cver, comparison, verstr): # Current version did not match desired, add to targets targets[pkgname] = pkgver if problems: return { 'name': name, 'changes': {}, 'result': False, 'comment': ' '.join(problems) } if not any((targets, to_unpurge)): # All specified packages are installed msg = ('All specified packages are already installed{0}.'.format( ' and are at the desired version' if version_spec else '')) return {'name': name, 'changes': {}, 'result': True, 'comment': msg} return desired, targets, to_unpurge
def _uninstall(action='remove', name=None, pkgs=None, **kwargs): ''' Common function for package removal ''' if action not in ('remove', 'purge'): return {'name': name, 'changes': {}, 'result': False, 'comment': 'Invalid action "{0}". ' 'This is probably a bug.'.format(action)} pkg_params = __salt__['pkg_resource.parse_targets'](name, pkgs)[0] old = __salt__['pkg.list_pkgs'](versions_as_list=True) if not salt.utils.is_windows(): targets = sorted([x for x in pkg_params if x in old]) else: targets = [] for item in pkg_params: pkginfo = _get_package_info(item) if kwargs.get('version') is not None: version_num = kwargs['version'] else: version_num = _get_latest_pkg_version(pkginfo) if pkginfo[version_num]['full_name'] in old: targets.append(pkginfo[version_num]['full_name']) targets = sorted(targets) if not targets: return {'name': name, 'changes': {}, 'result': True, 'comment': 'None of the targeted packages are installed'} if __opts__['test']: return {'name': name, 'changes': {}, 'result': None, 'comment': 'The following packages will be {0}d: ' '{1}.'.format(action, ', '.join(targets))} changes = __salt__['pkg.{0}'.format(action)](name, pkgs=pkgs, **kwargs) new = __salt__['pkg.list_pkgs'](versions_as_list=True) failed = [x for x in pkg_params if x in new] if failed: return {'name': name, 'changes': changes, 'result': False, 'comment': 'The following packages failed to {0}: ' '{1}.'.format(action, ', '.join(failed))} comments = [] not_installed = sorted([x for x in pkg_params if x not in targets]) if not_installed: comments.append('The following packages were not installed: ' '{0}.'.format(', '.join(not_installed))) comments.append('The following packages were {0}d: ' '{1}.'.format(action, ', '.join(targets))) else: comments.append('All targeted packages were {0}d.'.format(action)) return {'name': name, 'changes': changes, 'result': True, 'comment': ' '.join(comments)}