tripleo-quickstart/roles/fetch-images/tasks/fetch.yml

200 lines
6.2 KiB
YAML

- name: image name
debug:
msg: "checking for image {{ image.name }}"
# Set some convenience variables here to avoid boilerplate code
# elsewhere in this file. These are all set unconditionally to avoid
# any cruft leftover from a previous call to this file.
- name: set local variables
set_fact:
_force_cached_image: >-
{{ force_cached_images|default(false)|bool
or image.force_cached|default(false)|bool }}
_latest: >-
{{ image_cache_dir }}/latest-{{ image.name }}.{{ image.type }}
cacheable: true
# This looks for the latest image symlink that may have been created
# by a previous run of this tasklist.
- name: Check if we have a latest image
command: >
test -f {{ _latest }}
args:
chdir: "{{ image_cache_dir }}"
ignore_errors: true
register: latest_exists
changed_when: false
# If we want to use the most recent image in the local cache
# (`_force_cached_image` is `true`) *and* such an image exists, point
# `image_cache_path` at `latest-{{image.name}}.qcow2`.
- name: Set path to cached image [local]
set_fact:
image_cache_path: "{{ _latest }}"
cacheable: true
when: latest_exists is success and _force_cached_image
# The md5sum for base OS images are not hosted, they are defined in a configuration file.
# Handle base os images slightly differently
- when: image.md5sum is defined
block:
# Get the expected checksum from settings vs. pulling the md5sum.
- name: Get image expected checksum for base OS images
set_fact:
md5_expected: "{{ image.md5sum.split()[0] }}"
cacheable: true
- name: Set path to cached image
set_fact:
image_cache_path: "{{ image_cache_dir }}/{{ md5_expected }}.{{ image.type }}"
cacheable: true
# See if a matching image exists locally.
- name: Check for base OS image in cache
command: >
test -f {{ image_cache_path }}
args:
chdir: "{{ image_cache_dir }}"
ignore_errors: true
register: base_image_exists
changed_when: false
# Otherwise, check if there's a new image available.
- when:
- image.md5sum is not defined
- not _force_cached_image or latest_exists is failed
block:
# Get the expected checksum for the remote image.
- name: Get image expected checksum
command: >
curl -sfL {{ image.url }}.md5
register: md5_expected
- name: sanitize the md5sum
set_fact:
md5_expected: "{{ md5_expected.stdout.split()[0] }}"
cacheable: true
- name: Set path to cached image [upstream]
set_fact:
image_cache_path: "{{ image_cache_dir }}/{{ md5_expected }}.{{ image.type }}"
cacheable: true
# See if a matching image exists locally.
- name: Check for image in cache
command: >
test -f {{ image_cache_path }}
args:
chdir: "{{ image_cache_dir }}"
ignore_errors: true
register: image_exists
changed_when: false
# Looks like we're going to have to download the image after all.
# Note.. image_exists and base_image_exists are required variables because
# even unused variables will overwrite each other.
- when: image_exists is defined and (image_exists is failed or base_image_exists is failed)
block:
# This task will download the image. We're using `curl` here
# rather than `wget` because while `wget` has built-in retry
# capabilities, it is unable to handle `file://` URLs. We instead
# use an ansible `until` loop, combined with curl's `-C-` option
# to continue interrupted downloads.
- name: Get image
command: >
curl -sfL -C- -o _{{ image.name }}.{{ image.type}} {{ image.url }}
args:
chdir: "{{ image_cache_dir }}"
register: curl_result
until: curl_result.rc not in [18, 56]
retries: 20
delay: 5
# Compute the md5 checksum of the image we just downloaded
- name: Get actual md5 checksum of image
command: >
md5sum -b _{{ image.name }}.{{ image.type}}
args:
chdir: "{{ image_cache_dir }}"
register: md5_actual
- name: sanitize the md5sum for the downloaded image
set_fact:
md5_actual: "{{ md5_actual.stdout.split()[0] }}"
cacheable: true
# Verify that what we have is what we wanted.
- name: Verify image checksum
fail:
msg: image checksum does not match
when: >
image_exists is failed and
(md5_expected != md5_actual)
- name: Cache image by checksum
command: >
mv _{{ image.name }}.{{ image.type}} {{ image_cache_path }}
args:
chdir: "{{ image_cache_dir }}"
- name: Update "latest" symlink
file:
path: "{{ _latest }}"
state: link
src: "{{ image_cache_path }}"
# This is a workaround for ansible issue [15625][].
#
# [15625]: https://github.com/ansible/ansible/issues/15625
rescue:
- name: Note that there was a failure.
set_fact:
image_fetch_failed: true
cacheable: true
# Ensure that even if there are failures we still clean up our
# temporary image file.
always:
- name: Clean up temporary image file
file:
path: "{{ image_cache_dir }}/_{{ image.name }}.{{ image.type }}"
state: absent
- name: Propagate failure
fail:
when: image_fetch_failed|default(false)
# Use `image_cache_path`, which was set by one of the above tasks, and
# copy it to `undercloud.qcow2 in our `{{ image_fetch_dir }}`.
- name: Get qcow2 image from cache
command: >
cp {{ image_cache_path }} {{ image_fetch_dir }}/{{ image.name }}.{{ image.type }}
when: image.type == "qcow2" and image.md5sum is not defined
# Same as the above just copy the base os image to the fetch_dir as undercloud
- name: Get base OS qcow2 image from cache
command: >
cp {{ image_cache_path }} {{ image_fetch_dir }}/undercloud.{{ image.type }}
when: image.type == "qcow2" and image.md5sum is defined
- name: Get tar images from cache
unarchive:
src: "{{ image_cache_path }}"
copy: no
dest: "{{ image_fetch_dir }}"
list_files: yes
when: image.type == "tar"
- name: Clean image cache directory
shell: >-
find {{ image_cache_dir }} -type f
{% if not image_cache_dir_cleanup|bool %}
-mtime +{{ image_cache_expire_days|int - 1 }} {% endif %}|
xargs --no-run-if-empty -t rm -rf