Add build-container-image role

Testing is added in a followup change.

Change-Id: Ia1ebf0075e9f6976310dff618cb06da928f55a7b
This commit is contained in:
James E. Blair 2019-11-20 09:30:15 -08:00
parent 2a0c8a410f
commit 342fba5b45
6 changed files with 205 additions and 0 deletions

View File

@ -1,6 +1,7 @@
Container Roles Container Roles
=============== ===============
.. zuul:autorole:: build-container-image
.. zuul:autorole:: build-docker-image .. zuul:autorole:: build-docker-image
.. zuul:autorole:: deploy-openshift .. zuul:autorole:: deploy-openshift
.. zuul:autorole:: install-docker .. zuul:autorole:: install-docker

View File

@ -0,0 +1,3 @@
Build one or more container images.
.. include:: ../../roles/build-container-image/common.rst

View File

@ -0,0 +1,138 @@
This is one of a collection of roles which are designed to work
together to build, upload, and promote container images in a gating
context:
* :zuul:role:`build-container-image`: Build the images.
.. note:: Build and upload roles are forthcoming.
The :zuul:role:`build-container-image` role is designed to be used in
`check` and `gate` pipelines and simply builds the images. It can be
used to verify that the build functions, or it can be followed by the
use of subsequent roles to upload the images to a registry.
They all accept the same input data, principally a list of
dictionaries representing the images to build. YAML anchors_ can be
used to supply the same data to all three jobs.
Use the :zuul:role:`install-docker` or :zuul:role:`install-podman`
role to install Docker or Podman before using these roles.
**Role Variables**
.. zuul:rolevar:: zuul_work_dir
:default: {{ zuul.project.src_dir }}
The project directory. Serves as the base for
:zuul:rolevar:`build-container-image.container_images.context`.
.. zuul:rolevar:: container_dockerfile
:default: Dockerfile
The default Dockerfile name to use. Serves as the base for
:zuul:rolevar:`build-container-image.container_images.dockerfile`.
This allows a global overriding of Dockerfile name, for example
when building all images from different folders with similarily
named dockerfiles.
.. zuul:rolevar:: container_command
:default: podman
The command to use when building the image (E.g., ``docker``).
.. zuul:rolevar:: container_registry_credentials
:type: dict
This is only required for the upload and promote roles. This is
expected to be a Zuul Secret in dictionary form. Each key is the
name of a registry, and its value a dictionary with information
about that registry.
Example:
.. code-block:: yaml
container_registry_credentials:
quay.io:
username: foo
password: bar
.. zuul:rolevar:: [registry name]
:type: dict
Information about a registry. The key is the registry name, and
its value a dict as follows:
.. zuul:rolevar:: username
The registry username.
.. zuul:rolevar:: password
The registry password.
.. zuul:rolevar:: repository
Optional; if supplied this is a regular expression which
restricts to what repositories the image may be uploaded. The
following example allows projects to upload images to
repositories within an organization based on their own names::
repository: "^myorgname/{{ zuul.project.short_name }}.*"
.. zuul:rolevar:: container_images
:type: list
A list of images to build. Each item in the list should have:
.. zuul:rolevar:: context
The build context; this should be a directory underneath
:zuul:rolevar:`build-container-image.zuul_work_dir`.
.. zuul:rolevar:: dockerfile
The filename of the dockerfile, present in the context folder,
used for building the image. Provide this if you are using a
non-standard filename for a specific image.
.. zuul:rolevar:: registry
The name of the target registry (E.g., ``quay.io``). Used by
the upload and promote roles.
.. zuul:rolevar:: repository
The name of the target repository in the registry for the image.
Supply this even if the image is not going to be uploaded (it
will be tagged with this in the local registry).
.. zuul:rolevar:: path
Optional: the directory that should be passed to the build
command. Useful for building images with a Dockerfile in the
context directory but a source repository elsewhere.
.. zuul:rolevar:: build_args
:type: list
Optional: a list of values to pass to the ``--build-arg``
parameter.
.. zuul:rolevar:: target
Optional: the target for a multi-stage build.
.. zuul:rolevar:: tags
:type: list
:default: ['latest']
A list of tags to be added to the image when promoted.
.. zuul:rolevar:: tags
:type: list
:default: ['latest']
A list of tags to be added to the image when promoted.
.. _anchors: https://yaml.org/spec/1.2/spec.html#&%20anchor//

View File

@ -0,0 +1,3 @@
zuul_work_dir: "{{ zuul.project.src_dir }}"
container_dockerfile: "Dockerfile"
container_command: podman

View File

@ -0,0 +1,48 @@
# This can be removed if we add this functionality to Zuul directly
- name: Load information from zuul_return
when: buildset_registry is not defined
set_fact:
buildset_registry: "{{ (lookup('file', zuul.executor.work_root + '/results.json') | from_json)['buildset_registry'] }}"
ignore_errors: true
- name: Build a container image
command: >-
{{ container_command }} build {{ item.path | default('.') }} -f {{ item.dockerfile | default(container_dockerfile) }}
{% if item.target | default(false) -%}
--target {{ item.target }}
{% endif -%}
{% for build_arg in item.build_args | default([]) -%}
--build-arg {{ build_arg }}
{% endfor -%}
{% for tag in item.tags | default(['latest']) -%}
--tag {{ item.repository }}:change_{{ zuul.change }}_{{ tag }}
--tag {{ item.repository }}:{{ tag }}
{% endfor -%}
args:
chdir: "{{ zuul_work_dir }}/{{ item.context }}"
loop: "{{ container_images }}"
# Docker doesn't understand docker push [1234:5678::]:5000/image/path:tag
# so we set up /etc/hosts with a registry alias name to support ipv6 and 4.
- name: Configure /etc/hosts for buildset_registry to workaround not understanding ipv6 addresses
become: yes
lineinfile:
path: /etc/hosts
state: present
regex: "^{{ buildset_registry.host }}\tzuul-jobs.buildset-registry$"
line: "{{ buildset_registry.host }}\tzuul-jobs.buildset-registry"
insertafter: EOF
when: buildset_registry is defined and buildset_registry.host | ipaddr
- name: Set buildset_registry alias variable when using ip
set_fact:
buildset_registry_alias: zuul-jobs.buildset-registry
when: buildset_registry is defined and buildset_registry.host | ipaddr
- name: Set buildset_registry alias variable when using name
set_fact:
buildset_registry_alias: "{{ buildset_registry.host }}"
when: buildset_registry is defined and not ( buildset_registry.host | ipaddr )
# Push each image.
- name: Push image to buildset registry
when: buildset_registry is defined
include_tasks: push.yaml
loop: "{{ container_images }}"
loop_control:
loop_var: image

View File

@ -0,0 +1,12 @@
- name: Tag image for buildset registry
command: >-
{{ container_command }} tag {{ image.repository }}:{{ image_tag }} {{ buildset_registry_alias }}:{{ buildset_registry.port }}/{{ image.repository }}:{{ image_tag }}
loop: "{{ image.tags | default(['latest']) }}"
loop_control:
loop_var: image_tag
- name: Push tag to buildset registry
command: >-
{{ container_command }} push {{ buildset_registry_alias }}:{{ buildset_registry.port }}/{{ image.repository }}:{{ image_tag }}
loop: "{{ image.tags | default(['latest']) }}"
loop_control:
loop_var: image_tag