Skip to content

filetree lookup plugin resolves relative paths relative to cwd #9896

Open
@btmc

Description

@btmc

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugThis issue/PR relates to a buglookuplookup pluginpluginsplugin (any type)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions