yum: improved check_mode handling and package update flow.

pull/18777/head
queridiculo 10 years ago committed by Matt Clay
parent 9ffde6c048
commit 92615669c0

@ -224,7 +224,7 @@ def is_installed(module, repoq, pkgspec, conf_file, qf=def_qf, en_repos=None, di
for rid in en_repos: for rid in en_repos:
my.repos.enableRepo(rid) my.repos.enableRepo(rid)
e,m,u = my.rpmdb.matchPackageNames([pkgspec]) e, m, u = my.rpmdb.matchPackageNames([pkgspec])
pkgs = e + m pkgs = e + m
if not pkgs: if not pkgs:
pkgs.extend(my.returnInstalledPackagesByDep(pkgspec)) pkgs.extend(my.returnInstalledPackagesByDep(pkgspec))
@ -236,16 +236,16 @@ def is_installed(module, repoq, pkgspec, conf_file, qf=def_qf, en_repos=None, di
else: else:
cmd = repoq + ["--disablerepo=*", "--pkgnarrow=installed", "--qf", qf, pkgspec] cmd = repoq + ["--disablerepo=*", "--pkgnarrow=installed", "--qf", qf, pkgspec]
rc,out,err = module.run_command(cmd) rc, out, err = module.run_command(cmd)
if not is_pkg: if not is_pkg:
cmd = repoq + ["--disablerepo=*", "--pkgnarrow=installed", "--qf", qf, "--whatprovides", pkgspec] cmd = repoq + ["--disablerepo=*", "--pkgnarrow=installed", "--qf", qf, "--whatprovides", pkgspec]
rc2,out2,err2 = module.run_command(cmd) rc2, out2, err2 = module.run_command(cmd)
else: else:
rc2,out2,err2 = (0, '', '') rc2, out2, err2 = (0, '', '')
if rc == 0 and rc2 == 0: if rc == 0 and rc2 == 0:
out += out2 out += out2
return [ p for p in out.split('\n') if p.strip() ] return [p for p in out.split('\n') if p.strip()]
else: else:
module.fail_json(msg='Error from repoquery: %s: %s' % (cmd, err + err2)) module.fail_json(msg='Error from repoquery: %s: %s' % (cmd, err + err2))
@ -553,7 +553,7 @@ def install(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos):
module.fail_json(msg="Failure downloading %s, %s" % (spec, e)) module.fail_json(msg="Failure downloading %s, %s" % (spec, e))
#groups :( #groups :(
elif spec.startswith('@'): elif spec.startswith('@'):
# complete wild ass guess b/c it's a group # complete wild ass guess b/c it's a group
pkg = spec pkg = spec
@ -620,7 +620,11 @@ def install(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos):
shutil.rmtree(tempdir) shutil.rmtree(tempdir)
except Exception, e: except Exception, e:
module.fail_json(msg="Failure deleting temp directory %s, %s" % (tempdir, e)) module.fail_json(msg="Failure deleting temp directory %s, %s" % (tempdir, e))
module.exit_json(changed=True)
for p in pkgs:
# take note of which packages are getting installed
res['results'].append('%s will be installed' % p)
module.exit_json(changed=True, results=res['results'])
changed = True changed = True
@ -688,7 +692,10 @@ def remove(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos):
cmd = yum_basecmd + ["remove"] + pkgs cmd = yum_basecmd + ["remove"] + pkgs
if module.check_mode: if module.check_mode:
module.exit_json(changed=True) # take note of which packages are getting removed
for p in pkgs:
res['results'].append('%s will be removed' % p)
module.exit_json(changed=True, results=res['results'])
rc, out, err = module.run_command(cmd) rc, out, err = module.run_command(cmd)
@ -723,46 +730,68 @@ def latest(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos):
res['msg'] = '' res['msg'] = ''
res['changed'] = False res['changed'] = False
res['rc'] = 0 res['rc'] = 0
pkgs = {}
for spec in items: pkgs['update'] = []
pkgs['install'] = []
pkg = None updates = {}
basecmd = 'update' update_all = False
cmd = '' cmd = None
# groups, again
if spec.startswith('@'): # determine if we're doing an update all
pkg = spec if '*' in items:
update_all = True
elif spec == '*': #update all
# use check-update to see if there is any need # run check-update to see if we have packages pending
rc,out,err = module.run_command(yum_basecmd + ['check-update']) rc, out, err = module.run_command(yum_basecmd + ['check-update'])
if rc == 100: if rc == 0 and update_all:
cmd = yum_basecmd + [basecmd] res['results'].append('Nothing to do here, all packages are up to date')
else: return res
res['results'].append('All packages up to date') elif rc == 100:
available_updates = out.split('\n')
# build update dictionary
for line in available_updates:
line = line.split()
# ignore irrelevant lines
# FIXME... revisit for something less kludgy
if '*' in line or len(line) != 3 or '.' not in line[0]:
continue continue
# dep/pkgname - find it
else:
if is_installed(module, repoq, spec, conf_file, en_repos=en_repos, dis_repos=dis_repos):
basecmd = 'update'
else: else:
basecmd = 'install' pkg, version, repo = line
name, dist = pkg.split('.')
updates.update({name: {'version': version, 'dist': dist, 'repo': repo}})
elif rc == 1:
res['msg'] = err
res['rc'] = rc
module.fail_json(**res)
if update_all:
cmd = yum_basecmd + ['update']
else:
for spec in items:
# some guess work involved with groups. update @<group> will install the group if missing
if spec.startswith('@'):
pkgs['update'].append(spec)
continue
# dep/pkgname - find it
else:
if is_installed(module, repoq, spec, conf_file, en_repos=en_repos, dis_repos=dis_repos):
pkgs['update'].append(spec)
else:
pkgs['install'].append(spec)
pkglist = what_provides(module, repoq, spec, conf_file, en_repos=en_repos, dis_repos=dis_repos) pkglist = what_provides(module, repoq, spec, conf_file, en_repos=en_repos, dis_repos=dis_repos)
# FIXME..? may not be desirable to throw an exception here if a single package is missing
if not pkglist: if not pkglist:
res['msg'] += "No Package matching '%s' found available, installed or updated" % spec res['msg'] += "No Package matching '%s' found available, installed or updated" % spec
module.fail_json(**res) module.fail_json(**res)
nothing_to_do = True nothing_to_do = True
for this in pkglist: for this in pkglist:
if basecmd == 'install' and is_available(module, repoq, this, conf_file, en_repos=en_repos, dis_repos=dis_repos): if spec in pkgs['install'] and is_available(module, repoq, this, conf_file, en_repos=en_repos, dis_repos=dis_repos):
nothing_to_do = False nothing_to_do = False
break break
if basecmd == 'update' and is_update(module, repoq, this, conf_file, en_repos=en_repos, dis_repos=dis_repos): if spec in pkgs['update'] and spec in updates.keys():
nothing_to_do = False nothing_to_do = False
break
if nothing_to_do: if nothing_to_do:
res['results'].append("All packages providing %s are up to date" % spec) res['results'].append("All packages providing %s are up to date" % spec)
@ -775,26 +804,59 @@ def latest(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos):
res['msg'] += "The following packages have pending transactions: %s" % ", ".join(conflicts) res['msg'] += "The following packages have pending transactions: %s" % ", ".join(conflicts)
module.fail_json(**res) module.fail_json(**res)
pkg = spec # list of package updates
if not cmd: if update_all:
cmd = yum_basecmd + [basecmd, pkg] will_update = updates.keys()
else:
will_update = [u for u in pkgs['update'] if u in updates.keys() or u.startswith('@')]
if module.check_mode: # check_mode output
return module.exit_json(changed=True) if module.check_mode:
for w in will_update:
if w.startswith('@'):
msg = '%s will be updated' % w
else:
msg = '%s will be updated with %s-%s.%s from %s' % (w, w, updates[w]['version'], updates[w]['dist'], updates[w]['repo'])
res['results'].append(msg)
rc, out, err = module.run_command(cmd) for p in pkgs['install']:
res['results'].append('%s will be installed' % p)
res['rc'] += rc if len(will_update) > 0 or len(pkgs['install']) > 0:
res['results'].append(out) res['changed'] = True
res['msg'] += err
# FIXME if it is - update it and check to see if it applied return res
# check to see if there is no longer an update available for the pkgspec
if rc: # run commands
res['failed'] = True if cmd: # update all
rc, out, err = module.run_command(cmd)
res['changed'] = True
else:
if len(pkgs['install']) > 0: # install missing
cmd = yum_basecmd + ['install'] + pkgs['install']
rc, out, err = module.run_command(cmd)
res['changed'] = True
else: else:
rc, out, err = [0, '', '']
if len(will_update) > 0: # update present
cmd = yum_basecmd + ['update'] + pkgs['update']
rc2, out2, err2 = module.run_command(cmd)
res['changed'] = True res['changed'] = True
else:
rc2, out2, err2 = [0, '', '']
if not update_all:
rc += rc2
out += out2
err += err2
res['rc'] += rc
res['msg'] += err
res['results'].append(out)
if rc:
res['failed'] = True
return res return res
@ -939,4 +1001,3 @@ from ansible.module_utils.basic import *
from ansible.module_utils.urls import * from ansible.module_utils.urls import *
if __name__ == '__main__': if __name__ == '__main__':
main() main()

Loading…
Cancel
Save