Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extract filename from file result in ansible

I'm trying to use the result of Ansible find command, which return list of files it find on a specific folder, the problem is, when I iterate over the result, I do not have the file names, I only have their full paths (including the name), is there an easy way to use the result item below to provide the file_name in the second command as shown below?

- name: get files
  find:
    paths: /home/me
    file_type: "file"
  register: find_result

- name: Execute docker secret create
  shell: docker secret create <file_name> {{ item.path }}
  run_once: true
  with_items: "{{ find_result.files }}"
like image 830
toto Avatar asked Aug 08 '17 09:08

toto


2 Answers

basename filter?

{{ item.path | basename }}

There are also dirname, realpath, relpath filters.

like image 178
Konstantin Suvorov Avatar answered Nov 11 '22 17:11

Konstantin Suvorov


This question and accepted answer are great for the time they were written. However, I want to leave a note about the current preferred way of doing it.

https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html#migrating-to-loop

With the release of Ansible 2.5, the recommended way to perform loops is the use the new loop keyword instead of with_X style loops.

I've seen seen this common pattern evolve for such file-loop combinations.

- name: "Find python files in folder scripts"
  find:
    paths: "{{ playbook_dir }}/scripts"
    patterns: "*.py"
    file_type: "file"
  register: python_files

- name: "Execute those python scripts from the script folder"
  shell: "python {{ item.path | basename }}"
  args:
    chdir: "{{ playbook_dir }}/scripts"
  loop: "{{ python_files.files }}"
  loop_control:
    label: "{{ item.path | basename }}"

This loops over a certain type of files in a directory (python files) and takes a certain action with their filename (executes them), and using their filename is justified because chdir puts you in the directory where those files are.

It's important to use that same filename in loop_control because otherwise it prints item, which isn't just the absolute path, but a dozen other file properties which is completely unreadable.

This works, but it also ignores the motivations for the loop changes to Ansible in the first place. This also works, replacing 2 tasks with 1:

- name: "Execute python scripts from the script folder"
  shell: "python {{ item | basename }}"
  args:
    chdir: "{{ playbook_dir }}/scripts"
  with_fileglob: "{{ playbook_dir }}/scripts/*.py"
  loop_control:
    label: "{{ item | basename }}"

In this loop, item is the absolute path. You may prefer to print that, in which case lose the loop_control completely.

like image 3
AlanSE Avatar answered Nov 11 '22 16:11

AlanSE