Description
Summary
When there is a file or directory, matching lookup search criteria, in files
subdir of current working directory, it is returned by the lookup.
This means playbook execution results depend on cwd. Although not described in the docs explicitely, I believe that is not an expected behaviour.
The reason seems to be in the path_dwim_relative
function of ansible dataloader. One of search options added there is mentioned as being "absolute" in the comment line, but in fact is defined this way:
# try to create absolute path for loader basedir + templates/files/vars + filename
search.append(unfrackpath(os.path.join(dirname, source), follow=False))
dirname
here being 'files'
, from filetree
invocation.
And unfrackpath
, when it does not receive a basedir
parameter, renders relative path relative to cwd.
I'm not sure whether this should be reported directly to ansible repo, because the function path_dwim_relative
, although used in several places, does not have regressions there (and reproducible use-cases).
There also exists its counterpart with multi-path search: path_dwim_relative_stack
, which resolves such paths correctly, and that one is used in find_file_in_search_path
function in lookup plugins init code, so maybe it should also be used here instead?
Issue Type
Bug Report
Component Name
community.general.filetree
Ansible Version
ansible [core 2.18.3]
python version = 3.13.2 (main, Feb 14 2025, 19:28:41) [GCC 14.2.0] (/usr/local/bin/python3.13)
jinja version = 3.1.5
libyaml = True
Community.general Version
10.4.0
Configuration
No response
OS / Environment
cat /etc/os-release
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.21.3
PRETTY_NAME="Alpine Linux v3.21"
Steps to Reproduce
cd /tmp
mkdir -p /tmp/dir1
mkdir -p /tmp/files/dir2
touch /tmp/files/dir2/file
<<\Q cat > /tmp/dir1/test.yml
- hosts: localhost
gather_facts: no
tasks:
- debug:
msg:
src: "{{ item.src }}"
root: "{{ item.root }}"
with_community.general.filetree: [ dir2 ]
Q
# file from files dir, relative to cwd, is returned
#
ansible-playbook /tmp/dir1/test.yml
TASK [debug] **********
...
root: /tmp/files/dir2
src: /tmp/files/dir2/file
cd /tmp/dir1
# no file returned
#
ansible-playbook /tmp/dir1/test.yml
skipping: [localhost]
mkdir -p /tmp/dir1/dir2
touch /tmp/dir1/dir2/file
# file relative to playbook is returned
#
ansible-playbook /tmp/dir1/test.yml
root: /tmp/dir1/dir2
src: /tmp/dir1/dir2/file
cd /tmp
# file from files dir, relative to cwd, is returned again and overshadows the one,
# that is relative to the playbook, as it goes first in path_dwim_relative search order
#
ansible-playbook /tmp/dir1/test.yml
root: /tmp/files/dir2
src: /tmp/files/dir2/file
Expected Results
Only files and directories relative to playbook (or roles) are searched, the result is stable and does not depend on cwd.
Actual Results
No response
Code of Conduct
- I agree to follow the Ansible Code of Conduct