From c7b00fe62474ab8702cb7850af0f38096140d806 Mon Sep 17 00:00:00 2001 From: Ashok Pariya Date: Thu, 28 Nov 2024 07:22:14 +0000 Subject: [PATCH] Enable support for multiple platforms in the Linux Bridge CNI. These updates allow the building and pushing of Linux Bridge container images for multiple platforms (e.g., amd64, s390x) using a single Dockerfile. Multi-platform build support is provided for both Docker and Podman container runtimes. Signed-off-by: Ashok Pariya --- hack/build-operator-podman.sh | 1 + hack/components/bump-linux-bridge.sh | 83 ++++++++++++++++++++++++---- 2 files changed, 72 insertions(+), 12 deletions(-) diff --git a/hack/build-operator-podman.sh b/hack/build-operator-podman.sh index c47f64f9f..6cc75eb22 100755 --- a/hack/build-operator-podman.sh +++ b/hack/build-operator-podman.sh @@ -10,6 +10,7 @@ IFS=',' read -r -a PLATFORM_LIST <<< "$PLATFORMS" # Remove any existing manifest and image podman manifest rm "${OPERATOR_IMAGE_TAGGED}" 2>/dev/null || true podman rmi "${OPERATOR_IMAGE_TAGGED}" 2>/dev/null || true +podman rmi $(podman images --filter "dangling=true" -q) 2>/dev/null || true podman manifest create "${OPERATOR_IMAGE_TAGGED}" diff --git a/hack/components/bump-linux-bridge.sh b/hack/components/bump-linux-bridge.sh index fe13a03ce..890ba253f 100755 --- a/hack/components/bump-linux-bridge.sh +++ b/hack/components/bump-linux-bridge.sh @@ -7,7 +7,6 @@ source hack/components/git-utils.sh source hack/components/docker-utils.sh export OCI_BIN=${OCI_BIN:-$(docker-utils::determine_cri_bin)} - echo Bumping linux-bridge LINUX_BRIDGE_URL=$(yaml-utils::get_component_url linux-bridge) LINUX_BRIDGE_COMMIT=$(yaml-utils::get_component_commit linux-bridge) @@ -27,19 +26,33 @@ echo 'Build container image with linux-bridge binaries' LINUX_BRIDGE_TAR_CONTAINER_DIR=/usr/src/github.com/containernetworking/plugins/bin LINUX_BRIDGE_IMAGE=quay.io/kubevirt/cni-default-plugins LINUX_BRIDGE_IMAGE_TAGGED=${LINUX_BRIDGE_IMAGE}:${LINUX_BRIDGE_TAG} -( - cd ${LINUX_BRIDGE_PATH} +DOCKER_BUILDER="${DOCKER_BUILDER:-linux-bridge-docker-builder}" +# By default, the build will target all supported platforms(i.e PLATFORM_LIST). +# To build for specific platforms, you can: +# 1. Specify individual platforms: +# export PLATFORMS=linux/amd64 +# or +# export PLATFORMS=linux/amd64,linux/arm64 +PLATFORM_LIST="linux/amd64,linux/s390x,linux/arm64" +ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/') +PLATFORMS="${PLATFORMS:-all}" +[ "$PLATFORMS" == "all" ] && PLATFORMS="${PLATFORM_LIST}" +IFS=',' read -r -a PLATFORM_LIST <<< "$PLATFORMS" + +create_dockerfile() { cat < Dockerfile -FROM registry.access.redhat.com/ubi8/ubi-minimal AS builder +FROM --platform=\$BUILDPLATFORM registry.access.redhat.com/ubi8/ubi-minimal AS builder +ARG TARGETOS +ARG TARGETARCH RUN microdnf install -y golang git RUN \ git clone https://${LINUX_BRIDGE_REPO} ${LINUX_BRIDGE_PATH} && \ cd ${LINUX_BRIDGE_PATH} && \ git checkout ${LINUX_BRIDGE_TAG} WORKDIR ${LINUX_BRIDGE_PATH} -RUN GOFLAGS=-mod=vendor ./build_linux.sh +RUN GOFLAGS=-mod=vendor GOARCH=\${TARGETARCH} GOOS=\${TARGETOS} ./build_linux.sh -FROM registry.access.redhat.com/ubi8/ubi-minimal +FROM --platform=linux/\$TARGETARCH registry.access.redhat.com/ubi8/ubi-minimal LABEL org.opencontainers.image.authors="phoracek@redhat.com" ENV SOURCE_DIR=${REMOTE_SOURCE_DIR}/app RUN mkdir -p ${LINUX_BRIDGE_TAR_CONTAINER_DIR} @@ -49,14 +62,60 @@ COPY --from=builder ${LINUX_BRIDGE_PATH}/bin/tuning ${LINUX_BRIDGE_TAR_CONTAINER RUN sha256sum ${LINUX_BRIDGE_TAR_CONTAINER_DIR}/bridge >${LINUX_BRIDGE_TAR_CONTAINER_DIR}/bridge.checksum RUN sha256sum ${LINUX_BRIDGE_TAR_CONTAINER_DIR}/tuning >${LINUX_BRIDGE_TAR_CONTAINER_DIR}/tuning.checksum EOF - ${OCI_BIN} build -t ${LINUX_BRIDGE_IMAGE_TAGGED} . -) +} -echo 'Push the image to KubeVirt repo' -( - if [ ! -z ${PUSH_IMAGES} ]; then - ${OCI_BIN} push "${LINUX_BRIDGE_IMAGE_TAGGED}" +check_and_create_docker_builder() { + existing_builder=$(docker buildx ls | grep -w "$DOCKER_BUILDER" | awk '{print $1}' || true) + if [ -n "$existing_builder" ]; then + echo "Builder '$DOCKER_BUILDER' already exists. Using existing builder." + docker buildx use "$DOCKER_BUILDER" + else + echo "Creating a new Docker Buildx builder: $DOCKER_BUILDER" + docker buildx create --driver-opt network=host --use --name "$DOCKER_BUILDER" fi +} + +build_docker_image() { + docker buildx build --platform "${PLATFORMS}" -t "${LINUX_BRIDGE_IMAGE_TAGGED}" . --push + docker buildx rm "$DOCKER_BUILDER" +} + +build_podman_image() { + podman manifest rm "${LINUX_BRIDGE_IMAGE_TAGGED}" 2>/dev/null || true + podman rmi "${LINUX_BRIDGE_IMAGE_TAGGED}" 2>/dev/null || true + podman rmi $(podman images --filter "dangling=true" -q) 2>/dev/null || true + podman manifest create "${LINUX_BRIDGE_IMAGE_TAGGED}" + + for platform in "${PLATFORM_LIST[@]}"; do + podman build --platform "$platform" --manifest "${LINUX_BRIDGE_IMAGE_TAGGED}" . + done +} + +push_image_to_kubevirt_repo() { + echo 'Push the image to KubeVirt repo' + if [ "${OCI_BIN}" == "podman" ]; then + if [ ! -z "${PUSH_IMAGES}" ]; then + podman manifest push "${LINUX_BRIDGE_IMAGE_TAGGED}" + fi + fi +} + + +( + cd ${LINUX_BRIDGE_PATH} + create_dockerfile + ( + if [[ "${OCI_BIN}" == "docker" ]]; then + check_and_create_docker_builder + build_docker_image + elif [[ "${OCI_BIN}" == "podman" ]]; then + build_podman_image + push_image_to_kubevirt_repo + else + echo "Invalid OCI_BIN value. It must be either 'docker' or 'podman'." + exit 1 + fi + ) ) if [[ -n "$(docker-utils::check_image_exists "${LINUX_BRIDGE_IMAGE}" "${LINUX_BRIDGE_TAG}")" ]]; then