Add apt module support for installing/removing specific version of package

This uses standard APT syntax, e.g.:

    ansible webservers -m apt -a "pkg=nginx=1.1.19-1 state=installed"
reviewable/pr18780/r1
Daniel Néri 13 years ago
parent 73412513b8
commit 187ab3f918

39
apt

@ -63,16 +63,27 @@ def run_apt(command):
rc = cmd.returncode rc = cmd.returncode
return rc, out, err return rc, out, err
def package_status(pkgspec, cache): def package_split(pkgspec):
parts = pkgspec.split('=')
if len(parts) > 1:
return parts[0], parts[1]
else:
return parts[0], None
def package_status(pkgname, version, cache):
try: try:
pkg = cache[pkgspec] pkg = cache[pkgname]
except: except KeyError:
fail_json(msg="No package matching '%s' is available" % pkgspec) fail_json(msg="No package matching '%s' is available" % pkgname)
return (pkg.is_installed, pkg.is_upgradable) if version:
return pkg.is_installed and pkg.installed.version == version, False
else:
return pkg.is_installed, pkg.is_upgradable
def install(pkgspec, cache, upgrade=False): def install(pkgspec, cache, upgrade=False):
(installed, upgradable) = package_status(pkgspec, cache) name, version = package_split(pkgspec)
if (not installed) or (upgrade and upgradable): installed, upgradable = package_status(name, version, cache)
if not installed or (upgrade and upgradable):
cmd = "%s -q -y install '%s'" % (APT, pkgspec) cmd = "%s -q -y install '%s'" % (APT, pkgspec)
rc, out, err = run_apt(cmd) rc, out, err = run_apt(cmd)
if rc: if rc:
@ -82,15 +93,16 @@ def install(pkgspec, cache, upgrade=False):
return False return False
def remove(pkgspec, cache, purge=False): def remove(pkgspec, cache, purge=False):
(installed, upgradable) = package_status(pkgspec, cache) name, version = package_split(pkgspec)
installed, upgradable = package_status(name, version, cache)
if not installed: if not installed:
return False return False
else: else:
purge = '--purge' if purge else '' purge = '--purge' if purge else ''
cmd = "%s -q -y %s remove '%s'" % (APT, purge, pkgspec) cmd = "%s -q -y %s remove '%s'" % (APT, purge, name)
rc, out, err = run_apt(cmd) rc, out, err = run_apt(cmd)
if rc: if rc:
fail_json(msg="'apt-get remove %s' failed: %s" % (pkgspec, err)) fail_json(msg="'apt-get remove %s' failed: %s" % (name, err))
return True return True
@ -109,7 +121,7 @@ if not len(items):
params = {} params = {}
for x in items: for x in items:
(k, v) = x.split("=") (k, v) = x.split("=", 1)
params[k] = v params[k] = v
state = params.get('state','installed') state = params.get('state','installed')
@ -137,7 +149,12 @@ if update_cache == 'yes':
if package == None: if package == None:
exit_json(changed=False) exit_json(changed=False)
if package.count('=') > 1:
fail_json(msg='invalid package spec')
if state == 'latest': if state == 'latest':
if '=' in package:
fail_json(msg='version number inconsistent with state=latest')
changed = install(package, cache, upgrade=True) changed = install(package, cache, upgrade=True)
elif state == 'installed': elif state == 'installed':
changed = install(package, cache) changed = install(package, cache)

Loading…
Cancel
Save