Skip to content

Commit 7346c86

Browse files
committed
Fixes #1787: Multiarch skupper-router container image build using docker buildx.
1 parent 968b141 commit 7346c86

File tree

8 files changed

+78
-492
lines changed

8 files changed

+78
-492
lines changed

.github/scripts/image.sh

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
set -exo pipefail
2121

22-
CONTAINER=podman
22+
CONTAINER=docker
2323
PROJECT_NAME=skupper-router
2424
CONTAINER_REGISTRY=quay.io
2525
CONTAINER_ORG=skupper
@@ -28,41 +28,30 @@ export BUILDAH_FORMAT=docker
2828
if [ -z "$PROJECT_TAG" ]; then
2929
PROJECT_TAG=main
3030
fi
31-
# PLATFORM can be amd64 or arm64
32-
if [ -z "$PLATFORM" ]; then
33-
PLATFORM=amd64
34-
fi
35-
36-
PLATFORM_LINUX=linux-${PLATFORM}
37-
PROJECT_TAG=${PROJECT_TAG}-${PLATFORM_LINUX}
3831

3932
# Building the skupper-router image
4033
# Pass the VERSION as a build argument so Containerfile can use it when calling compile.sh
4134
# This version is passed in as a -DVERSION build parameter when building skupper-router.
42-
${CONTAINER} build --build-arg PLATFORM=$PLATFORM --build-arg VERSION=$VERSION -t ${PROJECT_NAME}:${PROJECT_TAG} -f ./Containerfile .
35+
# ${CONTAINER} build --build-arg PLATFORM=$PLATFORM --build-arg VERSION=$VERSION -t ${PROJECT_NAME}:${PROJECT_TAG} -f ./Containerfile .
4336

4437
# Pushing only when credentials available
4538
if [[ -n "${CONTAINER_USER}" && -n "${CONTAINER_PASSWORD}" ]]; then
39+
# Login to the quay.io container repo.
4640
${CONTAINER} login -u ${CONTAINER_USER} -p ${CONTAINER_PASSWORD} ${CONTAINER_REGISTRY}
47-
${CONTAINER} tag ${PROJECT_NAME}:${PROJECT_TAG} ${CONTAINER_REGISTRY}/${CONTAINER_ORG}/${PROJECT_NAME}:${PROJECT_TAG}
48-
${CONTAINER} push ${CONTAINER_REGISTRY}/${CONTAINER_ORG}/${PROJECT_NAME}:${PROJECT_TAG}
41+
${CONTAINER} buildx prune -af
42+
${CONTAINER} buildx build --provenance=false --platform linux/amd64,linux/arm64,linux/s390x,linux/ppc64le --build-arg PLATFORM=$PLATFORM --build-arg VERSION=$VERSION --push -t ${CONTAINER_REGISTRY}/${CONTAINER_ORG}/${PROJECT_NAME}:${PROJECT_TAG} -f ./Containerfile .
4943

5044
# Only publish build number tag if one provided
5145
if [[ -n "${BUILD_NUMBER}" ]]; then
52-
${CONTAINER} tag ${PROJECT_NAME}:${PROJECT_TAG} ${CONTAINER_REGISTRY}/${CONTAINER_ORG}/${PROJECT_NAME}:${PROJECT_TAG}-${BUILD_NUMBER}
53-
${CONTAINER} push ${CONTAINER_REGISTRY}/${CONTAINER_ORG}/${PROJECT_NAME}:${PROJECT_TAG}-${BUILD_NUMBER}
46+
${CONTAINER} buildx build --provenance=false --platform linux/amd64,linux/arm64,linux/s390x,linux/ppc64le --build-arg PLATFORM=$PLATFORM --build-arg VERSION=$VERSION --push -t ${CONTAINER_REGISTRY}/${CONTAINER_ORG}/${PROJECT_NAME}:${PROJECT_TAG}-${BUILD_NUMBER} -f ./Containerfile .
5447
fi
5548

