NicolasW
NicolasW

Reputation: 1599

ansible loop over file list and check file exists, if not download it

Not sure how to have this logic implemented, I know how to do it a single file :

- name: Obtain information about a file
  win_stat:
    path: "C:\myfile.txt"
  register: fileinfo

- [...]
  when: fileinfo.exists == False

how should I go with a list of files?

Upvotes: 2

Views: 9356

Answers (1)

gaige
gaige

Reputation: 17481

If you just want to reduce the steps for doing this, you should be able to do your download step (not shown in your example) with ignore_errors: yes on your download commands. If you use a combination of ignore_errors: yes and register, you can even tell whether the command failed.

If you're looking to make it a bit more efficient, you can do the stat in a single task and then examine the results of that. When you execute a task with a list, you get a hash of answers.

Assuming you have a list of file names/paths in ssh_key_config, you use the stat and then you can loop over the items (which conveniently have the file name in them).

- name: Check to see if file exists
  stat:
    path: "{{ remote_dir }}/{{ item }}"
  register: stat_results
  with_items: "{{ target_files }}"
  ignore_errors: True

- name: perform operation
  fetch:
    src: "{{ remote_dir }}/{{ item.item }}"
    dest: "{{ your_dest_dir }}"
    flat: yes
  with_items: "{{ stat_results.results }}"
  when: item.stat.exists == False

In this case, the assumptions are that remote_dir contains the remote directory on the host, target_files contains the actual file names, and your_dest_dir contains the location you want the files placed locally.

I don't do much with Windows and Ansible, but win_stat is documented pretty much the same as stat, so you can likely just replace that.

Also note that this expects the list of files, not a glob. If you use a glob (for example, you want to retrieve all files with a certain extension from the remote), then you would not use the with_items clause, and you'd need to use the item.stat.filename and/or item.stat.path to retrieve the file remotely (since the item.item would contain the request item, which would be the glob.

Upvotes: 8

Related Questions