--- - block: - name: prep_download | Set a few facts set_fact: download_force_cache: "{{ true if download_run_once else download_force_cache }}" - name: download_file | Starting download of file debug: msg: "{{ download.url }}" run_once: "{{ download_run_once }}" - name: download_file | Set pathname of cached file set_fact: file_path_cached: "{{ download_cache_dir }}/{{ download.dest | basename }}" tags: - facts - name: download_file | Create dest directory on node file: path: "{{ download.dest | dirname }}" owner: "{{ download.owner | default(omit) }}" mode: 0755 state: directory recurse: yes - name: download_file | Create local cache directory file: path: "{{ file_path_cached | dirname }}" state: directory recurse: yes delegate_to: localhost connection: local delegate_facts: false run_once: true become: false when: - download_force_cache tags: - localhost - name: download_file | Create cache directory on download_delegate host file: path: "{{ file_path_cached | dirname }}" state: directory recurse: yes delegate_to: "{{ download_delegate }}" delegate_facts: false run_once: true when: - download_force_cache - not download_localhost # We check a number of mirrors that may hold the file and pick a working one at random # This task will avoid logging it's parameters to not leak environment passwords in the log - name: download_file | Validate mirrors uri: url: "{{ mirror }}" method: HEAD validate_certs: "{{ download_validate_certs }}" url_username: "{{ download.username | default(omit) }}" url_password: "{{ download.password | default(omit) }}" force_basic_auth: "{{ download.force_basic_auth | default(omit) }}" delegate_to: "{{ download_delegate if download_force_cache else inventory_hostname }}" run_once: "{{ download_force_cache }}" register: uri_result become: "{{ not download_localhost }}" until: uri_result is success retries: "{{ download_retries }}" delay: "{{ retry_stagger | default(5) }}" environment: "{{ proxy_env }}" no_log: "{{ not (unsafe_show_logs|bool) }}" loop: "{{ download.mirrors | default([download.url]) }}" loop_control: loop_var: mirror ignore_errors: true # Ansible 2.9 requires we convert a generator to a list - name: download_file | Get the list of working mirrors set_fact: valid_mirror_urls: "{{ uri_result.results | selectattr('failed', 'eq', False) | map(attribute='mirror') | list }}" delegate_to: "{{ download_delegate if download_force_cache else inventory_hostname }}" # This must always be called, to check if the checksum matches. On no-match the file is re-downloaded. # This task will avoid logging it's parameters to not leak environment passwords in the log - name: download_file | Download item get_url: url: "{{ valid_mirror_urls | random }}" dest: "{{ file_path_cached if download_force_cache else download.dest }}" owner: "{{ omit if download_localhost else (download.owner | default(omit)) }}" mode: "{{ omit if download_localhost else (download.mode | default(omit)) }}" checksum: "{{ 'sha256:' + download.sha256 if download.sha256 else omit }}" validate_certs: "{{ download_validate_certs }}" url_username: "{{ download.username | default(omit) }}" url_password: "{{ download.password | default(omit) }}" force_basic_auth: "{{ download.force_basic_auth | default(omit) }}" timeout: "{{ download.timeout | default(omit) }}" delegate_to: "{{ download_delegate if download_force_cache else inventory_hostname }}" run_once: "{{ download_force_cache }}" register: get_url_result become: "{{ not download_localhost }}" until: "'OK' in get_url_result.msg or 'file already exists' in get_url_result.msg" retries: "{{ download_retries }}" delay: "{{ retry_stagger | default(5) }}" environment: "{{ proxy_env }}" no_log: "{{ not (unsafe_show_logs|bool) }}" - name: download_file | Copy file back to ansible host file cache ansible.posix.synchronize: src: "{{ file_path_cached }}" dest: "{{ file_path_cached }}" use_ssh_args: true mode: pull when: - download_force_cache - not download_localhost - download_delegate == inventory_hostname - name: download_file | Copy file from cache to nodes, if it is available ansible.posix.synchronize: src: "{{ file_path_cached }}" dest: "{{ download.dest }}" use_ssh_args: true mode: push register: get_task until: get_task is succeeded delay: "{{ retry_stagger | random + 3 }}" retries: "{{ download_retries }}" when: - download_force_cache - name: download_file | Set mode and owner file: path: "{{ download.dest }}" mode: "{{ download.mode | default(omit) }}" owner: "{{ download.owner | default(omit) }}" when: - download_force_cache - name: "download_file | Extract file archives" include_tasks: "extract_file.yml" tags: - download