56-
# PUSH_LATEST environment variable is exported only in release.yml
57-
# Only when an actual release tag (for e.g. 2.1.0) is pushed, we push the :latest.
5849
# :latest represents the latest released version of the software.
5950
# We do not push :latest when main or other non-release tags are pushed.
6051
if [ -z "$PUSH_LATEST" ]; then
6152
echo 'NOT Pushing :latest tag'
6253
else
63-
echo 'Pushing :latest-linux-amd64 tag or :latest-linux-arm64 (image.sh)'
64-
PROJECT_TAG_LATEST=latest-${PLATFORM_LINUX}
65-
${CONTAINER} tag ${PROJECT_NAME}:${PROJECT_TAG} ${CONTAINER_REGISTRY}/${CONTAINER_ORG}/${PROJECT_NAME}:${PROJECT_TAG_LATEST}
66-
${CONTAINER} push ${CONTAINER_REGISTRY}/${CONTAINER_ORG}/${PROJECT_NAME}:${PROJECT_TAG_LATEST}
54+
PROJECT_TAG_LATEST=latest
55+
${CONTAINER} buildx build --provenance=false --platform linux/amd64,linux/arm64,linux/s390x,linux/ppc64le --build-arg PLATFORM=$PLATFORM --build-arg VERSION=$VERSION --push -t ${CONTAINER_REGISTRY}/${CONTAINER_ORG}/${PROJECT_NAME}:${PROJECT_TAG_LATEST} -f ./Containerfile .
6756
fi
6857
fi

.github/scripts/manifest.sh

Lines changed: 0 additions & 80 deletions
This file was deleted.

.github/workflows/image-main.yml

Lines changed: 10 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -25,69 +25,26 @@ on:
2525
types:
2626
- completed
2727
jobs:
28-
build-image-amd64:
29-
name: Publish skupper-router amd64 image
28+
build-multiarch-image:
29+
name: Build and publish multiarch skupper-router image
3030
runs-on: ubuntu-latest
3131
steps:
32-
- uses: actions/checkout@v4
33-
- name: Build and publish the main amd64 image
34-
run: |
35-
# The version on main will be 0.0.0+<commit-sha>-main
36-
export VERSION="0.0.0+${GITHUB_SHA}-main"
37-
export PLATFORM=amd64
38-
unset PUSH_LATEST
39-
./.github/scripts/image.sh
40-
env:
41-
CONTAINER_USER: '${{ secrets.DOCKER_USER }}'
42-
CONTAINER_PASSWORD: '${{ secrets.DOCKER_PASSWORD }}'
32+
- name: Set up QEMU
33+
uses: docker/setup-qemu-action@v2
4334

44-
build-image-arm64:
45-
name: Publish skupper-router arm64 image
46-
runs-on: ubuntu-24.04-arm
47-
steps:
35+
- name: Set up Buildx
36+
uses: docker/setup-buildx-action@v2
37+
4838
- uses: actions/checkout@v4
49-
- name: Install podman
50-
run: |
51-
sudo apt-get update -qq
52-
sudo apt-get -qq -y install podman
53-
podman version
54-
# Starting systemd user service
55-
systemctl --user start podman.socket
56-
echo "PODMAN_SOCK=/run/user/${UID}/podman/podman.sock" >> $GITHUB_ENV
57-
echo "DOCKER_HOST=unix:///run/user/${UID}/podman/podman.sock" >> $GITHUB_ENV
58-
- name: Build and publish the main arm64 image
39+
- name: Build and publish multiarch skupper-router image
5940
run: |
6041
# The version on main will be 0.0.0+<commit-sha>-main
6142
export VERSION="0.0.0+${GITHUB_SHA}-main"
6243
unset PUSH_LATEST
63-
export PLATFORM=arm64
44+
6445
./.github/scripts/image.sh
6546
env:
6647
CONTAINER_USER: '${{ secrets.DOCKER_USER }}'
67-
CONTAINER_PASSWORD: '${{ secrets.DOCKER_PASSWORD }}'
48+
CONTAINER_PASSWORD: '${{ secrets.DOCKER_PASSWORD }}'
6849

