Fix Jinja plugin deduplication (#82002) (#82054)

for j2 plugins dedupe on path and  not basename
for j2 this is a container file , for other plugins file name == plugin name

(cherry picked from commit b4566c18b3)
pull/82092/head
Brian Coca 1 year ago committed by GitHub
parent 0c98b2256c
commit 8896db97ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,3 @@
bugfixes:
- Plugin loader does not dedupe nor cache filter/test plugins by file basename, but full path name.
- Restoring the ability of filters/tests can have same file base name but different tests/filters defined inside.

@ -986,23 +986,32 @@ class PluginLoader:
loaded_modules = set()
for path in all_matches:
name = os.path.splitext(path)[0]
basename = os.path.basename(name)
is_j2 = isinstance(self, Jinja2Loader)
if is_j2:
ref_name = path
else:
ref_name = basename
if basename in _PLUGIN_FILTERS[self.package]:
if not is_j2 and basename in _PLUGIN_FILTERS[self.package]:
# j2 plugins get processed in own class, here they would just be container files
display.debug("'%s' skipped due to a defined plugin filter" % basename)
continue
if basename == '__init__' or (basename == 'base' and self.package == 'ansible.plugins.cache'):
# cache has legacy 'base.py' file, which is wrapper for __init__.py
display.debug("'%s' skipped due to reserved name" % basename)
display.debug("'%s' skipped due to reserved name" % name)
continue
if dedupe and basename in loaded_modules:
display.debug("'%s' skipped as duplicate" % basename)
if dedupe and ref_name in loaded_modules:
# for j2 this is 'same file', other plugins it is basename
display.debug("'%s' skipped as duplicate" % ref_name)
continue
loaded_modules.add(basename)
loaded_modules.add(ref_name)
if path_only:
yield path

@ -0,0 +1,7 @@
- hosts: localhost
gather_facts: false
roles:
- r1
- r2
tasks:
- debug: msg={{'a'|filter1|filter2|filter3}}

@ -0,0 +1,15 @@
from __future__ import annotations
def do_nothing(myval):
return myval
class FilterModule(object):
''' Ansible core jinja2 filters '''
def filters(self):
return {
'filter1': do_nothing,
'filter3': do_nothing,
}

@ -0,0 +1,18 @@
DOCUMENTATION:
name: filter1
version_added: "1.9"
short_description: Does nothing
description:
- Really, does nothing
notes:
- This is a test filter
positional: _input
options:
_input:
description: the input
required: true
EXAMPLES: ''
RETURN:
_value:
description: The input

@ -0,0 +1,18 @@
DOCUMENTATION:
name: filter3
version_added: "1.9"
short_description: Does nothing
description:
- Really, does nothing
notes:
- This is a test filter
positional: _input
options:
_input:
description: the input
required: true
EXAMPLES: ''
RETURN:
_value:
description: The input

@ -0,0 +1,14 @@
from __future__ import annotations
def do_nothing(myval):
return myval
class FilterModule(object):
''' Ansible core jinja2 filters '''
def filters(self):
return {
'filter2': do_nothing,
}

@ -0,0 +1,18 @@
DOCUMENTATION:
name: filter2
version_added: "1.9"
short_description: Does nothing
description:
- Really, does nothing
notes:
- This is a test filter
positional: _input
options:
_input:
description: the input
required: true
EXAMPLES: ''
RETURN:
_value:
description: The input

@ -34,3 +34,6 @@ done
# test config loading
ansible-playbook use_coll_name.yml -i ../../inventory -e 'ansible_connection=ansible.builtin.ssh' "$@"
# test filter loading ignoring duplicate file basename
ansible-playbook file_collision/play.yml "$@"

Loading…
Cancel
Save