diff --git a/roles/build-container-image/tasks/main.yaml b/roles/build-container-image/tasks/main.yaml index 84bb82c79..8c821d6ea 100644 --- a/roles/build-container-image/tasks/main.yaml +++ b/roles/build-container-image/tasks/main.yaml @@ -87,6 +87,7 @@ loop: "{{ container_images }}" loop_control: loop_var: zj_image + when: inventory_hostname == ansible_play_hosts[0] - name: Multiarch podman block when: diff --git a/roles/build-container-image/tasks/setup-buildx.yaml b/roles/build-container-image/tasks/setup-buildx.yaml index 81f100c48..546a9acf7 100644 --- a/roles/build-container-image/tasks/setup-buildx.yaml +++ b/roles/build-container-image/tasks/setup-buildx.yaml @@ -3,13 +3,26 @@ when: ansible_architecture == 'x86_64' - name: Create builder - command: "docker buildx create --name mybuilder --driver-opt network=host{% if buildset_registry is defined %} --config /etc/buildkit/buildkitd.toml {% endif %}" + command: "docker buildx create --name mybuilder --node {{ inventory_hostname | replace('-', '_') }} --driver-opt network=host{% if buildset_registry is defined %} --config /etc/buildkit/buildkitd.toml {% endif %}" + when: inventory_hostname == ansible_play_hosts[0] + +- name: Add host key to known_hosts + shell: "ssh-keyscan -H {{ ansible_host }} >> ~/.ssh/known_hosts" + when: inventory_hostname != ansible_play_hosts[0] + delegate_to: "{{ ansible_play_hosts[0] }}" + +- name: Append builders from other nodes + command: "docker buildx create --append --name mybuilder --node {{ inventory_hostname | replace('-', '_') }} --driver-opt network=host{% if buildset_registry is defined %} --config /etc/buildkit/buildkitd.toml {% endif %} ssh://{{ ansible_user }}@{{ ansible_host }}" + when: inventory_hostname != ansible_play_hosts[0] + delegate_to: "{{ ansible_play_hosts[0] }}" - name: Use builder command: docker buildx use mybuilder + when: inventory_hostname == ansible_play_hosts[0] - name: Bootstrap builder command: docker buildx inspect --bootstrap + when: inventory_hostname == ansible_play_hosts[0] - name: Make tempfile for registry TLS certificate tempfile: @@ -25,11 +38,11 @@ when: buildset_registry is defined and buildset_registry.cert - name: Copy buildset registry TLS cert into worker container - command: "docker cp {{ buildkit_cert_tmp.path }} buildx_buildkit_mybuilder0:/usr/local/share/ca-certificates" + command: "docker cp {{ buildkit_cert_tmp.path }} buildx_buildkit_{{ inventory_hostname | replace('-', '_') }}:/usr/local/share/ca-certificates" when: buildset_registry is defined and buildset_registry.cert - name: Update CA certs in worker container - command: docker exec buildx_buildkit_mybuilder0 update-ca-certificates + command: "docker exec buildx_buildkit_{{ inventory_hostname | replace('-', '_') }} update-ca-certificates" when: buildset_registry is defined and buildset_registry.cert - name: Remove TLS cert tempfile @@ -44,7 +57,7 @@ register: etc_hosts_tmp - name: Copy /etc/hosts for editing - command: 'docker cp buildx_buildkit_mybuilder0:/etc/hosts {{ etc_hosts_tmp.path }}' + command: "docker cp buildx_buildkit_{{ inventory_hostname | replace('-', '_') }}:/etc/hosts {{ etc_hosts_tmp.path }}" # Docker buildx has its own /etc/hosts in the builder image. - name: Configure /etc/hosts for buildset_registry to workaround docker not understanding ipv6 addresses @@ -58,16 +71,16 @@ when: buildset_registry is defined and buildset_registry.host | ipaddr - name: Unmount the /etc/hosts mount - command: docker exec buildx_buildkit_mybuilder0 umount /etc/hosts + command: "docker exec buildx_buildkit_{{ inventory_hostname | replace('-', '_') }} umount /etc/hosts" # NOTE(mordred) This is done in two steps. Even though we've unmounted /etc/hosts # in the previous step, when we try to copy the file back directly, we get: # unlinkat /etc/hosts: device or resource busy - name: Copy modified hosts file back in - command: 'docker cp {{ etc_hosts_tmp.path }} buildx_buildkit_mybuilder0:/etc/new-hosts' + command: "docker cp {{ etc_hosts_tmp.path }} buildx_buildkit_{{ inventory_hostname | replace('-', '_') }}:/etc/new-hosts" - name: Copy modified hosts file into place - command: docker exec buildx_buildkit_mybuilder0 cp /etc/new-hosts /etc/hosts + command: "docker exec buildx_buildkit_{{ inventory_hostname | replace('-', '_') }} cp /etc/new-hosts /etc/hosts" - name: Remove tempfile for /etc/hosts file: diff --git a/roles/build-docker-image/tasks/main.yaml b/roles/build-docker-image/tasks/main.yaml index b51801cc0..684d46cbc 100644 --- a/roles/build-docker-image/tasks/main.yaml +++ b/roles/build-docker-image/tasks/main.yaml @@ -85,6 +85,7 @@ loop: "{{ docker_images }}" loop_control: loop_var: zj_image + when: inventory_hostname == ansible_play_hosts[0] - name: Cleanup sibling source directory file: diff --git a/roles/build-docker-image/tasks/setup-buildx.yaml b/roles/build-docker-image/tasks/setup-buildx.yaml index f42f93097..f2fefbe14 100644 --- a/roles/build-docker-image/tasks/setup-buildx.yaml +++ b/roles/build-docker-image/tasks/setup-buildx.yaml @@ -5,19 +5,34 @@ when: ansible_architecture == 'x86_64' - name: Create builder - command: "docker buildx create --name mybuilder --driver-opt network=host{% if buildset_registry is defined %} --config /etc/buildkit/buildkitd.toml {% endif %}" + command: "docker buildx create --name mybuilder --node {{ inventory_hostname | replace('-', '_') }} --driver-opt network=host{% if buildset_registry is defined %} --config /etc/buildkit/buildkitd.toml {% endif %}" environment: DOCKER_CLI_EXPERIMENTAL: enabled + when: inventory_hostname == ansible_play_hosts[0] + +- name: Add host key to known_hosts + shell: "ssh-keyscan -H {{ ansible_host }} >> ~/.ssh/known_hosts" + when: inventory_hostname != ansible_play_hosts[0] + delegate_to: "{{ ansible_play_hosts[0] }}" + +- name: Append builders from other nodes + command: "docker buildx create --append --name mybuilder --node {{ inventory_hostname | replace('-', '_') }} --driver-opt network=host{% if buildset_registry is defined %} --config /etc/buildkit/buildkitd.toml {% endif %} ssh://{{ ansible_user }}@{{ ansible_host }}" + environment: + DOCKER_CLI_EXPERIMENTAL: enabled + when: inventory_hostname != ansible_play_hosts[0] + delegate_to: "{{ ansible_play_hosts[0] }}" - name: Use builder command: docker buildx use mybuilder environment: DOCKER_CLI_EXPERIMENTAL: enabled + when: inventory_hostname == ansible_play_hosts[0] - name: Bootstrap builder command: docker buildx inspect --bootstrap environment: DOCKER_CLI_EXPERIMENTAL: enabled + when: inventory_hostname == ansible_play_hosts[0] - name: Make tempfile for registry TLS certificate tempfile: @@ -33,11 +48,11 @@ when: buildset_registry is defined and buildset_registry.cert - name: Copy buildset registry TLS cert into worker container - command: "docker cp {{ buildkit_cert_tmp.path }} buildx_buildkit_mybuilder0:/usr/local/share/ca-certificates" + command: "docker cp {{ buildkit_cert_tmp.path }} buildx_buildkit_{{ inventory_hostname | replace('-', '_') }}:/usr/local/share/ca-certificates" when: buildset_registry is defined and buildset_registry.cert - name: Update CA certs in worker container - command: docker exec buildx_buildkit_mybuilder0 update-ca-certificates + command: "docker exec buildx_buildkit_{{ inventory_hostname | replace('-', '_') }} update-ca-certificates" when: buildset_registry is defined and buildset_registry.cert - name: Remove TLS cert tempfile @@ -52,7 +67,7 @@ register: etc_hosts_tmp - name: Copy /etc/hosts for editing - command: 'docker cp buildx_buildkit_mybuilder0:/etc/hosts {{ etc_hosts_tmp.path }}' + command: "docker cp buildx_buildkit_{{ inventory_hostname | replace('-', '_') }}:/etc/hosts {{ etc_hosts_tmp.path }}" # Docker buildx has its own /etc/hosts in the builder image. - name: Configure /etc/hosts for buildset_registry to workaround docker not understanding ipv6 addresses @@ -66,16 +81,16 @@ when: buildset_registry is defined and buildset_registry.host | ipaddr - name: Unmount the /etc/hosts mount - command: docker exec buildx_buildkit_mybuilder0 umount /etc/hosts + command: "docker exec buildx_buildkit_{{ inventory_hostname | replace('-', '_') }} umount /etc/hosts" # NOTE(mordred) This is done in two steps. Even though we've unmounted /etc/hosts # in the previous step, when we try to copy the file back directly, we get: # unlinkat /etc/hosts: device or resource busy - name: Copy modified hosts file back in - command: 'docker cp {{ etc_hosts_tmp.path }} buildx_buildkit_mybuilder0:/etc/new-hosts' + command: "docker cp {{ etc_hosts_tmp.path }} buildx_buildkit_{{ inventory_hostname | replace('-', '_') }}:/etc/new-hosts" - name: Copy modified hosts file into place - command: docker exec buildx_buildkit_mybuilder0 cp /etc/new-hosts /etc/hosts + command: "docker exec buildx_buildkit_{{ inventory_hostname | replace('-', '_') }} cp /etc/new-hosts /etc/hosts" - name: Remove tempfile for /etc/hosts file: diff --git a/roles/upload-container-image/tasks/main.yaml b/roles/upload-container-image/tasks/main.yaml index 9239a436f..ec86ee992 100644 --- a/roles/upload-container-image/tasks/main.yaml +++ b/roles/upload-container-image/tasks/main.yaml @@ -27,4 +27,6 @@ loop_control: loop_var: zj_image include_tasks: push.yaml - when: not upload_container_image_promote|default(true) or promote_container_image_method|default('tag') == 'tag' + when: + - inventory_hostname == ansible_play_hosts[0] + - not upload_container_image_promote|default(true) or promote_container_image_method|default('tag') == 'tag' diff --git a/zuul-tests.d/container-roles-jobs.yaml b/zuul-tests.d/container-roles-jobs.yaml index bc3dffffc..7cb718286 100644 --- a/zuul-tests.d/container-roles-jobs.yaml +++ b/zuul-tests.d/container-roles-jobs.yaml @@ -124,6 +124,22 @@ container_command: docker multiarch: true +- job: + name: zuul-jobs-test-build-container-image-docker-release-multiarch-multinode + parent: zuul-jobs-test-build-container-image-docker-release-multiarch + description: | + Test building a multi-arch container image with docker in a release pipeline + across two nodes (native multiple architecture system). + + NOTE(mnaser): Since OpenDev doesn't natively support a provider that has + both x86_64 and arm64 nodes, we're using the same architecture for both. + nodeset: + nodes: + - name: amd64 + label: ubuntu-jammy + - name: arm64 + label: ubuntu-jammy + - job: name: zuul-jobs-test-build-container-image-podman-release parent: zuul-jobs-test-build-container-image-base @@ -580,6 +596,7 @@ - zuul-jobs-test-ensure-docker-ubuntu-noble - zuul-jobs-test-build-container-image-docker-release - zuul-jobs-test-build-container-image-docker-release-multiarch + - zuul-jobs-test-build-container-image-docker-release-multiarch-multinode - zuul-jobs-test-build-container-image-podman-release - zuul-jobs-test-build-container-image-docker-promote - zuul-jobs-test-build-container-image-docker-promote-multiarch