Skip to content

Commit 6694f0a

Browse files
authored
Multi-Arch Support for oci-registry builds and CI (#240)
* add multi-arch build support for build.sh script & update doc for new functionality Signed-off-by: Jordan Dubrick <jdubrick@redhat.com> * test new workflow for buildx Signed-off-by: Jordan Dubrick <jdubrick@redhat.com> * add multi arch script Signed-off-by: Jordan Dubrick <jdubrick@redhat.com> * add base repository Signed-off-by: Jordan Dubrick <jdubrick@redhat.com> * update ci to test both amd64 and arm64 image builds Signed-off-by: Jordan Dubrick <jdubrick@redhat.com> * add multi arch building stage for oci registry Signed-off-by: Jordan Dubrick <jdubrick@redhat.com> * add qemu for arm64 image building Signed-off-by: Jordan Dubrick <jdubrick@redhat.com> * add base tag for image Signed-off-by: Jordan Dubrick <jdubrick@redhat.com> * fix podman condition Signed-off-by: Jordan Dubrick <jdubrick@redhat.com> * pin login action to hash Signed-off-by: Jordan Dubrick <jdubrick@redhat.com> * make default manifest image a var Signed-off-by: Jordan Dubrick <jdubrick@redhat.com> * add troubleshooting section Signed-off-by: Jordan Dubrick <jdubrick@redhat.com> --------- Signed-off-by: Jordan Dubrick <jdubrick@redhat.com>
1 parent b1ec2c0 commit 6694f0a

File tree

5 files changed

+151
-12
lines changed

5 files changed

+151
-12
lines changed

.github/workflows/ci.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ jobs:
8888
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
8989
with:
9090
go-version: ${{ env.GO_VERSION }}
91+
92+
- name: Set up QEMU # Enables arm64 image building
93+
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 #v3.0.0
9194

9295
- name: Check license
9396
run: |
@@ -113,7 +116,7 @@ jobs:
113116
run: cd index/server && go test ./... -coverprofile cover.out
114117

115118
- name: Check if oci server build is working
116-
run: cd oci-registry && bash ./build.sh
119+
run: cd oci-registry && bash ./build.sh && bash ./build.sh linux/arm64
117120

118121
- name: Check if devfile-registry-integration build is working
119122
run: cd tests/integration && bash ./docker-build.sh

.github/workflows/pushimage-next.yaml

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,17 +89,16 @@ jobs:
8989
steps:
9090
- name: Check out registry support source code
9191
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
92-
- name: Build and push oci-registry docker image
93-
uses: docker/build-push-action@v1.1.0
92+
- name: Set up QEMU # Enables arm64 image building
93+
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 #v3.0.0
94+
- name: Login to Quay.io
95+
uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v2.2.0
9496
with:
95-
path: ./oci-registry
97+
registry: quay.io
9698
username: ${{ secrets.QUAY_USERNAME }}
9799
password: ${{ secrets.QUAY_PASSWORD }}
98-
registry: quay.io
99-
repository: devfile/oci-registry
100-
dockerfile: ./oci-registry/Dockerfile
101-
tags: next
102-
tag_with_sha: true
100+
- name: Build and push oci-registry docker image
101+
run: bash ./oci-registry/build-multi-arch.sh
103102

104103
devfileRegistryIntegrationBuild:
105104
runs-on: ubuntu-latest

oci-registry/README.md

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ This folder contains the Dockerfile for the OCI registry server. It is based off
55
## Build
66
The scripts in this project support both `Docker` and `Podman` container engines. By default the scripts will run using `Docker`, to use `Podman` first run `export USE_PODMAN=true`.
77

8-
To build the image, run `bash build.sh`.
8+
The build script enables users to build for different architectures, by default running `bash build.sh` will build for `linux/amd64`. If you would like to build for a different architecture simply add it as an argument to the script. E.g. `bash build.sh linux/arm64` for `linux/arm64` builds.
99

1010
To push the image to a repository of your choice, you can run `bash push.sh <repository-tag>`.
1111

@@ -16,4 +16,49 @@ To deploy this image as part of a Devfile registry:
1616
1. Build and push this image to an image registry.
1717
2. Install the [Devfile Registry Operator](https://github.com/devfile/registry-operator) on a Kubernetes cluster.
1818
3. Create a `DevfileRegistry` yaml file and set `spec.ociRegistryImage` to the name of your pushed image from the previous step.
19-
4. Run `kubectl apply -f <devfile-registry yaml>`
19+
4. Run `kubectl apply -f <devfile-registry yaml>`
20+
21+
## Troubleshooting
22+
23+
If you are trying to run `build-multi-arch.sh`, or you are trying to run `build.sh` for an architecture your machine is **not running** on, you may encounter an error similiar to this in your build:
24+
```
25+
Dockerfile:18
26+
--------------------
27+
16 |
28+
17 | FROM registry.access.redhat.com/ubi8-minimal:8.2
29+
18 | >>> RUN microdnf update -y && rm -rf /var/cache/yum && microdnf install ca-certificates httpd-tools
30+
19 |
31+
20 | # Create a non-root user to run the server as
32+
--------------------
33+
ERROR: failed to solve: process "/bin/sh -c microdnf update -y && rm -rf /var/cache/yum && microdnf install ca-certificates httpd-tools" did not complete successfully: exit code: 1
34+
```
35+
36+
This error can occur because your container engine is not properly supporting emulation. To check if this is the case you can run:
37+
```
38+
podman run --rm --privileged tonistiigi/binfmt
39+
```
40+
or if you are using docker:
41+
```
42+
docker run --rm --privileged tonistiigi/binfmt
43+
```
44+
45+
This command will output something similar to the following where you can observe what architectures are currently supported for you:
46+
```
47+
"supported": [
48+
"linux/arm64",
49+
"linux/amd64",
50+
"linux/riscv64",
51+
"linux/ppc64le",
52+
"linux/s390x",
53+
"linux/386",
54+
"linux/mips64le",
55+
"linux/mips64"
56+
]
57+
```
58+
59+
If you do not see the architecture you are trying to build for in the output list you are probably missing emulation capabilities. The following command has been known to fix this issue and allow for emulation:
60+
```
61+
sudo apt-get install -y gcc-arm-linux-gnueabihf libc6-dev-armhf-cross qemu-user-static qemu-system-i386
62+
```
63+
64+
The CI environments we call these scripts in are incorporating the use of QEMU. If the above command does not solve the issue for you it would be best to investigate into if QEMU is working properly in your environment.

oci-registry/build-multi-arch.sh

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#!/bin/sh
2+
3+
#
4+
# Copyright Red Hat
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
18+
buildfolder="$(basename "$(dirname "$0")")"
19+
# Due to command differences between podman and docker we need to separate the process
20+
# for creating and adding images to a multi-arch manifest
21+
podman=${USE_PODMAN:-false}
22+
# Stores all created image tags
23+
images=()
24+
# Base Repository
25+
BASE_REPO="quay.io/devfile/oci-registry"
26+
BASE_TAG="next"
27+
DEFAULT_MANIFEST="$BASE_REPO:$BASE_TAG"
28+
29+
function build {
30+
IMAGE="$BASE_REPO:$2"
31+
32+
echo "Building: ${IMAGE}"
33+
$1 build -t $IMAGE --platform "linux/$2" "$buildfolder"
34+
35+
echo "Tagging: ${IMAGE}"
36+
$1 tag "$IMAGE" "$IMAGE"
37+
38+
echo "Pushing: ${IMAGE}"
39+
$1 push "$IMAGE"
40+
41+
# Add image to list of all images to be added to a manifest
42+
images+=("${IMAGE}")
43+
}
44+
45+
function engine-handler {
46+
for arch in amd64 arm64 ; do
47+
build "$1" "$arch"
48+
done
49+
}
50+
51+
52+
if [ ${podman} == true ]; then
53+
echo "Executing with podman"
54+
55+
# Build and push multi-arch images
56+
engine-handler podman
57+
58+
# Create manifest and add images
59+
podman manifest create oci-registry-manifest
60+
for img in "${images[@]}" ; do
61+
podman manifest add oci-registry-manifest "$img"
62+
done
63+
64+
# Push and delete local manifest
65+
podman manifest push oci-registry-manifest "$DEFAULT_MANIFEST"
66+
podman manifest rm oci-registry-manifest
67+
68+
else
69+
echo "Executing with docker"
70+
71+
# Build and push multi-arch images
72+
engine-handler docker
73+
74+
# Create manifest and add images
75+
docker manifest create "$DEFAULT_MANIFEST" "${images[@]}"
76+
77+
# Push and delete local manifest
78+
docker manifest push "$DEFAULT_MANIFEST"
79+
docker manifest rm "$$DEFAULT_MANIFEST"
80+
81+
fi

oci-registry/build.sh

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,18 @@
1818
# Build the index container for the registry
1919
buildfolder="$(basename "$(dirname "$0")")"
2020

21+
DEFAULT_ARCH="linux/amd64"
22+
23+
# Check if different architecture was passed for image build
24+
# Will default to $DEFAULT_ARCH if unset
25+
if [ ! -z "$1" ]
26+
then
27+
arch="$1"
28+
else
29+
arch="$DEFAULT_ARCH"
30+
fi
31+
2132
# set podman alias if necessary
2233
. ${buildfolder}/../setenv.sh
2334

24-
docker build -t oci-registry:next $buildfolder
35+
docker build -t oci-registry:next --platform "${arch}" "$buildfolder"

0 commit comments

Comments
 (0)