Add ability to use *-docker-image roles in periodic jobs

Use '{{ zuul.pipeline }}' tag prefix in *-docker-image instead of
'change_{{ zuul.change }}' one when zuul.change is not provided, that is
the case with periodic jobs. This allows to build, upload and promote images
using periodic jobs e.g:

- project:
    periodic:
      - project-buildset-registry

      - project-build-image1:
          dependencies:
            - name: project-buildset-registry
      - project-build-image2:
          dependencies:
            - name: project-buildset-registry

      # pulls from buildset registry and tests both images
      - project-test:
          dependencies:
            - name: project-build-image1
            - name: project-build-image2

      # pre-pulls images from buildset registry for fast build
      - project-upload-image1:
          dependencies:
            - name: project-test
      - project-upload-image2:
          dependencies:
            - name: project-test

      - project-promote:
          dependencies:
            - name: project-upload-image1
            - name: project-upload-image2

This fuctionality will allow to keep latest images up to date for the
case when image incorporates continuously updating code from multiple
repositories.

Using true ternary for tag evaluation because ternary filter requires
all passed to it variables be defined or defaulted [0].

[0] https://github.com/ansible/ansible/issues/51276

Change-Id: I8eb7d2baa24905e7aac51fce0b2f9b1f24f037f9
Signed-off-by: Andrii Ostapenko <andrii.ostapenko@att.com>
This commit is contained in:
Andrii Ostapenko 2020-07-11 21:33:28 -05:00
parent a086fb4333
commit ef47a743b6
No known key found for this signature in database
GPG Key ID: F3E83668DBB223B3
7 changed files with 21 additions and 13 deletions

View File

@ -2,6 +2,8 @@
include_tasks: siblings.yaml include_tasks: siblings.yaml
- name: Build a docker image - name: Build a docker image
vars:
tag_prefix: "{{ ('change_' + zuul.change) if (zuul.change is defined) else zuul.pipeline }}_"
command: >- command: >-
docker build {{ zj_image.path | default('.') }} -f {{ zj_image.dockerfile | default(docker_dockerfile) }} docker build {{ zj_image.path | default('.') }} -f {{ zj_image.dockerfile | default(docker_dockerfile) }}
{% if zj_image.target | default(false) -%} {% if zj_image.target | default(false) -%}
@ -14,9 +16,7 @@
--build-arg "ZUUL_SIBLINGS={{ zj_image.siblings | join(' ') }}" --build-arg "ZUUL_SIBLINGS={{ zj_image.siblings | join(' ') }}"
{% endif -%} {% endif -%}
{% for tag in zj_image.tags | default(['latest']) -%} {% for tag in zj_image.tags | default(['latest']) -%}
{% if zuul.change | default(false) -%} --tag {{ docker_registry | ternary(docker_registry + '/', '') }}{{ zj_image.repository }}:{{ tag_prefix }}{{ tag }}
--tag {{ docker_registry | ternary(docker_registry + '/', '') }}{{ zj_image.repository }}:change_{{ zuul.change }}_{{ tag }}
{% endif -%}
--tag {{ docker_registry | ternary(docker_registry + '/', '') }}{{ zj_image.repository }}:{{ tag }} --tag {{ docker_registry | ternary(docker_registry + '/', '') }}{{ zj_image.repository }}:{{ tag }}
{% endfor -%} {% endfor -%}
{% for label in zj_image.labels | default([]) -%} {% for label in zj_image.labels | default([]) -%}

View File

@ -5,6 +5,8 @@
# they can be pulled back onto the host image cache), and also tags # they can be pulled back onto the host image cache), and also tags
# them for the buildset registry if one is present. # them for the buildset registry if one is present.
- name: Set base docker build command - name: Set base docker build command
vars:
tag_prefix: "change_{{ ('change_' + zuul.change) if (zuul.change is defined) else zuul.pipeline }}_"
set_fact: set_fact:
docker_buildx_command: >- docker_buildx_command: >-
docker buildx build {{ zj_image.path | default('.') }} -f {{ zj_image.dockerfile | default(docker_dockerfile) }} docker buildx build {{ zj_image.path | default('.') }} -f {{ zj_image.dockerfile | default(docker_dockerfile) }}
@ -18,11 +20,9 @@
--build-arg "ZUUL_SIBLINGS={{ zj_image.siblings | join(' ') }}" --build-arg "ZUUL_SIBLINGS={{ zj_image.siblings | join(' ') }}"
{% endif -%} {% endif -%}
{% for tag in zj_image.tags | default(['latest']) -%} {% for tag in zj_image.tags | default(['latest']) -%}
{% if zuul.change | default(false) -%} --tag {{ temp_registry.host }}:{{ temp_registry.port }}/{{ zj_image.repository }}:{{ tag_prefix }}{{ tag }}
--tag {{ temp_registry.host }}:{{ temp_registry.port }}/{{ zj_image.repository }}:change_{{ zuul.change }}_{{ tag }}
{% if buildset_registry | default(false) -%} {% if buildset_registry | default(false) -%}
--tag {{ buildset_registry_alias }}:{{ buildset_registry.port }}/{{ zj_image.repository }}:change_{{ zuul.change }}_{{ tag }} --tag {{ buildset_registry_alias }}:{{ buildset_registry.port }}/{{ zj_image.repository }}:{{ tag_prefix }}{{ tag }}
{% endif -%}
{% endif -%} {% endif -%}
--tag {{ temp_registry.host }}:{{ temp_registry.port }}/{{ zj_image.repository }}:{{ tag }} --tag {{ temp_registry.host }}:{{ temp_registry.port }}/{{ zj_image.repository }}:{{ tag }}
{% if buildset_registry | default(false) -%} {% if buildset_registry | default(false) -%}

