Skip to content

Commit d2c970a

Browse files
Merge pull request #444 from darkdoc/arm64_support
arm64 support
2 parents 280f2d9 + 30dcdb4 commit d2c970a

File tree

7 files changed

+202
-129
lines changed

7 files changed

+202
-129
lines changed

.github/workflows/build-push.yaml

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
name: Build (amd64 and arm64) and push to quay registries
2+
on:
3+
push:
4+
branches: ["main"]
5+
tags: ['[0-9]+.[0-9]+.[0-9]+']
6+
pull_request:
7+
branches: ["main"]
8+
9+
workflow_dispatch:
10+
11+
permissions:
12+
contents: read
13+
14+
env:
15+
REGISTRY: localhost
16+
NAME: patterns-operator
17+
TAG: ${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || (github.ref_name == 'main' && 'latest' || github.ref_name) }}
18+
19+
jobs:
20+
build-container:
21+
strategy:
22+
matrix:
23+
include:
24+
- targetarch: amd64
25+
runner: ubuntu-latest
26+
- targetarch: arm64
27+
runner: ubuntu-24.04-arm
28+
29+
runs-on: ${{ matrix.runner }}
30+
permissions:
31+
contents: read
32+
steps:
33+
- name: Checkout repository
34+
uses: actions/checkout@v5
35+
with:
36+
persist-credentials: false
37+
38+
- name: Build container and save tarball
39+
env:
40+
TARGETARCH: ${{ matrix.targetarch }}
41+
OPERATOR_IMG: ${{ env.NAME }}:${{ env.TAG }}
42+
KEY: ${{ secrets.API_KEY }}
43+
run: |
44+
export APIFILE="internal/controller/apikey.txt"
45+
trap "rm -f ${APIFILE}" SIGINT EXIT
46+
47+
if [ -z "${KEY}" ]; then
48+
echo "Key is empty"
49+
echo '' > "${APIFILE}"
50+
else
51+
echo "Key is set"
52+
echo "${KEY}" > "${APIFILE}"
53+
fi
54+
make "podman-build-${TARGETARCH}"
55+
buildah push "${OPERATOR_IMG}-${TARGETARCH}" "docker-archive:/tmp/image-${TARGETARCH}.tar:${OPERATOR_IMG}-${TARGETARCH}"
56+
57+
- name: Upload image artifact
58+
uses: actions/upload-artifact@v4
59+
with:
60+
name: image-${{ matrix.targetarch }}-${{ github.run_id }}
61+
path: /tmp/image-${{ matrix.targetarch }}.tar
62+
retention-days: 1
63+
64+
pre-push-check:
65+
needs: [build-container]
66+
if: github.event_name != 'pull_request'
67+
runs-on: ubuntu-latest
68+
steps:
69+
- name: Checkout repository
70+
uses: actions/checkout@v5
71+
with:
72+
persist-credentials: false
73+
74+
# We use an env due to https://docs.zizmor.sh/audits/#remediation_18
75+
- name: Check that tag version corresponds to metadata version
76+
run: |-
77+
VERSION=$(yq -r '.spec.version' bundle/manifests/patterns-operator.clusterserviceversion.yaml)
78+
if [ "${VERSION}" != "${TAG}" ]; then
79+
echo "Version in metadata ${VERSION} whereas tag is different: ${TAG}"
80+
exit 1
81+
fi
82+
83+
push-multiarch-manifest:
84+
needs: [pre-push-check]
85+
if: github.event_name != 'pull_request'
86+
strategy:
87+
matrix:
88+
include:
89+
- upload_registry: quay.io/validatedpatterns
90+
legacy: false
91+
- upload_registry: quay.io/hybridcloudpatterns
92+
legacy: true
93+
runs-on: ubuntu-latest
94+
permissions:
95+
contents: read
96+
# This is used to complete the identity challenge
97+
# with sigstore/fulcio when running outside of PRs.
98+
id-token: write
99+
100+
steps:
101+
- name: Checkout repository
102+
uses: actions/checkout@v5
103+
with:
104+
persist-credentials: false
105+
106+
- name: Download AMD64 image
107+
uses: actions/download-artifact@v5
108+
with:
109+
name: image-amd64-${{ github.run_id }}
110+
path: /tmp
111+
112+
- name: Download ARM64 image
113+
uses: actions/download-artifact@v5
114+
with:
115+
name: image-arm64-${{ github.run_id }}
116+
path: /tmp
117+
118+
- name: Load tarballs into local containers-storage
119+
run: |
120+
buildah pull docker-archive:/tmp/image-amd64.tar
121+
buildah pull docker-archive:/tmp/image-arm64.tar
122+
123+
- name: Log into Quay
124+
env:
125+
USERNAME: ${{ matrix.legacy && secrets.LEGACY_QUAY_USERNAME || secrets.QUAY_USERNAME }}
126+
PASSWORD: ${{ matrix.legacy && secrets.LEGACY_QUAY_PASSWORD || secrets.QUAY_PASSWORD }}
127+
run: |
128+
buildah login -u "${USERNAME}" -p "${PASSWORD}" quay.io
129+
130+
# The compressed manifest in Quay has a different digest than the local so we
131+
# need to use skopeo to retrieve the correct digest for signing
132+
- name: Create manifest and push to Quay
133+
id: manifest-push
134+
env:
135+
UPLOADREGISTRY: ${{ matrix.upload_registry }}
136+
OPERATOR_IMG: ${{ env.NAME }}:${{ env.TAG }}
137+
run: |
138+
make buildah-manifest
139+
buildah manifest add --arch=amd64 "${REGISTRY}/${OPERATOR_IMG}" "${REGISTRY}/${OPERATOR_IMG}-amd64"
140+
buildah manifest add --arch=arm64 "${REGISTRY}/${OPERATOR_IMG}" "${REGISTRY}/${OPERATOR_IMG}-arm64"
141+
make buildah-push
142+
DIGEST=$(skopeo inspect --format "{{.Digest}}" "docker://${UPLOADREGISTRY}/${OPERATOR_IMG}")
143+
echo "digest=$DIGEST" >> "$GITHUB_OUTPUT"
144+
145+
- name: Install cosign
146+
uses: sigstore/cosign-installer@d7543c93d881b35a8faa02e8e3605f69b7a1ce62 # v3.10.0
147+
with:
148+
cosign-release: "v2.2.4"
149+
150+
# Cosign expects the docker config.json for registry authentication so we must
151+
# copy it from buildah
152+
- name: Sign the published Docker image
153+
env:
154+
DIGEST: ${{ steps.manifest-push.outputs.digest }}
155+
UPLOADREGISTRY: ${{ matrix.upload_registry }}
156+
OPERATOR_IMG: ${{ env.NAME }}:${{ env.TAG }}
157+
run: |
158+
cat "${XDG_RUNTIME_DIR}/containers/auth.json" > ~/.docker/config.json
159+
cosign sign --yes "${UPLOADREGISTRY}/${OPERATOR_IMG}@${DIGEST}"

