From 48422fba85b73f39ad48b26e7e104b0e84064cf2 Mon Sep 17 00:00:00 2001 From: Edward Torbett Date: Thu, 11 Jun 2015 12:39:42 +0100 Subject: [PATCH 1/5] Rather than executing yum once per package, execute yum once for all supplied packages. This is necessary when performing a yum upgrade involving multiple dependent packages installed from RPM, for example when upgrading from PostgreSQL 9.0.11 to 9.0.21 on a Red Hat server. --- packaging/os/yum.py | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/packaging/os/yum.py b/packaging/os/yum.py index 00f77d68dfc..e81f16bb2c1 100644 --- a/packaging/os/yum.py +++ b/packaging/os/yum.py @@ -485,6 +485,7 @@ def list_stuff(module, conf_file, stuff): def install(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos): + pkgs = [] res = {} res['results'] = [] res['msg'] = '' @@ -586,7 +587,10 @@ def install(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos): # the error we're catching here pkg = spec - cmd = yum_basecmd + ['install', pkg] + pkgs.append(pkg) + + if pkgs: + cmd = yum_basecmd + ['install'] + pkgs if module.check_mode: # Remove rpms downloaded for EL5 via url @@ -596,15 +600,15 @@ def install(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos): module.fail_json(msg="Failure deleting temp directory %s, %s" % (tempdir, e)) module.exit_json(changed=True) - changed = True - rc, out, err = module.run_command(cmd) - # Fail on invalid urls: - if (rc == 1 and '://' in spec and ('No package %s available.' % spec in out or 'Cannot open: %s. Skipping.' % spec in err)): - err = 'Package at %s could not be installed' % spec - module.fail_json(changed=False,msg=err,rc=1) - elif (rc != 0 and 'Nothing to do' in err) or 'Nothing to do' in out: + if (rc == 1): + for spec in items: + # Fail on invalid urls: + if ('://' in spec and ('No package %s available.' % spec in out or 'Cannot open: %s. Skipping.' % spec in err)): + err = 'Package at %s could not be installed' % spec + module.fail_json(changed=False,msg=err,rc=1) + if (rc != 0 and 'Nothing to do' in err) or 'Nothing to do' in out: # avoid failing in the 'Nothing To Do' case # this may happen with an URL spec. # for an already installed group, @@ -614,16 +618,16 @@ def install(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos): out = '%s: Nothing to do' % spec changed = False - res['rc'] += rc + res['rc'] = rc res['results'].append(out) res['msg'] += err # FIXME - if we did an install - go and check the rpmdb to see if it actually installed - # look for the pkg in rpmdb - # look for the pkg via obsoletes + # look for each pkg in rpmdb + # look for each pkg via obsoletes - # accumulate any changes - res['changed'] |= changed + # Record change + res['changed'] = True # Remove rpms downloaded for EL5 via url try: From 471824b451581ccc22f511fd482cc38b0372b17f Mon Sep 17 00:00:00 2001 From: Edward Torbett Date: Thu, 11 Jun 2015 15:13:28 +0100 Subject: [PATCH 2/5] Comments by @abadger --- packaging/os/yum.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packaging/os/yum.py b/packaging/os/yum.py index e81f16bb2c1..858ed3af9a4 100644 --- a/packaging/os/yum.py +++ b/packaging/os/yum.py @@ -600,6 +600,8 @@ def install(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos): module.fail_json(msg="Failure deleting temp directory %s, %s" % (tempdir, e)) module.exit_json(changed=True) + changed = True + rc, out, err = module.run_command(cmd) if (rc == 1): @@ -627,7 +629,7 @@ def install(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos): # look for each pkg via obsoletes # Record change - res['changed'] = True + res['changed'] = changed # Remove rpms downloaded for EL5 via url try: From fc36506b9eed111e35e8858ca5d5d3ed2fb9f9d2 Mon Sep 17 00:00:00 2001 From: Edward Torbett Date: Thu, 11 Jun 2015 15:21:30 +0100 Subject: [PATCH 3/5] Added multi package operation to remove as suggested by @abadger. Adding to latest is a little more complex due to '*' support. --- packaging/os/yum.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/packaging/os/yum.py b/packaging/os/yum.py index 858ed3af9a4..8063904e312 100644 --- a/packaging/os/yum.py +++ b/packaging/os/yum.py @@ -642,6 +642,7 @@ def install(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos): def remove(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos): + pkgs = [] res = {} res['results'] = [] res['msg'] = '' @@ -658,17 +659,20 @@ def remove(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos): res['results'].append('%s is not installed' % pkg) continue + pkgs.append(pkg) + + if pkgs: # run an actual yum transaction - cmd = yum_basecmd + ["remove", pkg] + cmd = yum_basecmd + ["remove"] + pkg if module.check_mode: module.exit_json(changed=True) rc, out, err = module.run_command(cmd) - res['rc'] += rc + res['rc'] = rc res['results'].append(out) - res['msg'] += err + res['msg'] = err # compile the results into one batch. If anything is changed # then mark changed @@ -677,12 +681,13 @@ def remove(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos): # at this point we should check to see if the pkg is no longer present - if not is_group: # we can't sensibly check for a group being uninstalled reliably - # look to see if the pkg shows up from is_installed. If it doesn't - if not is_installed(module, repoq, pkg, conf_file, en_repos=en_repos, dis_repos=dis_repos): - res['changed'] = True - else: - module.fail_json(**res) + for pkg in pkgs: + if not pkg.startswith('@'): # we can't sensibly check for a group being uninstalled reliably + # look to see if the pkg shows up from is_installed. If it doesn't + if not is_installed(module, repoq, pkg, conf_file, en_repos=en_repos, dis_repos=dis_repos): + res['changed'] = True + else: + module.fail_json(**res) if rc != 0: module.fail_json(**res) From 1fe79801f8699bb0679f61719eb85bf873976257 Mon Sep 17 00:00:00 2001 From: Edward Torbett Date: Fri, 12 Jun 2015 11:18:14 +0100 Subject: [PATCH 4/5] Corrected pkg to pkgs as noted by @abadger --- packaging/os/yum.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/os/yum.py b/packaging/os/yum.py index 8063904e312..534440241b2 100644 --- a/packaging/os/yum.py +++ b/packaging/os/yum.py @@ -663,7 +663,7 @@ def remove(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos): if pkgs: # run an actual yum transaction - cmd = yum_basecmd + ["remove"] + pkg + cmd = yum_basecmd + ["remove"] + pkgs if module.check_mode: module.exit_json(changed=True) From bcbf8c555678214e905448692b00a1b7dbd01599 Mon Sep 17 00:00:00 2001 From: Edward Torbett Date: Fri, 12 Jun 2015 18:06:25 +0100 Subject: [PATCH 5/5] Renamed previous pkgs variable to installed_pkgs as spotted by @strahinja --- packaging/os/yum.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packaging/os/yum.py b/packaging/os/yum.py index 534440241b2..9490a15b15d 100644 --- a/packaging/os/yum.py +++ b/packaging/os/yum.py @@ -541,9 +541,9 @@ def install(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos): # short circuit all the bs - and search for it as a pkg in is_installed # if you find it then we're done if not set(['*','?']).intersection(set(spec)): - pkgs = is_installed(module, repoq, spec, conf_file, en_repos=en_repos, dis_repos=dis_repos, is_pkg=True) - if pkgs: - res['results'].append('%s providing %s is already installed' % (pkgs[0], spec)) + installed_pkgs = is_installed(module, repoq, spec, conf_file, en_repos=en_repos, dis_repos=dis_repos, is_pkg=True) + if installed_pkgs: + res['results'].append('%s providing %s is already installed' % (installed_pkgs[0], spec)) continue # look up what pkgs provide this