View File

@ -9,7 +9,7 @@
loop_control: loop_control:
loop_var: zj_docker_tag loop_var: zj_docker_tag
when: when:
- zj_docker_tag.name.startswith('change_') - zj_docker_tag.name.startswith('change_') or zj_docker_tag.name.startswith(zuul.pipeline))
# Was updated > 24 hours ago: # Was updated > 24 hours ago:
- "{{ ((ansible_date_time.iso8601 | regex_replace('^(....-..-..)T(..:..:..).*Z', '\\1 \\2') | to_datetime) - (zj_docker_tag.last_updated | regex_replace('^(....-..-..)T(..:..:..).*Z', '\\1 \\2') | to_datetime)).seconds > 86400 }}" - "{{ ((ansible_date_time.iso8601 | regex_replace('^(....-..-..)T(..:..:..).*Z', '\\1 \\2') | to_datetime) - (zj_docker_tag.last_updated | regex_replace('^(....-..-..)T(..:..:..).*Z', '\\1 \\2') | to_datetime)).seconds > 86400 }}"
uri: uri:

View File

@ -1,7 +1,10 @@
- name: Set promote_tag_prefix
set_fact:
promote_tag_prefix: "{{ ('change_' + zuul.change) if (zuul.change is defined) else zuul.pipeline }}"
- name: Get manifest - name: Get manifest
no_log: true no_log: true
uri: uri:
url: "https://registry.hub.docker.com/v2/{{ zj_image.repository }}/manifests/change_{{ zuul.change }}_{{ zj_image_tag }}" url: "https://registry.hub.docker.com/v2/{{ zj_image.repository }}/manifests/{{ promote_tag_prefix }}_{{ zj_image_tag }}"
status_code: 200 status_code: 200
headers: headers:
Accept: "application/vnd.docker.distribution.manifest.list.v2+json, application/vnd.docker.distribution.manifest.v2+json" Accept: "application/vnd.docker.distribution.manifest.list.v2+json, application/vnd.docker.distribution.manifest.v2+json"
@ -21,7 +24,7 @@
- name: Delete the current change tag - name: Delete the current change tag
no_log: true no_log: true
uri: uri:
url: "https://hub.docker.com/v2/repositories/{{ zj_image.repository }}/tags/change_{{ zuul.change }}_{{ zj_image_tag }}/" url: "https://hub.docker.com/v2/repositories/{{ zj_image.repository }}/tags/{{ promote_tag_prefix }}_{{ zj_image_tag }}/"
method: DELETE method: DELETE
status_code: [200, 204] status_code: [200, 204]
headers: headers:

View File

@ -2,6 +2,8 @@
include_tasks: siblings.yaml include_tasks: siblings.yaml
- name: Upload tag to dockerhub - name: Upload tag to dockerhub
vars:
promote_tag_prefix: "{{ ('change_' + zuul.change) if (zuul.change is defined) else zuul.pipeline }}_"
# docker buildx doesn't have a separate push command, only the # docker buildx doesn't have a separate push command, only the
# ability to push at the end of a build. We run build here with # ability to push at the end of a build. We run build here with
# all the same arguments as in the buildx build tasks, so they # all the same arguments as in the buildx build tasks, so they
@ -18,7 +20,7 @@
--build-arg "ZUUL_SIBLINGS={{ zj_image.siblings | join(' ') }}" --build-arg "ZUUL_SIBLINGS={{ zj_image.siblings | join(' ') }}"
{% endif -%} {% endif -%}
{% for tag in zj_image.tags | default(['latest']) -%} {% for tag in zj_image.tags | default(['latest']) -%}
--tag {{ docker_registry | ternary(docker_registry + '/', '') }}{{ zj_image.repository }}:{{ upload_docker_image_promote | ternary('change_' + zuul.get('change', '') + '_', '') }}{{ tag }} --tag {{ docker_registry | ternary(docker_registry + '/', '') }}{{ zj_image.repository }}:{{ upload_docker_image_promote | ternary(promote_tag_prefix, '') }}{{ tag }}
{% endfor -%} {% endfor -%}
{% for label in zj_image.labels | default([]) -%} {% for label in zj_image.labels | default([]) -%}
--label "{{ label }}" --label "{{ label }}"

View File

@ -1,5 +1,7 @@
- name: Upload tag to registry - name: Upload tag to registry
command: "docker push {{ docker_registry | ternary(docker_registry + '/', '' ) }}{{ zj_image.repository }}:{{ upload_docker_image_promote | ternary('change_' + zuul.get('change', '') + '_', '') }}{{ zj_image_tag }}" vars:
promote_tag_prefix: "{{ ('change_' + zuul.change) if (zuul.change is defined) else zuul.pipeline }}_"
command: "docker push {{ docker_registry | ternary(docker_registry + '/', '' ) }}{{ zj_image.repository }}:{{ upload_docker_image_promote | ternary(promote_tag_prefix, '') }}{{ zj_image_tag }}"
loop: "{{ zj_image.tags | default(['latest']) }}" loop: "{{ zj_image.tags | default(['latest']) }}"
loop_control: loop_control:
loop_var: zj_image_tag loop_var: zj_image_tag

View File

@ -20,6 +20,7 @@
- name: Set simulated zuul variables - name: Set simulated zuul variables
set_fact: set_fact:
new_zuul: new_zuul:
pipeline: "{{ old_zuul.pipeline }}"
change_url: "{{ old_zuul.change_url }}" change_url: "{{ old_zuul.change_url }}"
executor: "{{ old_zuul.executor }}" executor: "{{ old_zuul.executor }}"
newrev: c12f3fe1defe8b61d59061363c9c04fb520dae18 newrev: c12f3fe1defe8b61d59061363c9c04fb520dae18