Reputation: 105
How do i loop using "with_fileglob". I am trying to copy files matching wildcard, but with different permissions at the destination.
- hosts: myhost
gather_facts: no
tasks:
- name: Ansible copy test
copy:
src: "{{ item.origin }}"
dest: /home/user1/tmps/
owner: user1
mode: "{{item.mode}}"
with_fileglob:
- { origin: '/tmp/hello*', mode: '640'}
- { origin: '/tmp/hi*', mode: '600'}
It throws error as below:
An exception occurred during task execution. To see the full traceback, use
-vvv. The error was: AttributeError: 'dict' object has no attribute 'rfind'
Upvotes: 4
Views: 9716
Reputation: 68549
I think the cleanest way is to implement this, would be a nested loop with include_tasks
.
Where you main playbook file contains:
...
vars:
my_patterns:
- origin: "/tmp/hello*"
mode: "0640"
- origin: "/tmp/hi*"
mode: "0600"
tasks:
- include_tasks: "my_glob.yml"
with_items: "{{ my_patterns }}"
loop_control:
loop_var: my_pattern
...
and a subordinate my_glob.yml
-tasks file:
---
- name: Ansible copy test
copy:
src: "{{ item }}"
dest: /home/user1/tmps/
owner: user1
mode: "{{ my_pattern.mode }}"
with_fileglob: "{{ my_pattern.origin }}"
Alternative method
Using Jinja2 to populate a list of objects { 'path': '...', 'mode': '...' }'
based on fileglob
-lookup plugin results.
vars:
my_patterns:
- origin: '/tmp/hello*'
mode: '0640'
- origin: '/tmp/hi*'
mode: '0600'
tasks:
- copy:
src: "{{ item.paht }}"
dest: /home/user1/tmps/
owner: user1
mode: "{{ item.mode }}"
with_items: "[{% for match in my_patterns %}{% for file in lookup('fileglob', match.origin, wantlist=True) %}{ 'path':'{{ file }}','mode':'{{ match.mode }}'}{% if not loop.last %},{% endif %}{% endfor %}{% if not loop.last %},{% endif %}{% endfor %}]"
The above works if patterns are matched, you'd need to add checks if the results are not empty.
Upvotes: 5
Reputation: 6685
according to the documentation, you cant pass to the fileglob a dictionary variable, adding the desired file permissions after copy as you have attempted (i mean the declaration { origin: '/tmp/hello*', mode: '640'}
).
simple module call that will work for you:
- hosts: localhost
gather_facts: no
tasks:
- name: Ansible copy test
copy:
src: "{{ item }}"
dest: /SAMBA_ROOT/TEMP/
owner: root
with_fileglob:
- '/tmp/hello*'
- '/tmp/hi*'
if you want to have each of the file group have different file permissions, i suggest you use 2 different calls where the mode is "hardcoded", for example:
- hosts: localhost
gather_facts: no
tasks:
- name: copy hello files
copy:
src: "{{ item }}"
dest: /SAMBA_ROOT/TEMP/
owner: root
mode: 0640
with_fileglob:
- '/tmp/hello*'
- name: copy hi files
copy:
src: "{{ item }}"
dest: /SAMBA_ROOT/TEMP/
owner: root
mode: 0600
with_fileglob:
- '/tmp/hi*'
Upvotes: 0