69-
# This job pulls the images produced by the build-image-amd64 and build-image-arm64 jobs
70-
create-manifest:
71-
needs: [build-image-amd64, build-image-arm64]
72-
name: Pull skupper-router amd64 and arm64 images and create/push manifest
73-
runs-on: ubuntu-latest
74-
steps:
75-
- uses: actions/checkout@v4
76-
- name: Install podman
77-
run: |
78-
sudo apt-get update -qq
79-
sudo apt-get -qq -y install podman
80-
podman version
81-
# Starting systemd user service
82-
systemctl --user start podman.socket
83-
echo "PODMAN_SOCK=/run/user/${UID}/podman/podman.sock" >> $GITHUB_ENV
84-
echo "DOCKER_HOST=unix:///run/user/${UID}/podman/podman.sock" >> $GITHUB_ENV
85-
- name: Pull skupper-router amd64 and arm64 images and create/push manifest
86-
run: |
87-
# This is the main build which means we WON'T push the :latest tag to the container repo.
88-
unset PUSH_LATEST
89-
./.github/scripts/manifest.sh
90-
env:
91-
CONTAINER_USER: '${{ secrets.DOCKER_USER }}'
92-
CONTAINER_PASSWORD: '${{ secrets.DOCKER_PASSWORD }}'
9350

.github/workflows/image-manual.yml

Lines changed: 13 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ on:
3636
default: false
3737

3838
jobs:
39-
build-image-amd64:
40-
name: Build and publish skupper-router amd64 image
39+
build-multiarch-image:
40+
name: Build and publish multiarch skupper-router image
4141
runs-on: ubuntu-latest
4242
steps:
4343
- run: |
@@ -51,9 +51,17 @@ jobs:
5151
fi
5252
done
5353
env:
54-
CONTAINER_TAG: '${{github.event.inputs.containerTag}}'
54+
CONTAINER_TAG: '${{github.event.inputs.containerTag}}'
55+
56+
- name: Set up QEMU
57+
uses: docker/setup-qemu-action@v2
58+
59+
- name: Set up Buildx
60+
uses: docker/setup-buildx-action@v2
61+
5562
- uses: actions/checkout@v4
56-
- run: |
63+
- name: Build and Push Multi-Arch Image
64+
run: |
5765
# build, run tests and if all worked publish a custom image
5866
export PROJECT_TAG="${CONTAINER_TAG}"
5967
# The version of skupper-router should be the same as the version of the image.
@@ -73,107 +81,11 @@ jobs:
7381
else
7482
echo 'image-manual.yml(job:build-manual-amd64) not setting PUSH_LATEST, will not push :latest tag'
7583
fi
76-
export PLATFORM=amd64
77-
./.github/scripts/image.sh
78-
env:
79-
CONTAINER_USER: '${{ secrets.DOCKER_USER }}'
80-
CONTAINER_PASSWORD: '${{ secrets.DOCKER_PASSWORD }}'
81-
PROTON_SOURCE_URL: '${{github.event.inputs.protonSourceUrl}}'
82-
CONTAINER_TAG: '${{github.event.inputs.containerTag}}'
83-
84-
build-image-arm64:
85-
name: Build and publish skupper-router arm64 image
86-
runs-on: ubuntu-24.04-arm
87-
steps:
88-
- run: |
89-
# validate CONTAINER_TAG
90-
[[ ! "${CONTAINER_TAG}" =~ ^[a-z0-9][a-z0-9.-]+[a-z0-9]$ ]] && echo "invalid tag - it must begin and end with letter or digit and contains - and ." && exit 1
91-
protected=(latest nightly master)
92-
for ptag in ${protected[@]}; do
93-
if [[ "${ptag}" = "${CONTAINER_TAG}" ]]; then
94-
echo "${ptag} cannot be used (protected tag)"
95-
exit 1
96-
fi
97-
done
98-
env:
99-
CONTAINER_TAG: '${{github.event.inputs.containerTag}}'
100-
- uses: actions/checkout@v4
101-
- name: Install podman
102-
run: |
103-
sudo apt-get update -qq
104-
sudo apt-get -qq -y install podman
105-
podman version
106-
# Starting systemd user service
107-
systemctl --user start podman.socket
108-
echo "PODMAN_SOCK=/run/user/${UID}/podman/podman.sock" >> $GITHUB_ENV
109-
echo "DOCKER_HOST=unix:///run/user/${UID}/podman/podman.sock" >> $GITHUB_ENV
110-
- run: |
111-
export PROJECT_TAG="${CONTAINER_TAG}"
112-
# The version of skupper-router should be the same as the version of the image.
113-
export VERSION="${CONTAINER_TAG}"
114-
115-
if [ "${CONTAINER_TAG}" != "main" ]; then
116-
export BUILD_NUMBER=$((`curl -s https://quay.io/api/v1/repository/skupper/skupper-router/tag/?filter_tag_name=like:${VERSION} | jq '.tags[] | select(has("end_ts") | not) | .name' | grep -E "\"${VERSION}-[0-9]+\"" | wc -l || echo 0` + 1))
117-
# Only accepts tag if build_number is higher than one
118-
# Verify if build number is unique, otherwise fail
119-
[[ ${BUILD_NUMBER} -eq 1 ]] && { echo "The provided tag (${VERSION}) does not refer to a released image. You must provide a tag that has already been released."; exit 1; }
120-
else
121-
echo "CONTAINER_TAG is main"
122-
fi
123-
124-
CAN_PUSH_LATEST='${{github.event.inputs.canPushLatestTag}}'
125-
if [ "${CAN_PUSH_LATEST}" == "true" ]; then
126-
echo 'image-manual.yml(job:build-image-arm64) setting PUSH_LATEST=true, will push :latest tag'
127-
export PUSH_LATEST=true
128-
else
129-
echo 'image-manual.yml(job:build-image-arm64) not setting PUSH_LATEST, will not push :latest tag'
130-
fi
131-
export PLATFORM=arm64
84+
13285
./.github/scripts/image.sh
13386
env:
13487
CONTAINER_USER: '${{ secrets.DOCKER_USER }}'
13588
CONTAINER_PASSWORD: '${{ secrets.DOCKER_PASSWORD }}'
13689
PROTON_SOURCE_URL: '${{github.event.inputs.protonSourceUrl}}'
13790
CONTAINER_TAG: '${{github.event.inputs.containerTag}}'
13891