.github/workflows/docker-build.yml

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

.github/workflows/push-built-tag.yml

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

Dockerfile

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
FROM registry.access.redhat.com/ubi9/ubi-minimal:latest AS builder
2-
RUN microdnf install git-core jq tar -y && microdnf clean all
1+
ARG GO_VERSION=1.24.6
2+
FROM registry.access.redhat.com/ubi9/go-toolset:${GO_VERSION} AS builder
3+
ARG GOARCH=amd64
34

45
# Build the manager binary
56

@@ -9,18 +10,6 @@ WORKDIR /workspace
910
COPY go.mod go.mod
1011
COPY go.sum go.sum
1112

12-
# use latest Go z release
13-
ENV GOTOOLCHAIN=auto
14-
ENV GO_INSTALL_DIR=/golang
15-
16-
# Ensure correct Go version
17-
RUN export GO_VERSION=$(grep -E "go [[:digit:]]\.[[:digit:]][[:digit:]]" go.mod | awk '{print $2}') && \
18-
export GO_FILENAME=$(curl -sL 'https://go.dev/dl/?mode=json&include=all' | jq -r "[.[] | select(.version | startswith(\"go${GO_VERSION}\"))][0].files[] | select(.os == \"linux\" and .arch == \"amd64\") | .filename") && \
19-
curl -sL -o go.tar.gz "https://golang.org/dl/${GO_FILENAME}" && \
20-
mkdir -p ${GO_INSTALL_DIR} && \
21-
tar -C ${GO_INSTALL_DIR} -xzf go.tar.gz && \
22-
rm go.tar.gz && ln -sf ${GO_INSTALL_DIR}/go/bin/go /usr/bin/go
23-
2413
# Copy the go sources
2514
COPY vendor/ vendor/
2615
COPY cmd/main.go cmd/main.go
@@ -29,11 +18,12 @@ COPY version/ version/
2918
COPY internal/controller/ internal/controller/
3019
COPY hack/ hack/
3120
COPY .git/ .git/
32-
RUN mkdir /licenses
33-
COPY LICENSE /licenses
21+
COPY LICENSE /licenses/
22+
COPY Makefile .
3423

3524
# Build
36-
RUN --mount=type=secret,id=apikey hack/build.sh
25+
USER root
26+
RUN --mount=type=secret,id=apikey GOARCH=${GOARCH} make build
3727

3828
# Use distroless as minimal base image to package the manager binary
3929
# Refer to https://github.com/GoogleContainerTools/distroless for more details

Makefile

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ VERSION ?= 0.0.4
77
OPERATOR_NAME ?= patterns
88
GOFLAGS=-mod=vendor
99
GOLANGCI_VERSION ?= 2.5.0
10+
REGISTRY ?= localhost
11+
UPLOADREGISTRY ?= quay.io/validatedpatterns
1012

