diff --git a/Makefile b/Makefile index 9b8ca852..6b126ed4 100644 --- a/Makefile +++ b/Makefile @@ -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) @@ -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: @@ -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 @@ -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 diff --git a/build/Dockerfile b/build/Dockerfile index 3223a871..463763cf 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -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" @@ -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 diff --git a/pkg/resources/resources.go b/pkg/resources/resources.go index da6fbae5..1ceb0934 100644 --- a/pkg/resources/resources.go +++ b/pkg/resources/resources.go @@ -162,7 +162,7 @@ var assets = func() http.FileSystem { modTime: time.Time{}, uncompressedSize: 1953, - compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x95\xcf\x6e\xe3\x36\x10\xc6\xef\x7a\x8a\x0f\xd6\xa5\x05\x62\x39\xd9\x5b\xd5\x93\x9a\x78\x11\xa3\xa9\x6c\x58\xde\x06\x7b\x2a\xc6\xd4\x48\x22\x42\x91\x2a\x49\xd9\xab\xb7\x2f\x28\xdb\x59\x3b\xbb\x5e\xa0\x40\xb0\x3c\xd1\x9c\xf9\x66\x7e\xf3\xc7\x76\x8c\xe9\xfb\x9d\x28\xc6\xbd\xe9\x06\x2b\xeb\xc6\xc3\x37\x0c\x63\x65\x2d\x35\x29\x50\xef\x1b\x63\x61\xec\xf1\xe6\x92\x28\x8e\x62\x3c\x49\xc1\xda\x71\x89\x5e\x97\x6c\x47\x49\xd6\x91\x68\xf8\x64\xb9\xc1\xdf\x6c\x9d\x34\x1a\x1f\x92\x5b\xfc\x12\x1c\x26\x47\xd3\xe4\xd7\xdf\xa3\x18\x83\xe9\xd1\xd2\x00\x6d\x3c\x7a\xc7\xf0\x8d\x74\xa8\xa4\x62\xf0\x17\xc1\x9d\x87\xd4\x10\xa6\xed\x94\x24\x2d\x18\x7b\xe9\x9b\x31\xcd\x31\x48\x12\xc5\xf8\x7c\x0c\x61\xb6\x9e\xa4\x06\x41\x98\x6e\x80\xa9\xce\xfd\x40\x7e\x04\x06\xd0\x78\xdf\xa5\xb3\xd9\x7e\xbf\x4f\x68\x64\x4d\x8c\xad\x67\xea\xe0\xe7\x66\x4f\x8b\xfb\x79\x5e\xcc\xa7\x1f\x92\xdb\x51\xf1\x49\x2b\x76\x0e\x96\xff\xed\xa5\xe5\x12\xdb\x01\xd4\x75\x4a\x0a\xda\x2a\x86\xa2\xfd\xd8\x94\xda\x32\x97\xf0\x26\xe0\xee\xad\xf4\x52\xd7\x37\x70\xa6\xf2\x7b\xb2\x1c\xc5\x28\xa5\xf3\x56\x6e\x7b\x7f\xd1\xab\x13\x9c\x74\x17\x0e\x46\x83\x34\x26\x59\x81\x45\x31\xc1\x1f\x59\xb1\x28\x6e\xa2\x18\xcf\x8b\xcd\xe3\xf2\xd3\x06\xcf\xd9\x7a\x9d\xe5\x9b\xc5\xbc\xc0\x72\x8d\xfb\x65\xfe\xb0\xd8\x2c\x96\x79\x81\xe5\x47\x64\xf9\x67\xfc\xb9\xc8\x1f\x6e\xc0\xd2\x37\x6c\xc1\x5f\x3a\x1b\xf8\x8d\x85\x0c\x5d\xe4\x32\xb4\xac\x60\xbe\x00\xa8\xcc\x01\xc8\x75\x2c\x64\x25\x05\x14\xe9\xba\xa7\x9a\x51\x9b\x1d\x5b\x2d\x75\x8d\x8e\x6d\x2b\x5d\x98\xa5\x03\xe9\x32\x8a\xa1\x64\x2b\x3d\xf9\xf1\xe5\x9b\xa2\x42\x9a\xf7\x5c\xcd\xe8\x45\xea\x32\xc5\x03\x77\xca\x0c\x2d\x6b\x1f\x51\x27\x8f\xcb\x95\x86\x91\xb8\xd9\xee\x2e\x6a\xd9\x53\x49\x9e\xd2\x08\xd0\xd4\x72\x8a\x81\x5e\xdc\xd4\x74\x6c\xc9\x1b\x1b\x01\x8a\xb6\xac\x5c\xb0\x23\xa8\x52\x4c\x82\xc7\x64\xfc\x1c\x6e\x89\x90\xde\xf6\xae\xb2\xd4\xf2\xde\xd8\x97\x71\x3b\xc2\x06\x1a\xcd\xda\xa7\x78\x0d\x15\x7a\x15\xc2\x58\x1e\xb7\xc1\xa5\xb8\x8b\x00\xe7\x2d\x79\xae\x87\x43\x02\x3f\x74\x9c\x62\xcd\xc2\x32\x79\x0e\x66\x56\x2c\xbc\xb1\x07\x73\x4b\x5e\x34\x4f\x67\x40\xd7\xa0\x3d\xb7\x9d\x22\xcf\x47\xd9\x59\x91\xe1\xa8\x8b\x08\xd7\x62\x1c\xce\xff\x2a\xf1\x24\x7a\xdb\xa7\x53\xe9\xe3\x9d\xed\x4e\x0a\xce\x84\x30\xbd\xf6\xf9\xd5\xd4\xc2\xe8\xf0\xf5\x64\x7b\x06\x3a\xfd\x21\x2a\x20\x5b\xaa\x39\x45\x69\xc4\x0b\xdb\x44\x9a\xd9\x1b\xf0\x59\x10\xa6\xb7\xc9\xdd\x6f\xc9\xed\xb4\xc8\xb3\x55\xf1\xb8\xdc\x9c\xe9\x85\x69\x5b\xd2\x65\x7a\xf6\x34\x1d\x93\x5d\x3c\x5c\x4b\xbc\xea\x95\x5a\x19\x25\xc5\x90\x62\x51\xe5\xc6\xaf\x2c\xbb\xb0\x78\x5f\xfd\x58\xef\xce\x83\x7f\xad\xe8\x39\xdb\xdc\x3f\xfe\x93\x67\x7f\xcd\x8b\x55\x76\x3f\xbf\xf0\x01\x76\xa4\x7a\xfe\x68\x4d\x9b\xbe\x31\x00\x95\x64\x55\xae\xb9\xfa\xd6\x72\xb4\xad\xc8\x37\xe9\xeb\x0a\x24\x21\x9d\xeb\x48\xf0\x77\x31\x96\xab\xf9\x3a\xdb\x2c\xd7\x23\xc9\xf7\x20\x2e\xc6\xfa\x56\xbd\x5a\x3e\x5c\x15\xbe\x1f\xfd\x85\x6b\x8c\xd7\x9e\x85\x5f\x45\x52\x7b\x1a\xdc\xe1\xaf\xe8\x38\x25\xbc\x56\x7c\x03\xa9\x4b\xee\x58\x97\xac\xbd\x1a\x50\x59\xd3\xfe\xb0\xf1\xa7\xba\x7e\xea\x58\xfe\x0b\x00\x00\xff\xff\x6c\xba\x3d\x95\xa1\x07\x00\x00"), + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x95\xdf\x8f\xe2\x36\x10\xc7\xdf\xf3\x57\x7c\x45\x5e\x5a\x69\x09\x7b\xf7\x98\x3e\xa5\x2c\xa7\x45\xdd\x06\x44\xb8\xae\xee\xa9\x1a\x9c\x49\x62\xad\x63\xa7\xb6\x03\x97\xff\xbe\x72\x80\x3d\xd8\x3b\x4e\xaa\xb4\xaa\x9f\x8c\x67\xbe\x33\x9f\xf9\x01\xc4\x98\xbe\xdf\x89\x62\xcc\x4d\x37\x58\x59\x37\x1e\xbe\x61\x18\x2b\x6b\xa9\x49\x81\x7a\xdf\x18\x0b\x63\x4f\x37\x97\x44\x71\x14\xe3\x49\x0a\xd6\x8e\x4b\xf4\xba\x64\x3b\x4a\xb2\x8e\x44\xc3\x67\xcb\x1d\xfe\x62\xeb\xa4\xd1\xf8\x98\xdc\xe3\x97\xe0\x30\x39\x99\x26\xbf\xfe\x16\xc5\x18\x4c\x8f\x96\x06\x68\xe3\xd1\x3b\x86\x6f\xa4\x43\x25\x15\x83\xbf\x0a\xee\x3c\xa4\x86\x30\x6d\xa7\x24\x69\xc1\x38\x48\xdf\x8c\x69\x4e\x41\x92\x28\xc6\x97\x53\x08\xb3\xf3\x24\x35\x08\xc2\x74\x03\x4c\x75\xe9\x07\xf2\x23\x30\x80\xc6\xfb\x2e\x9d\xcd\x0e\x87\x43\x42\x23\x6b\x62\x6c\x3d\x53\x47\x3f\x37\x7b\x5a\xce\x17\x79\xb1\x98\x7e\x4c\xee\x47\xc5\x67\xad\xd8\x39\x58\xfe\xa7\x97\x96\x4b\xec\x06\x50\xd7\x29\x29\x68\xa7\x18\x8a\x0e\x63\x53\x6a\xcb\x5c\xc2\x9b\x80\x7b\xb0\xd2\x4b\x5d\xdf\xc1\x99\xca\x1f\xc8\x72\x14\xa3\x94\xce\x5b\xb9\xeb\xfd\x55\xaf\xce\x70\xd2\x5d\x39\x18\x0d\xd2\x98\x64\x05\x96\xc5\x04\xbf\x67\xc5\xb2\xb8\x8b\x62\x3c\x2f\xb7\x8f\xab\xcf\x5b\x3c\x67\x9b\x4d\x96\x6f\x97\x8b\x02\xab\x0d\xe6\xab\xfc\x61\xb9\x5d\xae\xf2\x02\xab\x4f\xc8\xf2\x2f\xf8\x63\x99\x3f\xdc\x81\xa5\x6f\xd8\x82\xbf\x76\x36\xf0\x1b\x0b\x19\xba\xc8\x65\x68\x59\xc1\x7c\x05\x50\x99\x23\x90\xeb\x58\xc8\x4a\x0a\x28\xd2\x75\x4f\x35\xa3\x36\x7b\xb6\x5a\xea\x1a\x1d\xdb\x56\xba\x30\x4b\x07\xd2\x65\x14\x43\xc9\x56\x7a\xf2\xe3\xcb\x77\x45\x85\x34\xef\xb9\x9a\xd1\x8b\xd4\x65\x8a\x07\xee\x94\x19\x5a\xd6\x3e\xa2\x4e\x9e\x96\x2b\x0d\x23\x71\xb3\xfd\x87\xa8\x65\x4f\x25\x79\x4a\x23\x40\x53\xcb\x29\x06\x7a\x71\x53\xd3\xb1\x25\x6f\x6c\x04\x28\xda\xb1\x72\xc1\x8e\xa0\x4a\x31\x09\x1e\x93\xf1\x73\xb8\x25\x42\x7a\xdb\xbb\xca\x52\xcb\x07\x63\x5f\xc6\xed\x08\x1b\x68\x34\x6b\x9f\xe2\x35\x54\xe8\x55\x08\x63\x79\xdc\x06\x97\xe2\x43\x04\x38\x6f\xc9\x73\x3d\x1c\x13\xf8\xa1\xe3\x14\x1b\x16\x96\xc9\x73\x30\xb3\x62\xe1\x8d\x3d\x9a\x5b\xf2\xa2\x79\xba\x00\xba\x05\xed\xb9\xed\x14\x79\x3e\xc9\x2e\x8a\x0c\x47\x5d\x45\xb8\x15\xe3\x78\xfe\x53\x89\x67\xd1\xdb\x3e\x9d\x4b\x1f\xef\x6c\xf7\x52\x70\x26\x84\xe9\xb5\xcf\x6f\xa6\x16\x46\x87\xaf\x27\xdb\x0b\xd0\xe9\x4f\x51\x01\xd9\x52\xcd\x29\x4a\x23\x5e\xd8\x26\xd2\xcc\xde\x80\xcf\x82\x30\xbd\x4f\x3e\xde\x27\xf7\xd3\x22\xcf\xd6\xc5\xe3\x6a\x7b\xa1\x17\xa6\x6d\x49\x97\xe9\xc5\xd3\x74\x4c\x76\xf5\x70\x2b\xf1\xba\x57\x6a\x6d\x94\x14\x43\x8a\x65\x95\x1b\xbf\xb6\xec\xc2\xe2\x7d\xf3\x63\xbd\xbf\x0c\xfe\xad\xa2\xe7\x6c\x3b\x7f\xfc\x3b\xcf\xfe\x5c\x14\xeb\x6c\xbe\xb8\xf2\x01\xf6\xa4\x7a\xfe\x64\x4d\x9b\xbe\x31\x00\x95\x64\x55\x6e\xb8\xfa\xde\x72\xb2\xad\xc9\x37\xe9\xeb\x0a\x24\x21\x9d\xeb\x48\xf0\x0f\x31\x56\xeb\xc5\x26\xdb\xae\x36\x23\xc9\x8f\x20\xae\xc6\xfa\x56\xbd\x5e\x3d\xdc\x14\xbe\x1f\xfd\x95\x6b\x8c\xd7\x9e\x85\x5f\x45\x52\x07\x1a\xdc\xf1\xaf\xe8\x34\x25\xbc\x56\x7c\x07\xa9\x4b\xee\x58\x97\xac\xbd\x1a\x50\x59\xd3\xfe\xb4\xf1\xe7\xba\xfe\xd7\xb1\xfc\x1b\x00\x00\xff\xff\xe7\x6a\x79\x81\xa1\x07\x00\x00"), }, "/manager/operator-service-account.yaml": &vfsgen۰CompressedFileInfo{ name: "operator-service-account.yaml", diff --git a/script/docker-build.sh b/script/docker-build.sh index 4fed939c..f2d70498 100755 --- a/script/docker-build.sh +++ b/script/docker-build.sh @@ -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 . diff --git a/script/release.sh b/script/release.sh index 794f18d4..4dedbece 100755 --- a/script/release.sh +++ b/script/release.sh @@ -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 @@ -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 @@ -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() {