mirror of
https://github.com/ansible/ansible.git
synced 2026-05-28 04:32:20 -04:00
package, allow to use actions over modules
add ability to override/set package managers
added collection specified action plugin
Co-authored-by: 🇺🇦 Sviatoslav Sydorenko (Святослав Сидоренко) <wk.cvs.github@sydorenko.org.ua>
This commit is contained in:
parent
2991883672
commit
a595ac2f2c
2 changed files with 57 additions and 21 deletions
|
|
@ -1822,6 +1822,13 @@ OLD_PLUGIN_CACHE_CLEARING:
|
|||
type: boolean
|
||||
default: False
|
||||
version_added: "2.8"
|
||||
PACKAGE_MANAGERS:
|
||||
name: Map of package facts to actions.
|
||||
description: A dictionary mapping the detected pkg_mgr fact to the action that should resolve it.
|
||||
default: {}
|
||||
type: dict
|
||||
vars:
|
||||
- name: ansible_package_managers
|
||||
PAGER:
|
||||
name: pager application to use
|
||||
default: less
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||
from __future__ import annotations
|
||||
|
||||
from ansible import constants as C
|
||||
from ansible.errors import AnsibleActionFail
|
||||
from ansible.executor.module_common import _apply_action_arg_defaults
|
||||
from ansible.module_utils.facts.system.pkg_mgr import PKG_MGRS
|
||||
|
|
@ -32,7 +33,7 @@ class ActionModule(ActionBase):
|
|||
|
||||
BUILTIN_PKG_MGR_MODULES = {manager['name'] for manager in PKG_MGRS}
|
||||
|
||||
def run(self, tmp=None, task_vars=None):
|
||||
def run(self, tmp: str | None = None, task_vars: dict | None = None) -> dict:
|
||||
""" handler for package operations """
|
||||
|
||||
self._supports_check_mode = True
|
||||
|
|
@ -40,10 +41,10 @@ class ActionModule(ActionBase):
|
|||
|
||||
super(ActionModule, self).run(tmp, task_vars)
|
||||
|
||||
module = self._task.args.get('use', 'auto')
|
||||
action = self._task.args.get('use', 'auto')
|
||||
|
||||
try:
|
||||
if module == 'auto':
|
||||
if action == 'auto':
|
||||
|
||||
if self._task.delegate_to:
|
||||
hosts_vars = task_vars['hostvars'][self._task.delegate_to]
|
||||
|
|
@ -53,9 +54,9 @@ class ActionModule(ActionBase):
|
|||
tvars = task_vars
|
||||
|
||||
# use config
|
||||
module = tvars.get('ansible_package_use', None)
|
||||
action = tvars.get('ansible_package_use', None)
|
||||
|
||||
if not module:
|
||||
if not action:
|
||||
# no use, no config, get from facts
|
||||
if hosts_vars.get('ansible_facts', {}).get('pkg_mgr', False):
|
||||
facts = hosts_vars
|
||||
|
|
@ -77,29 +78,57 @@ class ActionModule(ActionBase):
|
|||
|
||||
try:
|
||||
# actually get from facts
|
||||
module = facts['ansible_facts'][pmgr]
|
||||
action = facts['ansible_facts'][pmgr]
|
||||
except KeyError:
|
||||
raise AnsibleActionFail('Could not detect a package manager. Try using the "use" option.')
|
||||
|
||||
if module and module != 'auto':
|
||||
if not self._shared_loader_obj.module_loader.has_plugin(module):
|
||||
raise AnsibleActionFail('Could not find a matching action for the "%s" package manager.' % module)
|
||||
else:
|
||||
# run the 'package' module
|
||||
new_module_args = self._task.args.copy()
|
||||
if 'use' in new_module_args:
|
||||
del new_module_args['use']
|
||||
if action and action != 'auto':
|
||||
module_context = None
|
||||
|
||||
# see if we use custom mapped, use orig if not
|
||||
action = C.PACKAGE_MANAGERS.get(action, action)
|
||||
# prefix with ansible.legacy to eliminate external collisions while still allowing library/ override
|
||||
if action in self.BUILTIN_PKG_MGR_MODULES:
|
||||
action = f'ansible.legacy.{action}'
|
||||
|
||||
# find what to execute, action plugins having priority
|
||||
has_action_plugin = self._shared_loader_obj.module_loader.has_plugin(action)
|
||||
if not has_action_plugin:
|
||||
module_context = self._shared_loader_obj.module_loader.find_plugin_with_context(action, collection_list=self._task.collections)
|
||||
if module_context and module_context.resolved and module_context.action_plugin:
|
||||
# module itself specifies action plugin
|
||||
action = module_context.action_plugin
|
||||
has_action_plugin = True
|
||||
|
||||
# prep to run he action
|
||||
new_module_args = self._task.args.copy()
|
||||
if 'use' in new_module_args:
|
||||
del new_module_args['use']
|
||||
|
||||
if has_action_plugin:
|
||||
display.vvvv(f"Chose {action!r} action plugin")
|
||||
new_task = new_task = self._task.copy()
|
||||
new_task.args.update(new_module_args)
|
||||
pkg_action, action_context = self._shared_loader_obj.action_loader.get_with_context(action,
|
||||
task=new_task,
|
||||
connection=self._connection,
|
||||
play_context=self._play_context,
|
||||
loader=self._loader,
|
||||
templar=self._templar,
|
||||
shared_loader_obj=self._shared_loader_obj)
|
||||
if pkg_action:
|
||||
display.vvvv(f"Running {action!r}")
|
||||
return pkg_action.run(task_vars=task_vars)
|
||||
else:
|
||||
raise AnsibleActionFail(f"Failed to load {action!r}: {action_context!r}")
|
||||
elif module_context and module_context.resolved:
|
||||
display.vvvv(f"Chose {action!r} module")
|
||||
# get defaults for specific module
|
||||
context = self._shared_loader_obj.module_loader.find_plugin_with_context(module, collection_list=self._task.collections)
|
||||
new_module_args = _apply_action_arg_defaults(context.resolved_fqcn, self._task, new_module_args, self._templar)
|
||||
new_module_args = _apply_action_arg_defaults(module_context.resolved_fqcn, self._task, new_module_args, self._templar)
|
||||
|
||||
if module in self.BUILTIN_PKG_MGR_MODULES:
|
||||
# prefix with ansible.legacy to eliminate external collisions while still allowing library/ override
|
||||
module = 'ansible.legacy.' + module
|
||||
|
||||
display.vvvv("Running %s" % module)
|
||||
return self._execute_module(module_name=module, module_args=new_module_args, task_vars=task_vars, wrap_async=self._task.async_val)
|
||||
display.vvvv(f"Running {action!r}")
|
||||
return self._execute_module(module_name=action, module_args=new_module_args, task_vars=task_vars, wrap_async=self._task.async_val)
|
||||
else:
|
||||
raise AnsibleActionFail('Could not detect which package manager to use. Try gathering facts or setting the "use" option.')
|
||||
finally:
|
||||
|
|
|
|||
Loading…
Reference in a new issue