Skip to content

Commit

Permalink
Add Multi-Platform support for Kubemacpool Image using make command.
Browse files Browse the repository at this point in the history
These changes provide multi-platform build support for the Kubemacpool CNI,
enabling builds for Docker and Podman container runtimes.

Signed-off-by: Ashok Pariya [email protected]
  • Loading branch information
ashokpariya0 committed Dec 11, 2024
1 parent 8c69bf2 commit 48f76fe
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 9 deletions.
29 changes: 20 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,19 @@ IMAGE_GIT_TAG ?= $(shell git describe --abbrev=8 --tags)
IMG ?= $(REPO)/kubemacpool
OCI_BIN ?= $(shell if podman ps >/dev/null 2>&1; then echo podman; elif docker ps >/dev/null 2>&1; then echo docker; fi)
TLS_SETTING := $(if $(filter $(OCI_BIN),podman),--tls-verify=false,)
PLATFORM_LIST ?= linux/amd64,linux/s390x,linux/arm64
ARCH := $(shell uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')
PLATFORMS ?= linux/${ARCH}
PLATFORMS := $(if $(filter all,$(PLATFORMS)),$(PLATFORM_LIST),$(PLATFORMS))
# Define the platforms for building a multi-platform image.
# Example:
# PLATFORMS ?= linux/amd64,linux/arm64,linux/s390x
# Alternatively, you can set the PLATFORMS variable using:
# export PLATFORMS=linux/arm64,linux/s390x,linux/amd64
# or export PLATFORMS=all to automatically include all supported platforms.
DOCKER_BUILDER ?= kubemacpool-docker-builder
KUBEMACPOOL_IMAGE_TAGGED := ${REGISTRY}/${IMG}:${IMAGE_TAG}
KUBEMACPOOL_IMAGE_GIT_TAGGED := ${REGISTRY}/${IMG}:${IMAGE_GIT_TAG}

BIN_DIR = $(CURDIR)/build/_output/bin/

Expand Down Expand Up @@ -83,18 +96,17 @@ generate: generate-go generate-deploy generate-test generate-external
check: $(GO)
./hack/check.sh

manager: $(GO)
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(GO) build -o $(BIN_DIR)/manager github.com/k8snetworkplumbingwg/kubemacpool/cmd/manager

# Build the docker image
container: manager
$(OCI_BIN) build build/ -t ${REGISTRY}/${IMG}:${IMAGE_TAG}
container:
./hack/build-multiarch-kubemacpool.sh $(ARCH) $(PLATFORMS) $(KUBEMACPOOL_IMAGE_TAGGED) $(KUBEMACPOOL_IMAGE_GIT_TAGGED) $(DOCKER_BUILDER) $(OCI_BIN)

# Push the docker image
docker-push:
$(OCI_BIN) push ${TLS_SETTING} ${REGISTRY}/${IMG}:${IMAGE_TAG}
$(OCI_BIN) tag ${REGISTRY}/${IMG}:${IMAGE_TAG} ${REGISTRY}/${IMG}:${IMAGE_GIT_TAG}
$(OCI_BIN) push ${TLS_SETTING} ${REGISTRY}/${IMG}:${IMAGE_GIT_TAG}
ifeq ($(OCI_BIN),podman)
podman manifest push ${TLS_SETTING} ${KUBEMACPOOL_IMAGE_TAGGED} ${KUBEMACPOOL_IMAGE_TAGGED}
podman tag ${KUBEMACPOOL_IMAGE_TAGGED} ${KUBEMACPOOL_IMAGE_GIT_TAGGED}
podman manifest push ${TLS_SETTING} ${KUBEMACPOOL_IMAGE_GIT_TAGGED} ${KUBEMACPOOL_IMAGE_GIT_TAGGED}
endif

cluster-up:
./cluster/up.sh
Expand Down Expand Up @@ -128,7 +140,6 @@ vendor: $(GO)
fmt \
vet \
check \
manager \
container \
push \
cluster-up \
Expand Down
18 changes: 18 additions & 0 deletions hack/build-kubemacpool-docker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash

if [ -z "$ARCH" ] || [ -z "$PLATFORMS" ] || [ -z "$KUBEMACPOOL_IMAGE_TAGGED" ] || [ -z "$KUBEMACPOOL_IMAGE_GIT_TAGGED" ]; then
echo "Error: ARCH, PLATFORMS, KUBEMACPOOL_IMAGE_TAGGED, and KUBEMACPOOL_IMAGE_GIT_TAGGED must be set."
exit 1
fi

IFS=',' read -r -a PLATFORM_LIST <<< "$PLATFORMS"

BUILD_ARGS="--build-arg BUILD_ARCH=$ARCH -f build/Dockerfile -t $KUBEMACPOOL_IMAGE_TAGGED -t $KUBEMACPOOL_IMAGE_GIT_TAGGED . --push"

if [ ${#PLATFORM_LIST[@]} -eq 1 ]; then
docker build --platform "$PLATFORMS" $BUILD_ARGS
else
./hack/init-buildx.sh "$DOCKER_BUILDER"
docker buildx build --platform "$PLATFORMS" $BUILD_ARGS
docker buildx rm "$DOCKER_BUILDER" 2>/dev/null || echo "Builder ${DOCKER_BUILDER} not found or already removed, skipping."
fi
24 changes: 24 additions & 0 deletions hack/build-kubemacpool-podman.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/bash

if [ -z "$ARCH" ] || [ -z "$PLATFORMS" ] || [ -z "$KUBEMACPOOL_IMAGE_TAGGED" ] || [ -z "$KUBEMACPOOL_IMAGE_GIT_TAGGED" ]; then
echo "Error: ARCH, PLATFORMS, KUBEMACPOOL_IMAGE_TAGGED, and KUBEMACPOOL_IMAGE_GIT_TAGGED must be set."
exit 1
fi

IFS=',' read -r -a PLATFORM_LIST <<< "$PLATFORMS"

# Remove any existing manifest and image
podman manifest rm "${KUBEMACPOOL_IMAGE_TAGGED}" 2>/dev/null || true
podman manifest rm "${KUBEMACPOOL_IMAGE_GIT_TAGGED}" 2>/dev/null || true
podman rmi "${KUBEMACPOOL_IMAGE_TAGGED}" 2>/dev/null || true
podman rmi "${KUBEMACPOOL_IMAGE_GIT_TAGGED}" 2>/dev/null || true

podman manifest create "${KUBEMACPOOL_IMAGE_TAGGED}"

for platform in "${PLATFORM_LIST[@]}"; do
podman build \
--build-arg BUILD_ARCH="$ARCH" \
--platform "$platform" \
--manifest "${KUBEMACPOOL_IMAGE_TAGGED}" \
-f build/Dockerfile .
done
18 changes: 18 additions & 0 deletions hack/build-multiarch-kubemacpool.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash

ARCH=$1
PLATFORMS=$2
KUBEMACPOOL_IMAGE_TAGGED=$3
KUBEMACPOOL_IMAGE_GIT_TAGGED=$4
DOCKER_BUILDER=$5
OCI_BIN=$6

if [ "$OCI_BIN" == "docker" ]; then
ARCH=$ARCH PLATFORMS=$PLATFORMS KUBEMACPOOL_IMAGE_TAGGED=$KUBEMACPOOL_IMAGE_TAGGED KUBEMACPOOL_IMAGE_GIT_TAGGED=$KUBEMACPOOL_IMAGE_GIT_TAGGED DOCKER_BUILDER=$DOCKER_BUILDER ./hack/build-kubemacpool-docker.sh
elif [ "$OCI_BIN" == "podman" ]; then
ARCH=$ARCH PLATFORMS=$PLATFORMS KUBEMACPOOL_IMAGE_TAGGED=$KUBEMACPOOL_IMAGE_TAGGED KUBEMACPOOL_IMAGE_GIT_TAGGED=$KUBEMACPOOL_IMAGE_GIT_TAGGED ./hack/build-kubemacpool-podman.sh
else
echo "Unsupported OCI_BIN value: $OCI_BIN"
exit 1
fi

56 changes: 56 additions & 0 deletions hack/init-buildx.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/bin/bash

check_buildx() {
export DOCKER_CLI_EXPERIMENTAL=enabled

if ! docker buildx > /dev/null 2>&1; then
mkdir -p ~/.docker/cli-plugins
BUILDX_VERSION=$(curl -s https://api.github.com/repos/docker/buildx/releases/latest | jq -r .tag_name)
ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')
curl -L https://github.com/docker/buildx/releases/download/"${BUILDX_VERSION}"/buildx-"${BUILDX_VERSION}".linux-"${ARCH}" --output ~/.docker/cli-plugins/docker-buildx
chmod a+x ~/.docker/cli-plugins/docker-buildx
fi
}

create_or_use_buildx_builder() {
local builder_name=$1
if [ -z "$builder_name" ]; then
echo "Error: Builder name is required."
exit 1
fi

check_buildx

current_builder="$(docker buildx inspect "${builder_name}" 2>/dev/null)" || echo "Builder '${builder_name}' not found"

if ! grep -q "^Driver: docker$" <<<"${current_builder}" && \
grep -q "linux/amd64" <<<"${current_builder}" && \
grep -q "linux/arm64" <<<"${current_builder}" && \
grep -q "linux/s390x" <<<"${current_builder}"; then
echo "The current builder already has multi-architecture support (amd64, arm64, s390x)."
echo "Skipping setup as the builder is already configured correctly."
exit 0
fi

# Check if the builder already exists by parsing the output of `docker buildx ls`
# We check if the builder_name appears in the list of active builders
existing_builder=$(docker buildx ls | grep -w "$builder_name" | awk '{print $1}')

if [ -n "$existing_builder" ]; then
echo "Builder '$builder_name' already exists."
echo "Using existing builder '$builder_name'."
docker buildx use "$builder_name"
else
echo "Creating a new Docker Buildx builder: $builder_name"
docker buildx create --driver-opt network=host --use --name "$builder_name"
echo "The new builder '$builder_name' has been created and set as active."
fi
}

if [ $# -eq 1 ]; then
create_or_use_buildx_builder "$1"
else
echo "Usage: $0 <builder_name>"
echo "Example: $0 mybuilder"
exit 1
fi

0 comments on commit 48f76fe

Please sign in to comment.