From 58f408cfac9749cde749747225fac8cd2a04b1c5 Mon Sep 17 00:00:00 2001 From: Clark Boylan Date: Tue, 25 Apr 2023 15:21:57 -0700 Subject: [PATCH] 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 --- roles/ensure-quay-repo/README.rst | 21 ++++-- roles/ensure-quay-repo/tasks/create.yaml | 91 +++++++++++++----------- 2 files changed, 65 insertions(+), 47 deletions(-) diff --git a/roles/ensure-quay-repo/README.rst b/roles/ensure-quay-repo/README.rst index 5db7ea907..d8c071019 100644 --- a/roles/ensure-quay-repo/README.rst +++ b/roles/ensure-quay-repo/README.rst @@ -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 roles. Specify an ``api_token`` which is issued from an application assigned to an organisation. See ``__ + 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: @@ -26,7 +39,9 @@ When invoking this role you should set no_log: true on the container_registry_credentials: quay.io: + type: 'quay' api_token: 'abcd1234' + api_url: 'https://quay.io' .. zuul:rolevar:: container_images :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 container roles. Specify a ``registry`` (this should match up with your credentials to locate the api token), ``namespace``, ``repo_shortname``, - ``repo_description``, ``visibility``, and ``api_url`` attributes. - - By default visibility will be ``public`` and ``api_url`` will be - ``https://{{ registry }}``. + ``repo_description``, and ``visibility`` attributes. By default + visibility will be ``public``. Example: diff --git a/roles/ensure-quay-repo/tasks/create.yaml b/roles/ensure-quay-repo/tasks/create.yaml index 00f475860..2c0e82bf4 100644 --- a/roles/ensure-quay-repo/tasks/create.yaml +++ b/roles/ensure-quay-repo/tasks/create.yaml @@ -1,49 +1,54 @@ -- name: Set quay_root_url - set_fact: - quay_root_url: "https://{{ zj_image.registry }}" - when: zj_image.api_url is not defined +- name: Only run when necessary items are present + block: + - name: Set quay_root_url + 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 - set_fact: - quay_root_url: "{{ zj_image.api_url }}" - when: zj_image.api_url is defined + - name: Alias api_url + set_fact: + quay_root_url: "{{ container_registry_credentials[zj_image.registry].api_url }}" + when: container_registry_credentials[zj_image.registry].api_url is defined -- name: Set quay_repo_visibility - set_fact: - quay_repo_visibility: "public" - when: zj_image.visibility is not defined + - name: Set quay_repo_visibility + set_fact: + quay_repo_visibility: "public" + when: zj_image.visibility is not defined -- name: Alias visibility - set_fact: - quay_repo_visibility: "{{ zj_image.visibility }}" - when: zj_image.visibility is defined + - name: Alias visibility + set_fact: + quay_repo_visibility: "{{ zj_image.visibility }}" + when: zj_image.visibility is defined -- name: Create the repo in quay - no_log: true - uri: - url: "{{ quay_root_url }}/api/v1/repository" - method: POST - body_format: json - body: - namespace: "{{ zj_image.namespace }}" - repository: "{{ zj_image.repo_shortname}}" - description: "{{ zj_image.repo_description }}" - visibility: "{{ quay_repo_visibility }}" - headers: - Content-Type: application/json - Authorization: "Bearer {{ container_registry_credentials[zj_image.registry].api_token }}" - status_code: - - 201 - # 400 is returned when the repo already exists. - # We double check this below. - - 400 - register: quay_repo_create - delay: 5 - retries: 3 + - name: Create the repo in quay + no_log: true + uri: + url: "{{ quay_root_url }}/api/v1/repository" + method: POST + body_format: json + body: + namespace: "{{ zj_image.namespace }}" + repository: "{{ zj_image.repo_shortname}}" + description: "{{ zj_image.repo_description }}" + visibility: "{{ quay_repo_visibility }}" + headers: + Content-Type: application/json + Authorization: "Bearer {{ container_registry_credentials[zj_image.registry].api_token }}" + status_code: + - 201 + # 400 is returned when the repo already exists. + # We double check this below. + - 400 + register: quay_repo_create + delay: 5 + 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: - - 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 }}" + - zj_image.registry == 'quay.io' or (container_registry_credentials[zj_image.registry].type is defined and container_registry_credentials[zj_image.registry].type == 'quay') + - container_registry_credentials[zj_image.registry].api_token is defined