Reputation: 53
I need use ansible to ensure some files contain a particular pattern, and only copy those to a particular directory.
I'm very new to ansible, and my current idea was to use the find module to search for the pattern, then feed the resulting list of files into the copy module as a loop. However, I have no idea how to do this, and have been over the documentation for over an hour now but couldn't an find example of what im trying to do.
- name: "Ensure file contains pattern"
find:
paths: "/path/to/file.gz"
use_regex: yes
patterns: "-rev.*.gz"
register: chosen_files
Now how to feed the chosen_files list to the copy module?
Edit:
I have tried the approach below but unfortunately it wouldn't work with how things are currently set up, due to the fact that the image names were constructed using a variable, so it would only grab the relevant image, while the approach using find find all images in my repo with that pattern.
archived_image_name: "{{ new_image.registry }}_{{ new_image.image | regex_replace('/', '_') }}_{{ new_image.version }}_image.tar"
I have created a variable that compares this regex pattern vs the pre-existing pattern, so only if it contains "-rev" it will proceed with the next steps.
archived_image_prod_name: "{{ archived_image_name | regex_search('.*-rev\\d.*')}}"
Now I have another problem, which is that my database images are not expected have this pattern in their version tags, and I need to create an exception for them somehow.Task fails when it tries to check if there is enough space in the filesystem for the image.
- name: "Get {{ archived_image_prod_name }}.gz Size"
stat:
path: "{{ tower_path }}/images/{{ archived_image_prod_name }}.gz"
register: image_archive
delegate_to: 127.0.0.1
- name: "Ensure There Is Enough Disk Space Filesystem"
assert:
that: available_disk_space.stdout | int > image_archive.stat.size
msg: "Not enough disk space available for {{ archived_image_prod_name }}.gz"
The playbook stops here as some images don't match the pattern are so it fails to find their file size. I'm kinda pulling blanks on how to create an exception in this task particular images.
Upvotes: 1
Views: 1512
Reputation: 6198
First, you need to run the find
with delegate_to: localhost
, and add run_once: yes
because it won't change from one remote hosts to another. Also, your pattern needs, to start with .*
.
- name: "Ensure file contains pattern"
find:
paths: "/path/to/"
use_regex: yes
patterns: ".*-rev.*.gz"
register: chosen_files
delegate_to: localhost
run_once: yes
I put a debug in so you can see what files are going to be copied, but you can drop this when you've got it working.
- name: show files
debug:
var: item.path
loop: "{{ chosen_files.files }}"
delegate_to: localhost
run_once: yes
The other answer assumes the copy is just internal to the managed hosts, and your comment says that it not the case, so we drop his remote_src
line. Also, the src
and loop
were incorrect:
- name: Copy files from local to remote
copy:
src: "{{ item.path }}"
dest: /path/
loop: "{{ chosen_files.files }}"
Upvotes: 0
Reputation: 170806
Add a second task like:
- name: Copy files
copy:
src: {{ item }}
dest: /path/
remote_src: true # this tells ansible to perform action only on remote
loop: chosen_files
Read entire: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/copy_module.html as copy module can be used in many ways across different hosts. The default behavior is to "push" files from controller towards the target machine. Still you can change its behaviour.
Upvotes: 1