diff --git a/ansible_mitogen/loaders.py b/ansible_mitogen/loaders.py index 632b11b1..123dd4ac 100644 --- a/ansible_mitogen/loaders.py +++ b/ansible_mitogen/loaders.py @@ -99,5 +99,5 @@ from ansible.plugins.loader import shell_loader from ansible.plugins.loader import strategy_loader # These are original, unwrapped implementations -action_loader__get = action_loader.get -connection_loader__get = connection_loader.get_with_context +action_loader__get_with_context = action_loader.get_with_context +connection_loader__get_with_context = connection_loader.get_with_context diff --git a/ansible_mitogen/planner.py b/ansible_mitogen/planner.py index 4cdc0f20..6490afce 100644 --- a/ansible_mitogen/planner.py +++ b/ansible_mitogen/planner.py @@ -341,6 +341,47 @@ class NewStylePlanner(ScriptPlanner): 'firewalld', # issue #570: ansible module_utils caches dbus conn 'ansible.legacy.dnf', # issue #776 'ansible.builtin.dnf', # issue #832 + 'freeipa.ansible_freeipa.ipaautomember', # issue #1216 + 'freeipa.ansible_freeipa.ipaautomountkey', + 'freeipa.ansible_freeipa.ipaautomountlocation', + 'freeipa.ansible_freeipa.ipaautomountmap', + 'freeipa.ansible_freeipa.ipacert', + 'freeipa.ansible_freeipa.ipaconfig', + 'freeipa.ansible_freeipa.ipadelegation', + 'freeipa.ansible_freeipa.ipadnsconfig', + 'freeipa.ansible_freeipa.ipadnsforwardzone', + 'freeipa.ansible_freeipa.ipadnsrecord', + 'freeipa.ansible_freeipa.ipadnszone', + 'freeipa.ansible_freeipa.ipagroup', + 'freeipa.ansible_freeipa.ipahbacrule', + 'freeipa.ansible_freeipa.ipahbacsvc', + 'freeipa.ansible_freeipa.ipahbacsvcgroup', + 'freeipa.ansible_freeipa.ipahost', + 'freeipa.ansible_freeipa.ipahostgroup', + 'freeipa.ansible_freeipa.idoverridegroup', + 'freeipa.ansible_freeipa.idoverrideuser', + 'freeipa.ansible_freeipa.idp', + 'freeipa.ansible_freeipa.idrange', + 'freeipa.ansible_freeipa.idview', + 'freeipa.ansible_freeipa.ipalocation', + 'freeipa.ansible_freeipa.ipanetgroup', + 'freeipa.ansible_freeipa.ipapermission', + 'freeipa.ansible_freeipa.ipaprivilege', + 'freeipa.ansible_freeipa.ipapwpolicy', + 'freeipa.ansible_freeipa.iparole', + 'freeipa.ansible_freeipa.ipaselfservice', + 'freeipa.ansible_freeipa.ipaserver', + 'freeipa.ansible_freeipa.ipaservice', + 'freeipa.ansible_freeipa.ipaservicedelegationrule', + 'freeipa.ansible_freeipa.ipaservicedelegationtarget', + 'freeipa.ansible_freeipa.ipasudocmd', + 'freeipa.ansible_freeipa.ipasudocmdgroup', + 'freeipa.ansible_freeipa.ipasudorule', + 'freeipa.ansible_freeipa.ipatopologysegment', + 'freeipa.ansible_freeipa.ipatopologysuffix', + 'freeipa.ansible_freeipa.ipatrust', + 'freeipa.ansible_freeipa.ipauser', + 'freeipa.ansible_freeipa.ipavault', ]) def should_fork(self): diff --git a/ansible_mitogen/plugins/connection/mitogen_kubectl.py b/ansible_mitogen/plugins/connection/mitogen_kubectl.py index bae41609..33ae49e6 100644 --- a/ansible_mitogen/plugins/connection/mitogen_kubectl.py +++ b/ansible_mitogen/plugins/connection/mitogen_kubectl.py @@ -46,14 +46,12 @@ import ansible_mitogen.connection import ansible_mitogen.loaders -_get_result = ansible_mitogen.loaders.connection_loader__get( - 'kubectl', - class_only=True, -) - - class Connection(ansible_mitogen.connection.Connection): transport = 'kubectl' + (vanilla_class, load_context) = ansible_mitogen.loaders.connection_loader__get_with_context( + 'kubectl', + class_only=True, + ) not_supported_msg = ( 'The "mitogen_kubectl" plug-in requires a version of Ansible ' @@ -61,17 +59,12 @@ class Connection(ansible_mitogen.connection.Connection): ) def __init__(self, *args, **kwargs): - if not _get_result: + if not Connection.vanilla_class: raise ansible.errors.AnsibleConnectionFailure(self.not_supported_msg) super(Connection, self).__init__(*args, **kwargs) def get_extra_args(self): - try: - # Ansible < 2.10, _get_result is the connection class - connection_options = _get_result.connection_options - except AttributeError: - # Ansible >= 2.10, _get_result is a get_with_context_result - connection_options = _get_result.object.connection_options + connection_options = Connection.vanilla_class.connection_options parameters = [] for key in connection_options: task_var_name = 'ansible_%s' % key diff --git a/ansible_mitogen/plugins/connection/mitogen_ssh.py b/ansible_mitogen/plugins/connection/mitogen_ssh.py index f6a27a6e..b953edba 100644 --- a/ansible_mitogen/plugins/connection/mitogen_ssh.py +++ b/ansible_mitogen/plugins/connection/mitogen_ssh.py @@ -60,7 +60,7 @@ import ansible_mitogen.loaders class Connection(ansible_mitogen.connection.Connection): transport = 'ssh' - vanilla_class = ansible_mitogen.loaders.connection_loader__get( + (vanilla_class, load_context) = ansible_mitogen.loaders.connection_loader__get_with_context( 'ssh', class_only=True, ) diff --git a/ansible_mitogen/strategy.py b/ansible_mitogen/strategy.py index 440e5811..9408ca63 100644 --- a/ansible_mitogen/strategy.py +++ b/ansible_mitogen/strategy.py @@ -47,6 +47,8 @@ import ansible_mitogen.process import ansible.executor.process.worker import ansible.template import ansible.utils.sentinel +import ansible.playbook.play_context +import ansible.plugins.loader def _patch_awx_callback(): @@ -76,12 +78,12 @@ def _patch_awx_callback(): _patch_awx_callback() -def wrap_action_loader__get(name, *args, **kwargs): +def wrap_action_loader__get_with_context(name, *args, **kwargs): """ - While the mitogen strategy is active, trap action_loader.get() calls, - augmenting any fetched class with ActionModuleMixin, which replaces various - helper methods inherited from ActionBase with implementations that avoid - the use of shell fragments wherever possible. + While the mitogen strategy is active, trap action_loader.get_with_context() + calls, augmenting any fetched class with ActionModuleMixin, which replaces + various helper methods inherited from ActionBase with implementations that + avoid the use of shell fragments wherever possible. This is used instead of static subclassing as it generalizes to third party action plugins outside the Ansible tree. @@ -91,13 +93,26 @@ def wrap_action_loader__get(name, *args, **kwargs): name = 'mitogen_' + name get_kwargs['collection_list'] = kwargs.pop('collection_list', None) - klass = ansible_mitogen.loaders.action_loader__get(name, **get_kwargs) + (klass, context) = ansible_mitogen.loaders.action_loader__get_with_context( + name, + **get_kwargs + ) + if klass: bases = (ansible_mitogen.mixins.ActionModuleMixin, klass) adorned_klass = type(str(name), bases, {}) if kwargs.get('class_only'): - return adorned_klass - return adorned_klass(*args, **kwargs) + return ansible.plugins.loader.get_with_context_result( + adorned_klass, + context + ) + + return ansible.plugins.loader.get_with_context_result( + adorned_klass(*args, **kwargs), + context + ) + + return ansible.plugins.loader.get_with_context_result(None, context) REDIRECTED_CONNECTION_PLUGINS = ( @@ -115,15 +130,26 @@ REDIRECTED_CONNECTION_PLUGINS = ( ) -def wrap_connection_loader__get(name, *args, **kwargs): +def wrap_connection_loader__get_with_context(name, *args, **kwargs): """ - While a Mitogen strategy is active, rewrite connection_loader.get() calls - for some transports into requests for a compatible Mitogen transport. + While a Mitogen strategy is active, rewrite + connection_loader.get_with_context() calls for some transports into + requests for a compatible Mitogen transport. """ - if name in REDIRECTED_CONNECTION_PLUGINS: + is_play_using_mitogen_connection = None + if len(args) > 0 and isinstance(args[0], ansible.playbook.play_context.PlayContext): + play_context = args[0] + is_play_using_mitogen_connection = play_context.connection in REDIRECTED_CONNECTION_PLUGINS + + # assume true if we're not in a play context since we're using a Mitogen strategy + if is_play_using_mitogen_connection is None: + is_play_using_mitogen_connection = True + + redirect_connection = name in REDIRECTED_CONNECTION_PLUGINS and is_play_using_mitogen_connection + if redirect_connection: name = 'mitogen_' + name - return ansible_mitogen.loaders.connection_loader__get(name, *args, **kwargs) + return ansible_mitogen.loaders.connection_loader__get_with_context(name, *args, **kwargs) def wrap_worker__run(self): @@ -173,8 +199,8 @@ class AnsibleWrappers(object): Install our PluginLoader monkey patches and update global variables with references to the real functions. """ - ansible_mitogen.loaders.action_loader.get = wrap_action_loader__get - ansible_mitogen.loaders.connection_loader.get_with_context = wrap_connection_loader__get + ansible_mitogen.loaders.action_loader.get_with_context = wrap_action_loader__get_with_context + ansible_mitogen.loaders.connection_loader.get_with_context = wrap_connection_loader__get_with_context global worker__run worker__run = ansible.executor.process.worker.WorkerProcess.run @@ -184,11 +210,11 @@ class AnsibleWrappers(object): """ Uninstall the PluginLoader monkey patches. """ - ansible_mitogen.loaders.action_loader.get = ( - ansible_mitogen.loaders.action_loader__get + ansible_mitogen.loaders.action_loader.get_with_context = ( + ansible_mitogen.loaders.action_loader__get_with_context ) ansible_mitogen.loaders.connection_loader.get_with_context = ( - ansible_mitogen.loaders.connection_loader__get + ansible_mitogen.loaders.connection_loader__get_with_context ) ansible.executor.process.worker.WorkerProcess.run = worker__run diff --git a/docs/changelog.rst b/docs/changelog.rst index 915e10dc..86ed36fb 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -21,7 +21,17 @@ To avail of fixes in an unreleased version, please download a ZIP file In progress (unreleased) ------------------------ + + +v0.3.21 (2025-01-20) +-------------------- + * :gh:issue:`1209` docs: Fix Netlify build of website +* :gh:issue:`1216` :mod:`ansible_mitogen`: Add all ansible_freeipa modules to + the always-fork list. +* :gh:issue:`766` :mod:`ansible_mitogen`: Fix ""could not recover task_vars" + and "get_with_context_result object has no attribute _create_control_path" + when using ``kubectl``, ``netconf``, or ``network_cli`` connection plugins. v0.3.20 (2025-01-07) diff --git a/docs/contributors.rst b/docs/contributors.rst index ad35f91c..c37b64c9 100644 --- a/docs/contributors.rst +++ b/docs/contributors.rst @@ -124,6 +124,7 @@ sponsorship and outstanding future-thinking of its early adopters.