139-
# This job pulls the images produced by the build-image-amd64 and build-image-arm64 jobs
140-
create-manifest:
141-
needs: [build-image-amd64, build-image-arm64]
142-
name: Pull skupper-router amd64 and arm64 images and create/push manifest
143-
runs-on: ubuntu-latest
144-
steps:
145-
- uses: actions/checkout@v4
146-
- name: Install podman
147-
run: |
148-
sudo apt-get update -qq
149-
sudo apt-get -qq -y install podman
150-
podman version
151-
# Starting systemd user service
152-
systemctl --user start podman.socket
153-
echo "PODMAN_SOCK=/run/user/${UID}/podman/podman.sock" >> $GITHUB_ENV
154-
echo "DOCKER_HOST=unix:///run/user/${UID}/podman/podman.sock" >> $GITHUB_ENV
155-
- name: Pull skupper-router amd64 and arm64 images and create/push manifest
156-
run: |
157-
export VERSION="${CONTAINER_TAG}"
158-
if [ "${CONTAINER_TAG}" != "main" ]; then
159-
export BUILD_NUMBER=$((`curl -s https://quay.io/api/v1/repository/skupper/skupper-router/tag/?filter_tag_name=like:${VERSION} | jq '.tags[] | select(has("end_ts") | not) | .name' | grep -E "\"${VERSION}-[0-9]+\"" | wc -l || echo 0` + 1))
160-
echo "BUILD_NUMER(create-manifest)=${BUILD_NUMBER}"
161-
# Only accepts tag if build_number is higher than one
162-
# Verify if build number is unique, otherwise fail
163-
[[ ${BUILD_NUMBER} -eq 1 ]] && { echo "The provided tag (${VERSION}) does not refer to a released image. You must provide a tag that has already been released."; exit 1; }
164-
else
165-
echo "CONTAINER_TAG is main"
166-
fi
167-
export PROJECT_TAG="${CONTAINER_TAG}"
168-
CAN_PUSH_LATEST='${{github.event.inputs.canPushLatestTag}}'
169-
if [ "${CAN_PUSH_LATEST}" == "true" ]; then
170-
echo 'image-manual.yml(job:pull-images) setting PUSH_LATEST=true, will push :latest tag'
171-
export PUSH_LATEST=true
172-
else
173-
echo 'image-manual.yml(job:pull-images) not setting PUSH_LATEST, will not push :latest tag'
174-
fi
175-
./.github/scripts/manifest.sh
176-
env:
177-
CONTAINER_USER: '${{ secrets.DOCKER_USER }}'
178-
CONTAINER_PASSWORD: '${{ secrets.DOCKER_PASSWORD }}'
179-
CONTAINER_TAG: '${{github.event.inputs.containerTag}}'

0 commit comments

Comments
 (0)