win_pkg: remove all installed versions when no explicit version passed

This will make pkg.removed states work more intuitively, rather than
just trying to delete the newest available version.
This commit is contained in:
Erik Johnson 2017-02-13 16:43:01 -06:00
parent ce1f01f81a
commit 5871825b9e

View file

@ -1296,152 +1296,162 @@ def remove(name=None, pkgs=None, version=None, **kwargs):
pkg_params = __salt__['pkg_resource.parse_targets'](name, pkgs, **kwargs)[0]
# Get a list of currently installed software for comparison at the end
old = list_pkgs(saltenv=saltenv, refresh=refresh)
old = list_pkgs(saltenv=saltenv, refresh=refresh, versions_as_list=True)
# Loop through each package
changed = []
for target in pkg_params:
for pkgname, version_num in six.iteritems(pkg_params):
# Load package information for the package
pkginfo = _get_package_info(target, saltenv=saltenv)
pkginfo = _get_package_info(pkgname, saltenv=saltenv)
# Make sure pkginfo was found
if not pkginfo:
log.error('Unable to locate package {0}'.format(name))
ret[target] = 'Unable to locate package {0}'.format(target)
msg = 'Unable to locate package {0}'.format(pkgname)
log.error(msg)
ret[pkgname] = msg
continue
# Get latest version if no version passed, else use passed version
if not version:
version_num = _get_latest_pkg_version(pkginfo)
else:
version_num = version
if 'latest' in pkginfo and version_num not in pkginfo:
if version_num is not None \
and version_num not in pkginfo \
and 'latest' in pkginfo:
version_num = 'latest'
# Check to see if package is installed on the system
if target not in old:
log.error('{0} {1} not installed'.format(target, version))
ret[target] = {'current': 'not installed'}
removal_targets = []
if pkgname not in old:
log.error('%s %s not installed', pkgname, version)
ret[pkgname] = {'current': 'not installed'}
continue
else:
if version_num not in old.get(target, '').split(',') \
and not old.get(target) == "Not Found" \
if version_num is None:
removal_targets.extend(old[pkgname])
elif version_num not in old[pkgname] \
and 'Not Found' not in old['pkgname'] \
and version_num != 'latest':
log.error('{0} {1} not installed'.format(target, version))
ret[target] = {
log.error('%s %s not installed', pkgname, version)
ret[pkgname] = {
'current': '{0} not installed'.format(version_num)
}
continue
else:
removal_targets.append(version_num)
# Get the uninstaller
uninstaller = pkginfo[version_num].get('uninstaller')
# If no uninstaller found, use the installer
if not uninstaller:
uninstaller = pkginfo[version_num].get('installer')
for target in removal_targets:
# Get the uninstaller
uninstaller = pkginfo[target].get('uninstaller')
# If still no uninstaller found, fail
if not uninstaller:
log.error('Error: No installer or uninstaller configured '
'for package {0}'.format(name))
ret[target] = {'no uninstaller': version_num}
continue
# If no uninstaller found, use the installer
if not uninstaller:
uninstaller = pkginfo[target].get('installer')
# Where is the uninstaller
if uninstaller.startswith(('salt:', 'http:', 'https:', 'ftp:')):
# If still no uninstaller found, fail
if not uninstaller:
log.error(
'No installer or uninstaller configured for package %s',
pkgname,
)
ret[pkgname] = {'no uninstaller': target}
continue
# Check to see if the uninstaller is cached
cached_pkg = __salt__['cp.is_cached'](uninstaller)
if not cached_pkg:
# It's not cached. Cache it, mate.
cached_pkg = __salt__['cp.cache_file'](uninstaller)
# Where is the uninstaller
if uninstaller.startswith(('salt:', 'http:', 'https:', 'ftp:')):
# Check if the uninstaller was cached successfully
# Check to see if the uninstaller is cached
cached_pkg = __salt__['cp.is_cached'](uninstaller)
if not cached_pkg:
log.error('Unable to cache {0}'.format(uninstaller))
ret[target] = {'unable to cache': uninstaller}
continue
else:
# Run the uninstaller directly (not hosted on salt:, https:, etc.)
cached_pkg = uninstaller
# It's not cached. Cache it, mate.
cached_pkg = __salt__['cp.cache_file'](uninstaller)
# Fix non-windows slashes
cached_pkg = cached_pkg.replace('/', '\\')
cache_path, _ = os.path.split(cached_pkg)
# Check if the uninstaller was cached successfully
if not cached_pkg:
log.error('Unable to cache %s', uninstaller)
ret[pkgname] = {'unable to cache': uninstaller}
continue
else:
# Run the uninstaller directly (not hosted on salt:, https:, etc.)
cached_pkg = uninstaller
# Get parameters for cmd
expanded_cached_pkg = str(os.path.expandvars(cached_pkg))
# Fix non-windows slashes
cached_pkg = cached_pkg.replace('/', '\\')
cache_path, _ = os.path.split(cached_pkg)
# Get uninstall flags
uninstall_flags = '{0}'.format(
pkginfo[version_num].get('uninstall_flags', '')
)
if kwargs.get('extra_uninstall_flags'):
uninstall_flags = '{0} {1}'.format(
uninstall_flags,
kwargs.get('extra_uninstall_flags', "")
# Get parameters for cmd
expanded_cached_pkg = str(os.path.expandvars(cached_pkg))
# Get uninstall flags
uninstall_flags = '{0}'.format(
pkginfo[target].get('uninstall_flags', '')
)
if kwargs.get('extra_uninstall_flags'):
uninstall_flags = '{0} {1}'.format(
uninstall_flags,
kwargs.get('extra_uninstall_flags', "")
)
# Uninstall the software
# Check Use Scheduler Option
if pkginfo[version_num].get('use_scheduler', False):
# Uninstall the software
# Check Use Scheduler Option
if pkginfo[target].get('use_scheduler', False):
# Build Scheduled Task Parameters
if pkginfo[version_num].get('msiexec'):
cmd = 'msiexec.exe'
arguments = ['/x']
arguments.extend(salt.utils.shlex_split(uninstall_flags))
else:
cmd = expanded_cached_pkg
arguments = salt.utils.shlex_split(uninstall_flags)
# Build Scheduled Task Parameters
if pkginfo[target].get('msiexec'):
cmd = 'msiexec.exe'
arguments = ['/x']
arguments.extend(salt.utils.shlex_split(uninstall_flags))
else:
cmd = expanded_cached_pkg
arguments = salt.utils.shlex_split(uninstall_flags)
# Create Scheduled Task
__salt__['task.create_task'](name='update-salt-software',
user_name='System',
force=True,
action_type='Execute',
cmd=cmd,
arguments=' '.join(arguments),
start_in=cache_path,
trigger_type='Once',
start_date='1975-01-01',
start_time='01:00',
ac_only=False,
stop_if_on_batteries=False)
# Run Scheduled Task
if not __salt__['task.run_wait'](name='update-salt-software'):
log.error('Failed to remove {0}'.format(target))
log.error('Scheduled Task failed to run')
ret[target] = {'uninstall status': 'failed'}
else:
# Build the install command
cmd = []
if pkginfo[version_num].get('msiexec'):
cmd.extend(['msiexec', '/x', expanded_cached_pkg])
# Create Scheduled Task
__salt__['task.create_task'](name='update-salt-software',
user_name='System',
force=True,
action_type='Execute',
cmd=cmd,
arguments=' '.join(arguments),
start_in=cache_path,
trigger_type='Once',
start_date='1975-01-01',
start_time='01:00',
ac_only=False,
stop_if_on_batteries=False)
# Run Scheduled Task
if not __salt__['task.run_wait'](name='update-salt-software'):
log.error('Failed to remove %s', pkgname)
log.error('Scheduled Task failed to run')
ret[pkgname] = {'uninstall status': 'failed'}
else:
cmd.append(expanded_cached_pkg)
cmd.extend(salt.utils.shlex_split(uninstall_flags))
# Launch the command
result = __salt__['cmd.run_all'](cmd,
output_loglevel='trace',
python_shell=False,
redirect_stderr=True)
if not result['retcode']:
ret[target] = {'uninstall status': 'success'}
changed.append(target)
else:
log.error('Failed to remove {0}'.format(target))
log.error('retcode {0}'.format(result['retcode']))
log.error('uninstaller output: {0}'.format(result['stdout']))
ret[target] = {'uninstall status': 'failed'}
# Build the install command
cmd = []
if pkginfo[target].get('msiexec'):
cmd.extend(['msiexec', '/x', expanded_cached_pkg])
else:
cmd.append(expanded_cached_pkg)
cmd.extend(salt.utils.shlex_split(uninstall_flags))
# Launch the command
result = __salt__['cmd.run_all'](cmd,
output_loglevel='trace',
python_shell=False,
redirect_stderr=True)
if not result['retcode']:
ret[pkgname] = {'uninstall status': 'success'}
changed.append(pkgname)
else:
log.error('Failed to remove %s', pkgname)
log.error('retcode %s', result['retcode'])
log.error('uninstaller output: %s', result['stdout'])
ret[pkgname] = {'uninstall status': 'failed'}
# Get a new list of installed software
new = list_pkgs(saltenv=saltenv)
tries = 0
difference = salt.utils.compare_dicts(old, new)
# Take the "old" package list and convert the values to strings in
# preparation for the comparison below.
__salt__['pkg_resource.stringify'](old)
difference = salt.utils.compare_dicts(old, new)
tries = 0
while not all(name in difference for name in changed) and tries <= 1000:
new = list_pkgs(saltenv=saltenv)
difference = salt.utils.compare_dicts(old, new)