From 612426ead898d4608d38cdf3213b02bb5ec7b6a9 Mon Sep 17 00:00:00 2001 From: Yury K <60463629+ykulazhenkov@users.noreply.github.com> Date: Tue, 3 Dec 2024 17:53:34 +0200 Subject: [PATCH] Fix: multiarch build by using crosscompilation (#336) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use quay.io/centos/centos:stream9 with the –platform=$BUILDPLATFORM flag, in this case the image is pulled for the builder host's current architecture. The BUILDOS and BUILDARCH args are used to download the right go binary for the build platform. Cross-compilation occurs in the builder image using TARGETOS and TARGETARCH build arguments to determine the target OS/arch. These args are set automatically by the multiarch-build process (with docker buildx). The final container image (registry.access.redhat.com/ubi9/ubi-minimal) is pulled for the correct target architecture, such as amd64 or arm64. This update fixes support for multiarch builds and speeds up image building, as cross-compilation is faster than compiling on a non-native platform. Signed-off-by: Yury Kulazhenkov --- .github/workflows/image-build-test.yaml | 4 -- .github/workflows/image-push-main.yaml | 4 -- .github/workflows/image-push-release.yaml | 4 -- Makefile | 2 +- cmd/Dockerfile | 45 ++++++++++++++++------- 5 files changed, 32 insertions(+), 27 deletions(-) diff --git a/.github/workflows/image-build-test.yaml b/.github/workflows/image-build-test.yaml index 87bff92e4..917ce663e 100644 --- a/.github/workflows/image-build-test.yaml +++ b/.github/workflows/image-build-test.yaml @@ -27,9 +27,5 @@ jobs: with: context: . push: false - # no need to explicitly set goarch, - # correct arch will be selected for each build platform - build-args: | - goarch= platforms: ${{ env.BUILD_PLATFORMS }} file: ./cmd/Dockerfile diff --git a/.github/workflows/image-push-main.yaml b/.github/workflows/image-push-main.yaml index 3419ed10f..5fe74d245 100644 --- a/.github/workflows/image-push-main.yaml +++ b/.github/workflows/image-push-main.yaml @@ -45,10 +45,6 @@ jobs: with: context: . push: true - # no need to explicitly set goarch, - # correct arch will be selected for each build platform - build-args: | - goarch= platforms: ${{ env.BUILD_PLATFORMS }} tags: | ${{ env.IMAGE_NAME }}:latest diff --git a/.github/workflows/image-push-release.yaml b/.github/workflows/image-push-release.yaml index 120672a77..f45fe53b8 100644 --- a/.github/workflows/image-push-release.yaml +++ b/.github/workflows/image-push-release.yaml @@ -47,10 +47,6 @@ jobs: with: context: . push: true - # no need to explicitly set goarch, - # correct arch will be selected for each build platform - build-args: | - goarch= platforms: ${{ env.BUILD_PLATFORMS }} tags: | ${{ steps.docker_meta.outputs.tags }} diff --git a/Makefile b/Makefile index da10c4335..1d7687cd3 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ export GOROOT=$(BIN_DIR)/go/ export GOBIN = $(GOROOT)/bin/ export PATH := $(GOBIN):$(PATH):$(BIN_DIR) GOPATH = $(CURDIR)/.gopath -GOARCH ?= amd64 +GOARCH ?= $(shell uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/') ORG_PATH = github.com/k8snetworkplumbingwg PACKAGE = ovs-cni OCI_BIN ?= $(shell if podman ps >/dev/null 2>&1; then echo podman; elif docker ps >/dev/null 2>&1; then echo docker; fi) diff --git a/cmd/Dockerfile b/cmd/Dockerfile index fa677e40d..326e1157c 100644 --- a/cmd/Dockerfile +++ b/cmd/Dockerfile @@ -1,27 +1,42 @@ -FROM quay.io/centos/centos:stream9 as builder +FROM --platform=$BUILDPLATFORM quay.io/centos/centos:stream9 AS builder RUN mkdir /workdir -WORKDIR /workdir +# Support overriding target GOARCH during `make docker-build` +ARG goarch= -COPY go.mod . +# these variable are automatically set during the multiarch build by docker buildx +ARG TARGETOS +ARG TARGETARCH +ENV TARGETOS=${TARGETOS:-linux} +ENV TARGETARCH=${TARGETARCH:-amd64} + +ARG BUILDOS +ARG BUILDARCH +ENV BUILDOS=${BUILDOS:-linux} +ENV BUILDARCH=${BUILDARCH:-amd64} + +ENV GOOS=${TARGETOS} +ENV GOARCH=${goarch:-$TARGETARCH} +ENV CGO_ENABLED=0 +ENV GOFLAGS=-mod=vendor + +WORKDIR /workdir RUN dnf install -y wget +COPY go.mod . +COPY go.sum . + RUN GO_VERSION=$(sed -En 's/^go +(.*)$/\1/p' go.mod) && \ - wget https://dl.google.com/go/go${GO_VERSION}.linux-amd64.tar.gz && \ - tar -C /usr/local -xzf go${GO_VERSION}.linux-amd64.tar.gz && \ - rm go${GO_VERSION}.linux-amd64.tar.gz + wget https://dl.google.com/go/go${GO_VERSION}.${BUILDOS}-${BUILDARCH}.tar.gz && \ + tar -C /usr/local -xzf go${GO_VERSION}.${BUILDOS}-${BUILDARCH}.tar.gz && \ + rm go${GO_VERSION}.${BUILDOS}-${BUILDARCH}.tar.gz -ENV PATH /usr/local/go/bin:$PATH +ENV PATH=/usr/local/go/bin:$PATH -COPY . . +RUN go mod download -ENV GOOS linux -# Support overriding target GOARCH during `make docker-build` -ARG goarch=amd64 -ENV GOARCH=$goarch -ENV CGO_ENABLED 0 -ENV GOFLAGS -mod=vendor +COPY . . RUN mkdir /workdir/bin RUN go build -tags no_openssl -o /workdir/bin/ovs ./cmd/plugin @@ -30,6 +45,8 @@ RUN go build -tags no_openssl -o /workdir/bin/ovs-mirror-producer ./cmd/mirror-p RUN go build -tags no_openssl -o /workdir/bin/ovs-mirror-consumer ./cmd/mirror-consumer FROM registry.access.redhat.com/ubi9/ubi-minimal + RUN microdnf install -y findutils + COPY --from=builder /workdir/.version /.version COPY --from=builder /workdir/bin/* /