From 9f043d9ba81f6462dd775f7be4e616056f6825cb Mon Sep 17 00:00:00 2001 From: Toshio Kuratomi Date: Mon, 15 Jun 2015 09:51:15 -0700 Subject: [PATCH] Further optimizations pointed out by @kustodian in #1516 * Only install yum-utils if needed (b/c we're going to use repoquery) * Add a warning message explaining that why slower repoquery was used rather than yum API. --- lib/ansible/modules/packaging/os/yum.py | 86 +++++++++++++------------ 1 file changed, 45 insertions(+), 41 deletions(-) diff --git a/lib/ansible/modules/packaging/os/yum.py b/lib/ansible/modules/packaging/os/yum.py index d3c28a1d554..87c4d28c031 100644 --- a/lib/ansible/modules/packaging/os/yum.py +++ b/lib/ansible/modules/packaging/os/yum.py @@ -175,12 +175,17 @@ def yum_base(conf_file=None): return my -def install_yum_utils(module): +def ensure_yum_utils(module): - if not module.check_mode: + repoquerybin = module.get_bin_path('repoquery', required=False) + + if module.params['install_repoquery'] and not repoquerybin and not module.check_mode: yum_path = module.get_bin_path('yum') if yum_path: - rc, so, se = module.run_command('%s -y install yum-utils' % yum_path) + rc, so, se = module.run_command('%s -y install yum-utils' % yum_path) + repoquerybin = module.get_bin_path('repoquery', required=False) + + return repoquerybin def po_to_nevra(po): @@ -323,7 +328,7 @@ def is_update(module, repoq, pkgspec, conf_file, qf=def_qf, en_repos=None, dis_r else: module.fail_json(msg='Error from repoquery: %s: %s' % (cmd, err)) - return [] + return set() def what_provides(module, repoq, req_spec, conf_file, qf=def_qf, en_repos=None, dis_repos=None): if en_repos is None: @@ -375,7 +380,7 @@ def what_provides(module, repoq, req_spec, conf_file, qf=def_qf, en_repos=None, else: module.fail_json(msg='Error from repoquery: %s: %s' % (cmd, err + err2)) - return [] + return set() def transaction_exists(pkglist): """ @@ -636,8 +641,8 @@ def install(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos): shutil.rmtree(tempdir) except Exception, e: module.fail_json(msg="Failure deleting temp directory %s, %s" % (tempdir, e)) - - module.exit_json(**res) + + return res def remove(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos): @@ -691,8 +696,8 @@ def remove(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos): if rc != 0: module.fail_json(**res) - - module.exit_json(**res) + + return res def latest(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos): @@ -774,30 +779,15 @@ def latest(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos): else: res['changed'] = True - module.exit_json(**res) + return res def ensure(module, state, pkgs, conf_file, enablerepo, disablerepo, - disable_gpg_check, exclude): + disable_gpg_check, exclude, repoq): yumbin = module.get_bin_path('yum') # need debug level 2 to get 'Nothing to do' for groupinstall. yum_basecmd = [yumbin, '-d', '2', '-y'] - # If rhn-plugin is installed and no rhn-certificate is available on the - # system then users will see an error message using the yum API. Use - # repoquery in those cases. - - my = yum_base(conf_file) - # A sideeffect of accessing conf is that the configuration is - # loaded and plugins are discovered - my.conf - - repoq = None - if 'rhnplugin' in my.plugins._plugins: - repoquery = module.get_bin_path('repoquery', required=False) - if repoquery: - repoq = [repoquery, '--show-duplicates', '--plugins', '--quiet'] - if conf_file and os.path.exists(conf_file): yum_basecmd += ['-c', conf_file] if repoq: @@ -844,16 +834,19 @@ def ensure(module, state, pkgs, conf_file, enablerepo, disablerepo, if state in ['installed', 'present']: if disable_gpg_check: yum_basecmd.append('--nogpgcheck') - install(module, pkgs, repoq, yum_basecmd, conf_file, en_repos, dis_repos) + res = install(module, pkgs, repoq, yum_basecmd, conf_file, en_repos, dis_repos) elif state in ['removed', 'absent']: - remove(module, pkgs, repoq, yum_basecmd, conf_file, en_repos, dis_repos) + res = remove(module, pkgs, repoq, yum_basecmd, conf_file, en_repos, dis_repos) elif state == 'latest': if disable_gpg_check: yum_basecmd.append('--nogpgcheck') - latest(module, pkgs, repoq, yum_basecmd, conf_file, en_repos, dis_repos) + res = latest(module, pkgs, repoq, yum_basecmd, conf_file, en_repos, dis_repos) + else: + # should be caught by AnsibleModule argument_spec + module.fail_json(msg="we should never get here unless this all + failed", changed=False, results='', errors='unepected state') - # should be caught by AnsibleModule argument_spec - return dict(changed=False, failed=True, results='', errors='unexpected state') + return res def main(): @@ -888,28 +881,39 @@ def main(): supports_check_mode = True ) - # this should not be needed, but exists as a failsafe - params = module.params - if params['install_repoquery'] and not repoquery and not module.check_mode: - install_yum_utils(module) - - repoquerybin = module.get_bin_path('repoquery', required=False) if params['list']: + repoquerybin = ensure_yum_utils(module) if not repoquerybin: module.fail_json(msg="repoquery is required to use list= with this module. Please install the yum-utils package.") results = dict(results=list_stuff(module, repoquerybin, params['conf_file'], params['list'])) - module.exit_json(**results) else: + # If rhn-plugin is installed and no rhn-certificate is available on + # the system then users will see an error message using the yum API. + # Use repoquery in those cases. + + my = yum_base(conf_file) + # A sideeffect of accessing conf is that the configuration is + # loaded and plugins are discovered + my.conf + repoquery = None + if 'rhnplugin' in my.plugins._plugins: + repoquerybin = ensure_yum_utils(module) + if repoquerybin: + repoquery = [repoquerybin, '--show-duplicates', '--plugins', '--quiet'] + pkg = [ p.strip() for p in params['name']] exclude = params['exclude'] state = params['state'] enablerepo = params.get('enablerepo', '') disablerepo = params.get('disablerepo', '') disable_gpg_check = params['disable_gpg_check'] - res = ensure(module, state, pkg, params['conf_file'], enablerepo, - disablerepo, disable_gpg_check, exclude) - module.fail_json(msg="we should never get here unless this all failed", **res) + results = ensure(module, state, pkg, params['conf_file'], enablerepo, + disablerepo, disable_gpg_check, exclude, repoquery) + if repoquery: + results['msg'] = '%s %s' % (results.get('msg',''), 'Warning: Due to potential bad behaviour with rhnplugin and certificates, used slower repoquery calls instead of Yum API.') + + module.exit_json(**results) # import module snippets from ansible.module_utils.basic import *