Skip to content

Commit

Permalink
chore: Fix multi arch Docker image build
Browse files Browse the repository at this point in the history
  • Loading branch information
christophd committed Apr 24, 2024
1 parent 4b40d5f commit 2631084
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 34 deletions.
51 changes: 40 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ OPERATOR_SDK_VERSION := v1.28.0
KUSTOMIZE_VERSION := v4.5.4
DEFAULT_IMAGE := docker.io/citrusframework/yaks
IMAGE_NAME ?= $(DEFAULT_IMAGE)
# Check for arm64, aarch64, fallback to amd64
OS_ARCH = $(if $(filter arm64 aarch64,$(shell uname -m)),arm64,amd64)
IMAGE_ARCH ?= $(OS_ARCH)

RELEASE_GIT_REMOTE := upstream
GIT_COMMIT := $(shell if [ -d .git ]; then git rev-list -1 HEAD; else echo "$(CUSTOM_VERSION)"; fi)
Expand Down Expand Up @@ -103,12 +106,19 @@ test: build
go test ./...

build-yaks:
@echo "####### Building yaks CLI..."
@# Ensure the binary is statically linked when building on Linux due to ABI changes in newer glibc 2.32, otherwise it would not run on older versions.
ifeq ($(shell uname -s 2>/dev/null || echo Unknown),Linux)
CGO_ENABLED=0 go build $(GOFLAGS) -o yaks ./cmd/manager/*.go
else
go build $(GOFLAGS) -o yaks ./cmd/manager/*.go
@echo "####### Building yaks CLI for linux/$(IMAGE_ARCH) architecture..."
CGO_ENABLED=0 GOOS=linux GOARCH=$(IMAGE_ARCH) go build $(GOFLAGS) -o build/_output/bin/yaks-$(IMAGE_ARCH) ./cmd/manager/*.go
go build $(GOFLAGS) -o build/_output/bin/yaks-$(IMAGE_ARCH) ./cmd/manager/*.go
# Symbolic link to a local CLI
ln -sf build/_output/bin/yaks-$(IMAGE_ARCH) ./yaks

build-yaks-platform:
# Perform only when running on OS other than linux
ifneq ($(shell uname -s 2>/dev/null || echo Unknown),Linux)
@echo "####### Building platform specific yaks CLI for $(OS_ARCH) architecture..."
CGO_ENABLED=0 GOARCH=$(OS_ARCH) go build $(GOFLAGS) -o build/_output/bin/yaks-$(OS_ARCH) ./cmd/manager/*.go
# Symbolic link to a local CLI
ln -sf build/_output/bin/yaks-$(OS_ARCH) ./yaks
endif

build-resources:
Expand All @@ -126,15 +136,34 @@ set-next-version:
cross-compile:
./script/cross_compile.sh $(VERSION) '$(GOFLAGS)'

docker-build:
./script/docker-build.sh $(IMAGE_NAME):$(VERSION) '$(GOFLAGS)'
image-build:
./script/docker-build.sh $(IMAGE_NAME) $(IMAGE_ARCH) $(VERSION) '$(GOFLAGS)'

images-no-test: build package-artifacts-no-test image-build build-yaks-platform

images-no-test: build package-artifacts-no-test docker-build
images: test package-artifacts image-build build-yaks-platform

images: test package-artifacts docker-build
# Make sure the current docker builder must supports the wanted platform list, which may not be the case for the default builder
#
# docker buildx inspect
# ...
# Platforms: linux/amd64*, linux/arm64*
#
# docker buildx create --name mybuilder --platform linux/amd64,linux/arm64
# docker buildx use mybuilder
images-all:
make IMAGE_ARCH=arm64 images-no-test
make IMAGE_ARCH=amd64 images-no-test

images-push:
docker push $(IMAGE_NAME):$(VERSION)-amd64
docker push $(IMAGE_NAME):$(VERSION)
@if docker inspect $(IMAGE_NAME):$(VERSION)-arm64 &> /dev/null; then \
echo "Image $(IMAGE_NAME):$(VERSION)-arm64 exists, building the multiarch manifest"; \
docker push $(IMAGE_NAME):$(VERSION)-arm64; \
docker manifest create $(IMAGE_NAME):$(VERSION) --amend $(IMAGE_NAME):$(VERSION)-amd64 --amend $(IMAGE_NAME):$(VERSION)-arm64; \
docker manifest push --purge $(IMAGE_NAME):$(VERSION); \
fi

prepare-release: check-repo clean check-licenses

Expand Down Expand Up @@ -180,7 +209,7 @@ snapshot-version:
version:
@echo $(VERSION)

.PHONY: clean build build-yaks build-resources generate-docs release-docs release-docs-dry-run release-docs-major update-olm cross-compile test docker-build images images-no-test images-push package-artifacts package-artifacts-no-test release release-snapshot set-version-file set-version set-next-version check-repo check-licenses snapshot-version version
.PHONY: clean build build-yaks build-yaks-platform build-resources generate-docs release-docs release-docs-dry-run release-docs-major update-olm cross-compile test image-build images images-no-test images-all images-push package-artifacts package-artifacts-no-test release release-snapshot set-version-file set-version set-next-version check-repo check-licenses snapshot-version version

codegen-tools-install: controller-gen
@# We must force the installation to make sure we are using the correct version
Expand Down
4 changes: 3 additions & 1 deletion build/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

FROM eclipse-temurin:17

ARG IMAGE_ARCH

ARG MAVEN_VERSION="3.9.5"
ARG MAVEN_HOME="/usr/share/maven"
ARG SHA="4810523ba025104106567d8a15a8aa19db35068c8c8be19e30b219a1d7e83bcab96124bf86dc424b1cd3c5edba25d69ec0b31751c136f88975d15406cab3842b"
Expand Down Expand Up @@ -58,4 +60,4 @@ RUN chgrp -R 0 ${APP_LIBS} && \
USER ${USER_UID}

# install operator binary
COPY build/_output/bin/yaks /usr/local/bin/yaks
COPY build/_output/bin/yaks-${IMAGE_ARCH} /usr/local/bin/yaks
2 changes: 1 addition & 1 deletion pkg/resources/resources.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 8 additions & 7 deletions script/docker-build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,21 @@
# limitations under the License.
#

if [ "$#" -ne 2 ]; then
echo "usage: $0 image:version flags"
if [ "$#" -ne 4 ]; then
echo "usage: $0 image_name image_arch version build_flags"
exit 1
fi

location=$(dirname $0)
image="$1"
build_flags="$2"
image_name="$1"
image_arch="$2"
release_version="$3"
build_flags="$4"

cd $location/..

export GOOS=linux
export GOARCH=${image_arch}
export CGO_ENABLED=0

mkdir -p build/_output/bin
eval go build "$build_flags" -o build/_output/bin/yaks ./cmd/manager/*.go
docker build --load -t $image -f build/Dockerfile .
docker buildx build --platform=linux/${image_arch} --build-arg IMAGE_ARCH=${image_arch} --load -t ${image_name}-${image_arch}:${release_version} -f build/Dockerfile .
33 changes: 19 additions & 14 deletions script/release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,11 @@ release() {
# Commit, tag, release, push
# --------------------------

# Build Docker image
# Build Docker images
mkdir -p ${working_dir}/build/_output/bin
export GOOS=linux
export GOARCH=amd64
export CGO_ENABLED=0
eval go build "$build_flags" -o ${working_dir}/build/_output/bin/yaks ${working_dir}/cmd/manager/*.go
docker build --load -t ${image}:${release_version} -f ${working_dir}/build/Dockerfile ${working_dir}
docker_build "$working_dir" "$image" "$release_version" amd64 "$build_flags"
docker_build "$working_dir" "$image" "$release_version" arm64 "$build_flags"
docker tag ${image}:${release_version}-amd64 ${image}:${release_version}

if [ ! $(hasflag --snapshot-release) ] && [ ! $(hasflag --local-release) ]; then
# Release staging repo
Expand All @@ -121,7 +119,15 @@ release() {
git_push "$working_dir" "$release_version"

# Push Docker image (if configured)
docker_push "${working_dir}" "$image" "$release_version"
if [ ! $(hasflag --no-docker-push) ]; then
echo "==== Pushing Docker images ${image}:${$release_version}"
# Push docker image
docker push ${image}:${release_version}-amd64
docker push ${image}:${release_version}-arm64
docker push ${image}:${release_version}
docker manifest create ${image}:${release_version} --amend ${image}:${release_version}-amd64 --amend ${image}:${release_version}-arm64; \
docker manifest push --purge ${image}:${release_version}
fi
fi

# Use next snapshot version for major release only
Expand Down Expand Up @@ -149,17 +155,16 @@ release() {
echo "==== Finished release $release_version"
}

docker_push() {
docker_build() {
local working_dir="$1"
local image="$2"
local release_version="$3"
local image_arch="$4"
local build_flags="$5"

echo "==== Pushing Docker image"
if [ ! $(hasflag --no-docker-push) ]; then
echo "Pushing image $image:$release_version"
# Push docker image
docker push ${image}:${release_version}
fi
echo "==== Building Docker image ${image}-${image_arch}:${$release_version}"
eval CGO_ENABLED=0 GOOS=linux GOARCH=${image_arch} go build "$build_flags" -o ${working_dir}/build/_output/bin/yaks-${image_arch} ${working_dir}/cmd/manager/*.go
docker buildx build --platform=linux/${image_arch} --build-arg IMAGE_ARCH=${image_arch} --load -t ${image}-${image_arch}:${release_version} -f ${working_dir}/build/Dockerfile ${working_dir}
}

git_push() {
Expand Down

0 comments on commit 2631084

Please sign in to comment.