diff options
author | Mark Goddard <mark@stackhpc.com> | 2020-05-12 12:00:02 +0100 |
---|---|---|
committer | Matt Clay <matt@mystile.com> | 2020-05-12 09:58:45 -0700 |
commit | 5a0d35646dc0854229c742d70a2ce56f8b2d91e4 (patch) | |
tree | 7489abc95f1b6d6ecafc4c83bd6484145ec923d7 | |
parent | 457a1115e8b7f5f7e5523a6cfc4c3a341ce1705f (diff) | |
download | ansible-5a0d35646dc0854229c742d70a2ce56f8b2d91e4.tar.gz |
Fix fileglob plugin with non-existent subdirectory
Since Ansible 2.9.8, if the fileglob plugin is passed a path containing
a subdirectory of a non-existent directory, it will fail. For example:
lookup('fileglob', '/'): ok
lookup('fileglob', '/foo'): (non-existent): ok
lookup('fileglob', '/foo/bar'): (non-existent): FAIL
The exact error depends on Python 2 or 3, but here is the error on
Python 2:
AttributeError: 'NoneType' object has no attribute 'endswith'
And on Python 3:
TypeError: expected str, bytes or os.PathLike object, not NoneType
This change fixes the issue by skipping paths that are falsey before
passing them to os.path.join().
Fixes: #69450
4 files changed, 21 insertions, 4 deletions
diff --git a/changelogs/fragments/69451-fix-fileglob-nonexistent-subdirs.yaml b/changelogs/fragments/69451-fix-fileglob-nonexistent-subdirs.yaml new file mode 100644 index 0000000000..7d12124664 --- /dev/null +++ b/changelogs/fragments/69451-fix-fileglob-nonexistent-subdirs.yaml @@ -0,0 +1,4 @@ +bugfixes: +- Fix an issue with the ``fileglob`` plugin where passing a subdirectory of + non-existent directory would cause it to fail - + https://github.com/ansible/ansible/issues/69450 diff --git a/lib/ansible/plugins/lookup/fileglob.py b/lib/ansible/plugins/lookup/fileglob.py index 2460ba15dd..503973ce46 100644 --- a/lib/ansible/plugins/lookup/fileglob.py +++ b/lib/ansible/plugins/lookup/fileglob.py @@ -72,8 +72,9 @@ class LookupModule(LookupBase): 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 + if dwimmed_path: + 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/non_existent/play.yml b/test/integration/targets/fileglob/non_existent/play.yml new file mode 100644 index 0000000000..e92dff5acc --- /dev/null +++ b/test/integration/targets/fileglob/non_existent/play.yml @@ -0,0 +1,6 @@ +- hosts: localhost + gather_facts: false + tasks: + - name: fileglob should be empty + assert: + that: q("fileglob", seed) | length == 0 diff --git a/test/integration/targets/fileglob/runme.sh b/test/integration/targets/fileglob/runme.sh index 1ca7e1b7ad..1e0297c79d 100755 --- a/test/integration/targets/fileglob/runme.sh +++ b/test/integration/targets/fileglob/runme.sh @@ -7,3 +7,9 @@ for seed in play_adj play_adj_subdir somepath/play_adj_subsubdir in_role otherpa do ansible-playbook find_levels/play.yml -e "seed='${seed}'" "$@" done + +# non-existent paths +for seed in foo foo/bar foo/bar/baz +do + ansible-playbook non_existent/play.yml -e "seed='${seed}'" "$@" +done |