1113
# CI uses a non-writable home dir, make sure .cache is writable
1214
ifeq ("${HOME}", "/")
@@ -65,6 +67,7 @@ BUNDLE_IMG ?= $(IMAGE_TAG_BASE)-bundle:v$(VERSION)
6567

6668
# Image URL to use all building/pushing image targets
6769
IMG ?= $(IMAGE_TAG_BASE):$(VERSION)
70+
OPERATOR_IMG ?= $(OPERATOR_NAME)-operator:$(VERSION)
6871
# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
6972
ENVTEST_K8S_VERSION = 1.30
7073

@@ -148,18 +151,42 @@ clean: ## Remove build artifacts and downloaded tools
148151
run: apikey manifests generate fmt vet ## Run a controller from your host.
149152
GOOS=${GOOS} GOARCH=${GOARCH} hack/build.sh run
150153

151-
.PHONY: docker-build
152-
docker-build: apikey ## Build docker image with the manager.
153-
docker build --secret id=apikey,src=$(APIKEYFILE) --platform $(CONTAINER_OS)/$(CONTAINER_PLATFORM) -t ${IMG} .
154154

155-
.PHONY: docker-push
156-
docker-push: ## Push docker image with the manager.
157-
docker push ${IMG}
155+
##@ Conatiner-related tasks
156+
.PHONY: buildah-manifest
157+
buildah-manifest: apikey ## creates the buildah manifest for multi-arch images
158+
# The rm is needed due to bug https://www.github.com/containers/podman/issues/19757
159+
buildah manifest rm "${REGISTRY}/${OPERATOR_IMG}" || /bin/true
160+
buildah manifest create "${REGISTRY}/${OPERATOR_IMG}"
161+
162+
.PHONY: podman-build-amd64
163+
podman-build-amd64: buildah-manifest ## build the container in amd64
164+
@echo "Building the operator amd64"
165+
buildah build --secret id=apikey,src=$(APIKEYFILE) --platform linux/amd64 --format docker -f Dockerfile -t "${OPERATOR_IMG}-amd64"
166+
buildah manifest add --arch=amd64 "${REGISTRY}/${OPERATOR_IMG}" "${REGISTRY}/${OPERATOR_IMG}-amd64"
167+
168+
.PHONY: podman-build-arm64
169+
podman-build-arm64: buildah-manifest ## build the container in arm64
170+
@echo "Building the operator arm64"
171+
buildah build --secret id=apikey,src=$(APIKEYFILE) --platform linux/arm64 --build-arg GOARCH="arm64" --format docker -f Dockerfile -t "${OPERATOR_IMG}-arm64"
172+
buildah manifest add --arch=arm64 "${REGISTRY}/${OPERATOR_IMG}" "${REGISTRY}/${OPERATOR_IMG}-arm64"
173+
174+
.PHONY: buildah-push
175+
buildah-push: ## Uploads the container to quay.io/validatedpatterns/${OPERATOR_IMG}
176+
@echo "Uploading the ${REGISTRY}/${OPERATOR_IMG} container to ${UPLOADREGISTRY}/${OPERATOR_IMG}"
177+
buildah manifest push --all "${REGISTRY}/${OPERATOR_IMG}" "docker://${UPLOADREGISTRY}/${OPERATOR_IMG}"
158178

159179
.PHONY: golangci-lint
160180
golangci-lint: apikey ## Run golangci-lint locally
161181
podman run --pull=newer --rm -v $(PWD):/app:rw,z -w /app golangci/golangci-lint:v$(GOLANGCI_VERSION) golangci-lint run -v
162182

183+
##@ Legacy docker tasks
184+
.PHONY: docker-build
185+
docker-build: apikey podman-build-amd64 ## Build docker image with the manager.
186+
187+
.PHONY: docker-push
188+
docker-push: buildah-push ## Push docker image with the manager.
189+
163190
##@ Deployment
164191

165192
ifndef ignore-not-found

config/manifests/bases/patterns-operator.clusterserviceversion.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ metadata:
2020
operators.openshift.io/must-gather-image: quay.io/validatedpatterns/must-gather:latest
2121
repository: https://github.com/validatedpatterns/patterns-operator
2222
23+
labels:
24+
operatorframework.io/arch.amd64: supported
25+
operatorframework.io/arch.arm64: supported
2326
name: patterns-operator.v0.0.0
2427
namespace: placeholder
2528
spec:

hack/build.sh

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
#!/bin/bash
22
set -ex
33

4-
# GOOS and GOARCH will be set if calling from make. Dockerfile calls this script
5-
# directly without calling make so the default values need to be set here also.
6-
[[ -z "$GOOS" ]] && GOOS=linux
7-
[[ -z "$GOARCH" ]] && GOARCH=amd64
8-
94
GIT_VERSION=$(git describe --always --tags || true)
105
VERSION=${CI_UPSTREAM_VERSION:-${GIT_VERSION}}
116
GIT_COMMIT=$(git rev-list -1 HEAD || true)

0 commit comments

Comments
 (0)