summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/ansible/config/ansible_builtin_runtime.yml7
-rw-r--r--lib/ansible/executor/task_queue_manager.py30
2 files changed, 29 insertions, 8 deletions
diff --git a/lib/ansible/config/ansible_builtin_runtime.yml b/lib/ansible/config/ansible_builtin_runtime.yml
index b412518ab1..e7d35fb3d8 100644
--- a/lib/ansible/config/ansible_builtin_runtime.yml
+++ b/lib/ansible/config/ansible_builtin_runtime.yml
@@ -8290,6 +8290,13 @@ plugin_routing:
redirect: ansible.posix.timer
foreman:
redirect: theforeman.foreman.foreman
+ # 'collections' integration test entries, do not remove
+ formerly_core_callback:
+ redirect: testns.testcoll.usercallback
+ formerly_core_removed_callback:
+ redirect: testns.testcoll.removedcallback
+ formerly_core_missing_callback:
+ redirect: bogusns.boguscoll.boguscallback
doc_fragments:
a10:
redirect: community.network.a10
diff --git a/lib/ansible/executor/task_queue_manager.py b/lib/ansible/executor/task_queue_manager.py
index cd6c396860..e7277c9183 100644
--- a/lib/ansible/executor/task_queue_manager.py
+++ b/lib/ansible/executor/task_queue_manager.py
@@ -138,6 +138,9 @@ class TaskQueueManager:
else:
raise AnsibleError("callback must be an instance of CallbackBase or the name of a callback plugin")
+ loaded_callbacks = set()
+
+ # first, load callbacks in the core distribution and configured callback paths
for callback_plugin in callback_loader.all(class_only=True):
callback_type = getattr(callback_plugin, 'CALLBACK_TYPE', '')
callback_needs_whitelist = getattr(callback_plugin, 'CALLBACK_NEEDS_WHITELIST', False)
@@ -150,23 +153,34 @@ class TaskQueueManager:
elif callback_name == 'tree' and self._run_tree:
# special case for ansible cli option
pass
+ # eg, ad-hoc doesn't allow non-default callbacks
elif not self._run_additional_callbacks or (callback_needs_whitelist and (
C.DEFAULT_CALLBACK_WHITELIST is None or callback_name not in C.DEFAULT_CALLBACK_WHITELIST)):
# 2.x plugins shipped with ansible should require whitelisting, older or non shipped should load automatically
continue
callback_obj = callback_plugin()
+ loaded_callbacks.add(callback_name) # mark as loaded so we skip in second pass
callback_obj.set_options()
self._callback_plugins.append(callback_obj)
- for callback_plugin_name in (c for c in C.DEFAULT_CALLBACK_WHITELIST if AnsibleCollectionRef.is_valid_fqcr(c)):
- # TODO: need to extend/duplicate the stdout callback check here (and possible move this ahead of the old way
- callback_obj = callback_loader.get(callback_plugin_name)
- if callback_obj:
- callback_obj.set_options()
- self._callback_plugins.append(callback_obj)
- else:
- display.warning("Skipping '%s', unable to load or use as a callback" % callback_plugin_name)
+ # eg, ad-hoc doesn't allow non-default callbacks
+ if self._run_additional_callbacks:
+ # Second pass over everything in the whitelist we haven't already loaded, try to explicitly load. This will catch
+ # collection-hosted callbacks, as well as formerly-core callbacks that have been redirected to collections.
+ for callback_plugin_name in (c for c in C.DEFAULT_CALLBACK_WHITELIST if c not in loaded_callbacks):
+ # TODO: need to extend/duplicate the stdout callback check here (and possible move this ahead of the old way
+ callback_obj, plugin_load_context = callback_loader.get_with_context(callback_plugin_name)
+ if callback_obj:
+ loaded_as_name = callback_obj._redirected_names[-1]
+ if loaded_as_name in loaded_callbacks:
+ display.warning("Skipping callback '%s', already loaded as '%s'." % (callback_plugin_name, loaded_as_name))
+ continue
+ loaded_callbacks.add(loaded_as_name)
+ callback_obj.set_options()
+ self._callback_plugins.append(callback_obj)
+ else:
+ display.warning("Skipping '%s', unable to load or use as a callback" % callback_plugin_name)
self._callbacks_loaded = True