Update ensure-quay-repo to run opportunistically

This updates the new ensure-quay-repo to run opportunistically if the
registry_type image flag is set to quay and the registry credentials
matching the container image has an api token defined. This will allow
us to include this role in base jobs and it will do what we need it to
do without impacting docker based images or quay managed images that
don't need automatic creation.

Change-Id: Ia419578bf0a27293757c5f723873e9930ee2c489
This commit is contained in:
Clark Boylan 2023-04-25 15:21:57 -07:00
parent 0e6df8d38f
commit 58f408cfac
2 changed files with 65 additions and 47 deletions

View File

@ -19,6 +19,19 @@ When invoking this role you should set no_log: true on the
``container_registry_credentials`` variable used by the other container ``container_registry_credentials`` variable used by the other container
roles. Specify an ``api_token`` which is issued from an application roles. Specify an ``api_token`` which is issued from an application
assigned to an organisation. See `<https://docs.quay.io/api/>`__ assigned to an organisation. See `<https://docs.quay.io/api/>`__
This application API token needs create permissions. If the registry
name is quay.io we know that the registry type is ``quay``. If you are
running a private Quay installation you can manually set
``type`` to ``quay`` to force this behavior.
This role will only take action on image repos that map to
container registries for which both an ``api_token`` is set and
``type`` can be determined to be ``quay``.
You may also set ``api_url`` on the registry credentials if the
API is not hosted at the root of the registry name. Most installations
should be able to ignore this and use the default of
``https://{{ $name }}``.
Example: Example:
@ -26,7 +39,9 @@ When invoking this role you should set no_log: true on the
container_registry_credentials: container_registry_credentials:
quay.io: quay.io:
type: 'quay'
api_token: 'abcd1234' api_token: 'abcd1234'
api_url: 'https://quay.io'
.. zuul:rolevar:: container_images .. zuul:rolevar:: container_images
:type: list :type: list
@ -36,10 +51,8 @@ When invoking this role you should set no_log: true on the
is in the same format as the ``container_images`` variable used by other is in the same format as the ``container_images`` variable used by other
container roles. Specify a ``registry`` (this should match up with your container roles. Specify a ``registry`` (this should match up with your
credentials to locate the api token), ``namespace``, ``repo_shortname``, credentials to locate the api token), ``namespace``, ``repo_shortname``,
``repo_description``, ``visibility``, and ``api_url`` attributes. ``repo_description``, and ``visibility`` attributes. By default
visibility will be ``public``.
By default visibility will be ``public`` and ``api_url`` will be
``https://{{ registry }}``.
Example: Example:

View File

@ -1,49 +1,54 @@
- name: Set quay_root_url - name: Only run when necessary items are present
set_fact: block:
quay_root_url: "https://{{ zj_image.registry }}" - name: Set quay_root_url
when: zj_image.api_url is not defined set_fact:
quay_root_url: "https://{{ zj_image.registry }}"
when: container_registry_credentials[zj_image.registry].api_url is not defined
- name: Alias api_url - name: Alias api_url
set_fact: set_fact:
quay_root_url: "{{ zj_image.api_url }}" quay_root_url: "{{ container_registry_credentials[zj_image.registry].api_url }}"
when: zj_image.api_url is defined when: container_registry_credentials[zj_image.registry].api_url is defined
- name: Set quay_repo_visibility - name: Set quay_repo_visibility
set_fact: set_fact:
quay_repo_visibility: "public" quay_repo_visibility: "public"
when: zj_image.visibility is not defined when: zj_image.visibility is not defined
- name: Alias visibility - name: Alias visibility
set_fact: set_fact:
quay_repo_visibility: "{{ zj_image.visibility }}" quay_repo_visibility: "{{ zj_image.visibility }}"
when: zj_image.visibility is defined when: zj_image.visibility is defined
- name: Create the repo in quay - name: Create the repo in quay
no_log: true no_log: true
uri: uri:
url: "{{ quay_root_url }}/api/v1/repository" url: "{{ quay_root_url }}/api/v1/repository"
method: POST method: POST
body_format: json body_format: json
body: body:
namespace: "{{ zj_image.namespace }}" namespace: "{{ zj_image.namespace }}"
repository: "{{ zj_image.repo_shortname}}" repository: "{{ zj_image.repo_shortname}}"
description: "{{ zj_image.repo_description }}" description: "{{ zj_image.repo_description }}"
visibility: "{{ quay_repo_visibility }}" visibility: "{{ quay_repo_visibility }}"
headers: headers:
Content-Type: application/json Content-Type: application/json
Authorization: "Bearer {{ container_registry_credentials[zj_image.registry].api_token }}" Authorization: "Bearer {{ container_registry_credentials[zj_image.registry].api_token }}"
status_code: status_code:
- 201 - 201
# 400 is returned when the repo already exists. # 400 is returned when the repo already exists.
# We double check this below. # We double check this below.
- 400 - 400
register: quay_repo_create register: quay_repo_create
delay: 5 delay: 5
retries: 3 retries: 3
- name: Fail if repo doesn't exist and we got a 400 status code - name: Fail if repo doesn't exist and we got a 400 status code
when:
- quay_repo_create.status == 400
- "'error_message' not in quay_repo_create.json or ('error_message' in quay_repo_create.json and quay_repo_create.json.error_message != 'Repository already exists')"
fail:
msg: "Could not create {{ quay_root_url }}/{{ zj_image.namespace }}/{{ zj_image.repo_shortname }}"
when: when:
- quay_repo_create.status == 400 - zj_image.registry == 'quay.io' or (container_registry_credentials[zj_image.registry].type is defined and container_registry_credentials[zj_image.registry].type == 'quay')
- "'error_message' not in quay_repo_create.json or ('error_message' in quay_repo_create.json and quay_repo_create.json.error_message != 'Repository already exists')" - container_registry_credentials[zj_image.registry].api_token is defined
fail:
msg: "Could not create {{ quay_root_url }}/{{ zj_image.namespace }}/{{ zj_image.repo_shortname }}"