diff --git a/changelogs/fragments/fqn-module-cache.yml b/changelogs/fragments/fqn-module-cache.yml new file mode 100644 index 00000000000..9dffb3d231d --- /dev/null +++ b/changelogs/fragments/fqn-module-cache.yml @@ -0,0 +1,5 @@ +bugfixes: +- AnsiballZ - Ensure we use the full python package in the module cache filename + to avoid a case where ``collections:`` is used to execute a module via short name, + where the short name duplicates another module from ``ansible.builtin`` or another + collection that was executed previously. diff --git a/lib/ansible/executor/module_common.py b/lib/ansible/executor/module_common.py index c3aa8b2d846..9b54eac689f 100644 --- a/lib/ansible/executor/module_common.py +++ b/lib/ansible/executor/module_common.py @@ -1153,7 +1153,7 @@ def _find_module_utils(module_name, b_module_data, module_path, module_args, tas compression_method = zipfile.ZIP_STORED lookup_path = os.path.join(C.DEFAULT_LOCAL_TMP, 'ansiballz_cache') - cached_module_filename = os.path.join(lookup_path, "%s-%s" % (module_name, module_compression)) + cached_module_filename = os.path.join(lookup_path, "%s-%s" % (remote_module_fqn, module_compression)) zipdata = None # Optimization -- don't lock if the module has already been cached diff --git a/test/integration/targets/collections/ansiballz_dupe/collections/ansible_collections/duplicate/name/plugins/modules/ping.py b/test/integration/targets/collections/ansiballz_dupe/collections/ansible_collections/duplicate/name/plugins/modules/ping.py new file mode 100644 index 00000000000..d0fdba76781 --- /dev/null +++ b/test/integration/targets/collections/ansiballz_dupe/collections/ansible_collections/duplicate/name/plugins/modules/ping.py @@ -0,0 +1,3 @@ +#!/usr/bin/python +from ansible.module_utils.basic import AnsibleModule +AnsibleModule({}).exit_json(ping='duplicate.name.pong') diff --git a/test/integration/targets/collections/ansiballz_dupe/test_ansiballz_cache_dupe_shortname.yml b/test/integration/targets/collections/ansiballz_dupe/test_ansiballz_cache_dupe_shortname.yml new file mode 100644 index 00000000000..25526246e71 --- /dev/null +++ b/test/integration/targets/collections/ansiballz_dupe/test_ansiballz_cache_dupe_shortname.yml @@ -0,0 +1,15 @@ +- hosts: localhost + gather_facts: false + tasks: + - ping: + register: result1 + + - ping: + collections: + - duplicate.name + register: result2 + + - assert: + that: + - result1.ping == 'pong' + - result2.ping == 'duplicate.name.pong' diff --git a/test/integration/targets/collections/runme.sh b/test/integration/targets/collections/runme.sh index 5a5261bb932..d9d8a31af57 100755 --- a/test/integration/targets/collections/runme.sh +++ b/test/integration/targets/collections/runme.sh @@ -100,6 +100,9 @@ ansible-playbook inventory_test.yml -i a.statichost.yml -i redirected.statichost # test plugin loader redirect_list ansible-playbook test_redirect_list.yml -v "$@" +# test ansiballz cache dupe +ansible-playbook ansiballz_dupe/test_ansiballz_cache_dupe_shortname.yml -v "$@" + # test adjacent with --playbook-dir export ANSIBLE_COLLECTIONS_PATH='' ANSIBLE_INVENTORY_ANY_UNPARSED_IS_FAILED=1 ansible-inventory --list --export --playbook-dir=. -v "$@"