From 8d1f2ba9d9ba159110986486875a90c4a10ee56e Mon Sep 17 00:00:00 2001 From: Andrew Widdersheim Date: Wed, 23 May 2018 22:04:05 -0400 Subject: [PATCH] yum: Propagate plugins to all parts of the module (#40085) In `2.5` (d1b63bd5), the `yum` module received the capability to disable and enable specific plugins. However, these changes only applied to certain parts of the logic. This change propagates those changes to the rest of the module, specifically those using the `yum` API. --- lib/ansible/modules/packaging/os/yum.py | 124 +++++++++++++++--------- 1 file changed, 78 insertions(+), 46 deletions(-) diff --git a/lib/ansible/modules/packaging/os/yum.py b/lib/ansible/modules/packaging/os/yum.py index 6f2227d78e8..a4c6d6e5836 100644 --- a/lib/ansible/modules/packaging/os/yum.py +++ b/lib/ansible/modules/packaging/os/yum.py @@ -285,11 +285,13 @@ def_qf = "%{epoch}:%{name}-%{version}-%{release}.%{arch}" rpmbin = None -def yum_base(conf_file=None, installroot='/'): +def yum_base(conf_file=None, installroot='/', enabled_plugins=None, disabled_plugins=None): my = yum.YumBase() my.preconf.debuglevel = 0 my.preconf.errorlevel = 0 my.preconf.plugins = True + my.preconf.enabled_plugins = enabled_plugins + my.preconf.disabled_plugins = disabled_plugins # my.preconf.releasever = '/' if installroot != '/': # do not setup installroot by default, because of error @@ -352,10 +354,10 @@ def po_to_envra(po): return '%s:%s-%s-%s.%s' % (po.epoch, po.name, po.version, po.release, po.arch) -def is_group_env_installed(name, conf_file, installroot='/'): +def is_group_env_installed(name, conf_file, en_plugins=None, dis_plugins=None, installroot='/'): name_lower = name.lower() - my = yum_base(conf_file, installroot) + my = yum_base(conf_file, installroot, en_plugins, dis_plugins) if yum.__version_info__ >= (3, 4): groups_list = my.doGroupLists(return_evgrps=True) else: @@ -377,7 +379,7 @@ def is_group_env_installed(name, conf_file, installroot='/'): return False -def is_installed(module, repoq, pkgspec, conf_file, qf=None, en_repos=None, dis_repos=None, is_pkg=False, installroot='/'): +def is_installed(module, repoq, pkgspec, conf_file, qf=None, en_repos=None, dis_repos=None, en_plugins=None, dis_plugins=None, is_pkg=False, installroot='/'): if en_repos is None: en_repos = [] if dis_repos is None: @@ -388,7 +390,7 @@ def is_installed(module, repoq, pkgspec, conf_file, qf=None, en_repos=None, dis_ if not repoq: pkgs = [] try: - my = yum_base(conf_file, installroot) + my = yum_base(conf_file, installroot, en_plugins, dis_plugins) for rid in dis_repos: my.repos.disableRepo(rid) for rid in en_repos: @@ -439,7 +441,7 @@ def is_installed(module, repoq, pkgspec, conf_file, qf=None, en_repos=None, dis_ return [] -def is_available(module, repoq, pkgspec, conf_file, qf=def_qf, en_repos=None, dis_repos=None, installroot='/'): +def is_available(module, repoq, pkgspec, conf_file, qf=def_qf, en_repos=None, dis_repos=None, en_plugins=None, dis_plugins=None, installroot='/'): if en_repos is None: en_repos = [] if dis_repos is None: @@ -449,7 +451,7 @@ def is_available(module, repoq, pkgspec, conf_file, qf=def_qf, en_repos=None, di pkgs = [] try: - my = yum_base(conf_file, installroot) + my = yum_base(conf_file, installroot, en_plugins, dis_plugins) for rid in dis_repos: my.repos.disableRepo(rid) for rid in en_repos: @@ -483,7 +485,7 @@ def is_available(module, repoq, pkgspec, conf_file, qf=def_qf, en_repos=None, di return [] -def is_update(module, repoq, pkgspec, conf_file, qf=def_qf, en_repos=None, dis_repos=None, installroot='/'): +def is_update(module, repoq, pkgspec, conf_file, qf=def_qf, en_repos=None, dis_repos=None, en_plugins=None, dis_plugins=None, installroot='/'): if en_repos is None: en_repos = [] if dis_repos is None: @@ -496,7 +498,7 @@ def is_update(module, repoq, pkgspec, conf_file, qf=def_qf, en_repos=None, dis_r updates = [] try: - my = yum_base(conf_file, installroot) + my = yum_base(conf_file, installroot, en_plugins, dis_plugins) for rid in dis_repos: my.repos.disableRepo(rid) for rid in en_repos: @@ -535,7 +537,9 @@ def is_update(module, repoq, pkgspec, conf_file, qf=def_qf, en_repos=None, dis_r return set() -def what_provides(module, repoq, yum_basecmd, req_spec, conf_file, qf=def_qf, en_repos=None, dis_repos=None, installroot='/'): +def what_provides(module, repoq, yum_basecmd, req_spec, conf_file, qf=def_qf, + en_repos=None, dis_repos=None, en_plugins=None, + dis_plugins=None, installroot='/'): if en_repos is None: en_repos = [] if dis_repos is None: @@ -545,7 +549,7 @@ def what_provides(module, repoq, yum_basecmd, req_spec, conf_file, qf=def_qf, en pkgs = [] try: - my = yum_base(conf_file, installroot) + my = yum_base(conf_file, installroot, en_plugins, dis_plugins) for rid in dis_repos: my.repos.disableRepo(rid) for rid in en_repos: @@ -790,7 +794,7 @@ def exec_install(module, items, action, pkgs, res, yum_basecmd): return res -def install(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos, installroot='/', allow_downgrade=False): +def install(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos, en_plugins, dis_plugins, installroot='/', allow_downgrade=False): pkgs = [] downgrade_pkgs = [] @@ -822,13 +826,17 @@ def install(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos, i envra = local_envra(package) if envra is None: module.fail_json(msg="Failed to get nevra information from RPM package: %s" % spec) - installed_pkgs = is_installed(module, repoq, envra, conf_file, en_repos=en_repos, dis_repos=dis_repos, installroot=installroot) + installed_pkgs = is_installed(module, repoq, envra, conf_file, en_repos=en_repos, + dis_repos=dis_repos, en_plugins=en_plugins, + dis_plugins=dis_plugins, installroot=installroot) if installed_pkgs: res['results'].append('%s providing %s is already installed' % (installed_pkgs[0], package)) continue (name, ver, rel, epoch, arch) = splitFilename(envra) - installed_pkgs = is_installed(module, repoq, name, conf_file, en_repos=en_repos, dis_repos=dis_repos, installroot=installroot) + installed_pkgs = is_installed(module, repoq, name, conf_file, en_repos=en_repos, + dis_repos=dis_repos, en_plugins=en_plugins, + dis_plugins=dis_plugins, installroot=installroot) # case for two same envr but differrent archs like x86_64 and i686 if len(installed_pkgs) == 2: @@ -863,7 +871,7 @@ def install(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos, i # groups elif spec.startswith('@'): - if is_group_env_installed(spec, conf_file, installroot=installroot): + if is_group_env_installed(spec, conf_file, en_plugins=en_plugins, dis_plugins=dis_plugins, installroot=installroot): continue pkg = spec @@ -874,13 +882,18 @@ def install(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos, i # 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)): - installed_pkgs = is_installed(module, repoq, spec, conf_file, en_repos=en_repos, dis_repos=dis_repos, is_pkg=True, installroot=installroot) + installed_pkgs = is_installed(module, repoq, spec, conf_file, en_repos=en_repos, + dis_repos=dis_repos, en_plugins=en_plugins, + dis_plugins=dis_plugins, is_pkg=True, + installroot=installroot) if installed_pkgs: res['results'].append('%s providing %s is already installed' % (installed_pkgs[0], spec)) continue # look up what pkgs provide this - pkglist = what_provides(module, repoq, yum_basecmd, spec, conf_file, en_repos=en_repos, dis_repos=dis_repos, installroot=installroot) + pkglist = what_provides(module, repoq, yum_basecmd, spec, conf_file, en_repos=en_repos, + dis_repos=dis_repos, en_plugins=en_plugins, dis_plugins=dis_plugins, + installroot=installroot) if not pkglist: res['msg'] += "No package matching '%s' found available, installed or updated" % spec res['results'].append("No package matching '%s' found available, installed or updated" % spec) @@ -900,7 +913,9 @@ def install(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos, i found = False for this in pkglist: - if is_installed(module, repoq, this, conf_file, en_repos=en_repos, dis_repos=dis_repos, is_pkg=True, installroot=installroot): + if is_installed(module, repoq, this, conf_file, en_repos=en_repos, dis_repos=dis_repos, + en_plugins=en_plugins, dis_plugins=dis_plugins, is_pkg=True, + installroot=installroot): found = True res['results'].append('%s providing %s is already installed' % (this, spec)) break @@ -911,7 +926,8 @@ def install(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos, i # but virt provides should be all caught in what_provides on its own. # highly irritating if not found: - if is_installed(module, repoq, spec, conf_file, en_repos=en_repos, dis_repos=dis_repos, installroot=installroot): + if is_installed(module, repoq, spec, conf_file, en_repos=en_repos, dis_repos=dis_repos, + en_plugins=en_plugins, dis_plugins=dis_plugins, installroot=installroot): found = True res['results'].append('package providing %s is already installed' % (spec)) @@ -929,7 +945,9 @@ def install(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos, i (name, ver, rel, epoch, arch) = splitFilename(package) # Check if any version of the requested package is installed - inst_pkgs = is_installed(module, repoq, name, conf_file, en_repos=en_repos, dis_repos=dis_repos, is_pkg=True) + inst_pkgs = is_installed(module, repoq, name, conf_file, en_repos=en_repos, + dis_repos=dis_repos, en_plugins=en_plugins, + dis_plugins=dis_plugins, is_pkg=True) if inst_pkgs: (cur_name, cur_ver, cur_rel, cur_epoch, cur_arch) = splitFilename(inst_pkgs[0]) compare = compareEVR((cur_epoch, cur_ver, cur_rel), (epoch, ver, rel)) @@ -958,7 +976,7 @@ def install(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos, i return res -def remove(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos, installroot='/'): +def remove(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos, en_plugins, dis_plugins, installroot='/'): pkgs = [] res = {} @@ -969,9 +987,11 @@ def remove(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos, in for pkg in items: if pkg.startswith('@'): - installed = is_group_env_installed(pkg, conf_file, installroot=installroot) + installed = is_group_env_installed(pkg, conf_file, en_plugins=en_plugins, dis_plugins=dis_plugins, installroot=installroot) else: - installed = is_installed(module, repoq, pkg, conf_file, en_repos=en_repos, dis_repos=dis_repos, installroot=installroot) + installed = is_installed(module, repoq, pkg, conf_file, en_repos=en_repos, + dis_repos=dis_repos, en_plugins=en_plugins, + dis_plugins=dis_plugins, installroot=installroot) if installed: pkgs.append(pkg) @@ -1002,9 +1022,11 @@ def remove(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos, in # at this point we check to see if the pkg is no longer present for pkg in pkgs: if pkg.startswith('@'): - installed = is_group_env_installed(pkg, conf_file, installroot=installroot) + installed = is_group_env_installed(pkg, conf_file, en_plugins=en_plugins, dis_plugins=dis_plugins, installroot=installroot) else: - installed = is_installed(module, repoq, pkg, conf_file, en_repos=en_repos, dis_repos=dis_repos, installroot=installroot) + installed = is_installed(module, repoq, pkg, conf_file, en_repos=en_repos, + dis_repos=dis_repos, en_plugins=en_plugins, + dis_plugins=dis_plugins, installroot=installroot) if installed: module.fail_json(**res) @@ -1060,7 +1082,7 @@ def parse_check_update(check_update_output): return updates -def latest(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos, update_only, installroot='/'): +def latest(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos, en_plugins, dis_plugins, update_only, installroot='/'): res = {} res['results'] = [] @@ -1120,7 +1142,9 @@ def latest(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos, up module.fail_json(msg="Failed to get nevra information from RPM package: %s" % spec) # local rpm files can't be updated - if not is_installed(module, repoq, envra, conf_file, en_repos=en_repos, dis_repos=dis_repos, installroot=installroot): + if not is_installed(module, repoq, envra, conf_file, en_repos=en_repos, + dis_repos=dis_repos, en_plugins=en_plugins, + dis_plugins=dis_plugins, installroot=installroot): pkgs['install'].append(spec) continue @@ -1135,17 +1159,22 @@ def latest(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos, up module.fail_json(msg="Failed to get nevra information from RPM package: %s" % spec) # local rpm files can't be updated - if not is_installed(module, repoq, envra, conf_file, en_repos=en_repos, dis_repos=dis_repos, installroot=installroot): + if not is_installed(module, repoq, envra, conf_file, en_repos=en_repos, + dis_repos=dis_repos, en_plugins=en_plugins, + dis_plugins=dis_plugins, installroot=installroot): pkgs['install'].append(package) continue # dep/pkgname - find it else: - if is_installed(module, repoq, spec, conf_file, en_repos=en_repos, dis_repos=dis_repos, installroot=installroot) or update_only: + if is_installed(module, repoq, spec, conf_file, en_repos=en_repos, dis_repos=dis_repos, + en_plugins=en_plugins, dis_plugins=dis_plugins, installroot=installroot) or update_only: pkgs['update'].append(spec) else: pkgs['install'].append(spec) - pkglist = what_provides(module, repoq, yum_basecmd, spec, conf_file, en_repos=en_repos, dis_repos=dis_repos, installroot=installroot) + pkglist = what_provides(module, repoq, yum_basecmd, spec, conf_file, en_repos=en_repos, + dis_repos=dis_repos, en_plugins=en_plugins, dis_plugins=dis_plugins, + installroot=installroot) # FIXME..? may not be desirable to throw an exception here if a single package is missing if not pkglist: res['msg'] += "No package matching '%s' found available, installed or updated" % spec @@ -1155,7 +1184,10 @@ def latest(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos, up nothing_to_do = True for pkg in pkglist: - if spec in pkgs['install'] and is_available(module, repoq, pkg, conf_file, en_repos=en_repos, dis_repos=dis_repos, installroot=installroot): + if spec in pkgs['install'] and is_available(module, repoq, pkg, conf_file, + en_repos=en_repos, dis_repos=dis_repos, + en_plugins=en_plugins, dis_plugins=dis_plugins, + installroot=installroot): nothing_to_do = False break @@ -1173,7 +1205,9 @@ def latest(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos, up will_update_from_other_package[spec] = pkgname break - if not is_installed(module, repoq, spec, conf_file, en_repos=en_repos, dis_repos=dis_repos, installroot=installroot) and update_only: + if not is_installed(module, repoq, spec, conf_file, en_repos=en_repos, + dis_repos=dis_repos, en_plugins=en_plugins, + dis_plugins=dis_plugins, installroot=installroot) and update_only: res['results'].append("Packages providing %s not installed due to update_only specified" % spec) continue if nothing_to_do: @@ -1238,7 +1272,7 @@ def latest(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos, up def ensure(module, state, pkgs, conf_file, enablerepo, disablerepo, disable_gpg_check, exclude, repoq, skip_broken, update_only, security, - installroot='/', allow_downgrade=False, disable_plugin='', enable_plugin=''): + installroot='/', allow_downgrade=False, disable_plugin=None, enable_plugin=None): # fedora will redirect yum to dnf, which has incompatibilities # with how this module expects yum to operate. If yum-deprecated @@ -1272,10 +1306,10 @@ def ensure(module, state, pkgs, conf_file, enablerepo, disablerepo, yum_basecmd.extend(r_cmd) if enable_plugin: - yum_basecmd.extend(['--enableplugin', enable_plugin]) + yum_basecmd.extend(['--enableplugin', ','.join(enable_plugin)]) if disable_plugin: - yum_basecmd.extend(['--disableplugin', disable_plugin]) + yum_basecmd.extend(['--disableplugin', ','.join(disable_plugin)]) if exclude: e_cmd = ['--exclude=%s' % exclude] @@ -1317,7 +1351,7 @@ def ensure(module, state, pkgs, conf_file, enablerepo, disablerepo, if module.params.get('update_cache'): module.run_command(yum_basecmd + ['clean', 'expire-cache']) - my = yum_base(conf_file, installroot) + my = yum_base(conf_file, installroot, enable_plugin, disable_plugin) try: if disablerepo: my.repos.disableRepo(disablerepo) @@ -1338,15 +1372,17 @@ def ensure(module, state, pkgs, conf_file, enablerepo, disablerepo, if state in ['installed', 'present']: if disable_gpg_check: yum_basecmd.append('--nogpgcheck') - res = install(module, pkgs, repoq, yum_basecmd, conf_file, en_repos, dis_repos, installroot=installroot, allow_downgrade=allow_downgrade) + res = install(module, pkgs, repoq, yum_basecmd, conf_file, en_repos, dis_repos, + enable_plugin, disable_plugin, installroot=installroot, + allow_downgrade=allow_downgrade) elif state in ['removed', 'absent']: - res = remove(module, pkgs, repoq, yum_basecmd, conf_file, en_repos, dis_repos, installroot=installroot) + res = remove(module, pkgs, repoq, yum_basecmd, conf_file, en_repos, dis_repos, enable_plugin, disable_plugin, installroot=installroot) elif state == 'latest': if disable_gpg_check: yum_basecmd.append('--nogpgcheck') if security: yum_basecmd.append('--security') - res = latest(module, pkgs, repoq, yum_basecmd, conf_file, en_repos, dis_repos, update_only, installroot=installroot) + res = latest(module, pkgs, repoq, yum_basecmd, conf_file, en_repos, dis_repos, enable_plugin, disable_plugin, update_only, installroot=installroot) else: # should be caught by AnsibleModule argument_spec module.fail_json(msg="we should never get here unless this all failed", @@ -1404,12 +1440,8 @@ def main(): module.fail_json(msg='. '.join(error_msgs)) params = module.params - enable_plugin = params.get('enable_plugin', '') - if enable_plugin: - enable_plugin = ','.join(enable_plugin) - disable_plugin = params.get('disable_plugin', '') - if disable_plugin: - disable_plugin = ','.join(disable_plugin) + enable_plugin = params.get('enable_plugin') + disable_plugin = params.get('disable_plugin') if params['list']: repoquerybin = ensure_yum_utils(module) @@ -1423,7 +1455,7 @@ def main(): # the system then users will see an error message using the yum API. # Use repoquery in those cases. - my = yum_base(params['conf_file'], params['installroot']) + my = yum_base(params['conf_file'], params['installroot'], enable_plugin, disable_plugin) # A sideeffect of accessing conf is that the configuration is # loaded and plugins are discovered my.conf