diff --git a/changelogs/fragments/fileglob_fixes.yml b/changelogs/fragments/fileglob_fixes.yml new file mode 100644 index 00000000000..c0a12b07348 --- /dev/null +++ b/changelogs/fragments/fileglob_fixes.yml @@ -0,0 +1,2 @@ +bugfixes: + - deal with cases in which just a file is pased and not a path with directories, now fileglob correctly searches in 'files/' subdirs. diff --git a/lib/ansible/plugins/lookup/fileglob.py b/lib/ansible/plugins/lookup/fileglob.py index 91442dda5e1..2460ba15ddd 100644 --- a/lib/ansible/plugins/lookup/fileglob.py +++ b/lib/ansible/plugins/lookup/fileglob.py @@ -58,8 +58,22 @@ class LookupModule(LookupBase): ret = [] for term in terms: term_file = os.path.basename(term) - dwimmed_path = self.find_file_in_search_path(variables, 'files', os.path.dirname(term)) - if dwimmed_path: + found_paths = [] + if term_file != term: + found_paths.append(self.find_file_in_search_path(variables, 'files', os.path.dirname(term))) + else: + # no dir, just file, so use paths and 'files' paths instead + if 'ansible_search_path' in variables: + paths = variables['ansible_search_path'] + else: + paths = [self.get_basedir(variables)] + for p in paths: + found_paths.append(os.path.join(p, 'files')) + found_paths.append(p) + + for dwimmed_path in found_paths: globbed = glob.glob(to_bytes(os.path.join(dwimmed_path, term_file), errors='surrogate_or_strict')) ret.extend(to_text(g, errors='surrogate_or_strict') for g in globbed if os.path.isfile(g)) + if ret: + break return ret diff --git a/test/integration/targets/fileglob/aliases b/test/integration/targets/fileglob/aliases new file mode 100644 index 00000000000..a6dafcf8cd8 --- /dev/null +++ b/test/integration/targets/fileglob/aliases @@ -0,0 +1 @@ +shippable/posix/group1 diff --git a/test/integration/targets/fileglob/find_levels/files/play_adj_subdir.txt b/test/integration/targets/fileglob/find_levels/files/play_adj_subdir.txt new file mode 100644 index 00000000000..50255880719 --- /dev/null +++ b/test/integration/targets/fileglob/find_levels/files/play_adj_subdir.txt @@ -0,0 +1 @@ +in files subdir adjacent to play diff --git a/test/integration/targets/fileglob/find_levels/files/somepath/play_adj_subsubdir.txt b/test/integration/targets/fileglob/find_levels/files/somepath/play_adj_subsubdir.txt new file mode 100644 index 00000000000..96c7a549362 --- /dev/null +++ b/test/integration/targets/fileglob/find_levels/files/somepath/play_adj_subsubdir.txt @@ -0,0 +1 @@ +in play adjacent subdir of files/ diff --git a/test/integration/targets/fileglob/find_levels/play.yml b/test/integration/targets/fileglob/find_levels/play.yml new file mode 100644 index 00000000000..4bdee05de38 --- /dev/null +++ b/test/integration/targets/fileglob/find_levels/play.yml @@ -0,0 +1,13 @@ +- hosts: localhost + gather_facts: false + vars: + expected: + play_adj: ajectent to play + play_adj_subdir: in files subdir adjacent to play + somepath/play_adj_subsubdir: in play adjacent subdir of files/ + in_role: file in role + otherpath/in_role_subdir: file in role subdir + tasks: + - name: Import role lookup + import_role: + name: get_file diff --git a/test/integration/targets/fileglob/find_levels/play_adj.txt b/test/integration/targets/fileglob/find_levels/play_adj.txt new file mode 100644 index 00000000000..14f0cf502bc --- /dev/null +++ b/test/integration/targets/fileglob/find_levels/play_adj.txt @@ -0,0 +1 @@ +ajectent to play diff --git a/test/integration/targets/fileglob/find_levels/roles/get_file/files/in_role.txt b/test/integration/targets/fileglob/find_levels/roles/get_file/files/in_role.txt new file mode 100644 index 00000000000..fdfc9476c8a --- /dev/null +++ b/test/integration/targets/fileglob/find_levels/roles/get_file/files/in_role.txt @@ -0,0 +1 @@ +file in role diff --git a/test/integration/targets/fileglob/find_levels/roles/get_file/files/otherpath/in_role_subdir.txt b/test/integration/targets/fileglob/find_levels/roles/get_file/files/otherpath/in_role_subdir.txt new file mode 100644 index 00000000000..40e75a40db5 --- /dev/null +++ b/test/integration/targets/fileglob/find_levels/roles/get_file/files/otherpath/in_role_subdir.txt @@ -0,0 +1 @@ +file in role subdir diff --git a/test/integration/targets/fileglob/find_levels/roles/get_file/tasks/main.yml b/test/integration/targets/fileglob/find_levels/roles/get_file/tasks/main.yml new file mode 100644 index 00000000000..2fc21df70df --- /dev/null +++ b/test/integration/targets/fileglob/find_levels/roles/get_file/tasks/main.yml @@ -0,0 +1,10 @@ +- name: show file contents + debug: + msg: '{{ q("fileglob", seed + ".*") }}' + register: found + +- name: did we get right one? + assert: + that: + - found['msg'][0].endswith(seed + '.txt') + - q('file', found['msg'][0])[0] == expected[seed] diff --git a/test/integration/targets/fileglob/runme.sh b/test/integration/targets/fileglob/runme.sh new file mode 100755 index 00000000000..1ca7e1b7adf --- /dev/null +++ b/test/integration/targets/fileglob/runme.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -eux + +# fun multilevel finds +for seed in play_adj play_adj_subdir somepath/play_adj_subsubdir in_role otherpath/in_role_subdir +do + ansible-playbook find_levels/play.yml -e "seed='${seed}'" "$@" +done