Skip to content

Commit 9449c27

Browse files
authored
Add support for arm64 container build (#506)
1 parent 101feae commit 9449c27

File tree

3 files changed

+67
-35
lines changed

3 files changed

+67
-35
lines changed

.github/workflows/publish-docker.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,8 @@ jobs:
6767
uses: docker/build-push-action@v6
6868
with:
6969
context: .
70-
#TODO: Fix linux/arm64 build
71-
platforms: linux/amd64 #,linux/arm64
70+
platforms: linux/amd64 ,linux/arm64
7271
push: ${{ github.event_name != 'pull_request' }}
7372
tags: ${{ steps.meta.outputs.tags }}
7473
labels: ${{ steps.meta.outputs.labels }}
75-
target: ${{ matrix.image.target }}
74+
target: ${{ matrix.image.target }}

Dockerfile

Lines changed: 58 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,78 @@
22
FROM --platform=$BUILDPLATFORM golang:1.23-bookworm AS builder
33

44
WORKDIR /workspace
5+
56
# Copy the Go Modules manifests
6-
COPY go.mod go.mod
7-
COPY go.sum go.sum
8-
# cache deps before building and copying source so that we don't need to re-download as much
9-
# and so that source changes don't invalidate our downloaded layer
7+
COPY go.mod go.sum ./
8+
9+
# Cache dependencies before copying source code
1010
RUN --mount=type=cache,target=/root/.cache/go-build \
1111
--mount=type=cache,target=/go/pkg \
1212
go mod download
1313

14-
# Copy the go source
14+
# Copy the Go source code
1515
COPY api/ api/
1616
COPY internal/ internal/
1717
COPY cmd/ cmd/
1818
COPY hack/ hack/
1919

2020
ARG TARGETOS
2121
ARG TARGETARCH
22+
ARG BUILDPLATFORM
23+
ENV BUILDARCH=${BUILDPLATFORM##*/}
2224

25+
# Install common dependencies
2326
RUN apt-get update && apt-get install -y --no-install-recommends \
24-
qemu-utils ca-certificates libvirt-clients libcephfs-dev librbd-dev librados-dev libc-bin gcc \
27+
qemu-user-static qemu-utils ca-certificates \
28+
libvirt-clients libcephfs-dev librbd-dev librados-dev libc-bin \
29+
gcc g++ \
2530
&& update-ca-certificates \
2631
&& rm -rf /var/lib/apt/lists/*
2732

28-
# Build
29-
RUN --mount=type=cache,target=/root/.cache/go-build \
30-
--mount=type=cache,target=/go/pkg \
31-
CGO_ENABLED=1 GOOS=$TARGETOS GOARCH=$TARGETARCH GO111MODULE=on go build -ldflags="-s -w" -a -o libvirt-provider ./cmd/libvirt-provider/main.go
33+
# Install cross-compiler for ARM64 if building for arm64 on an amd64 host
34+
RUN if [ "$TARGETARCH" = "arm64" ] && [ "$BUILDARCH" = "amd64" ]; then \
35+
dpkg --add-architecture arm64 && \
36+
apt-get update && apt-get install -y --no-install-recommends \
37+
gcc-aarch64-linux-gnu librbd-dev:arm64 librados-dev:arm64 libc6-dev:arm64; \
38+
fi
39+
40+
# Install cross-compiler for AMD64 if building for amd64 on an arm64 host
41+
RUN if [ "$TARGETARCH" = "amd64" ] && [ "$BUILDARCH" = "arm64" ]; then \
42+
apt update && \
43+
apt-get install -y --no-install-recommends \
44+
gcc-x86-64-linux-gnu; \
45+
fi
46+
47+
# Set compiler and linker flags based on target architecture
48+
ENV CC=""
49+
ENV CGO_LDFLAGS=""
50+
51+
RUN if [ "$TARGETARCH" != "$BUILDARCH" ] && [ "$TARGETARCH" = "arm64" ]; then \
52+
export CC="/usr/bin/aarch64-linux-gnu-gcc"; \
53+
export CGO_LDFLAGS="-L/usr/lib/aarch64-linux-gnu -Wl,-lrados -Wl,-lrbd"; \
54+
elif [ "$TARGETARCH" != "$BUILDARCH" ] && [ "$TARGETARCH" = "amd64" ]; then \
55+
export CC="/usr/bin/x86_64-linux-gnu-gcc"; \
56+
export CGO_LDFLAGS="-L/usr/lib/x86_64-linux-gnu -Wl,-lrados -Wl,-lrbd"; \
57+
else \
58+
export CC="/usr/bin/gcc"; \
59+
export CGO_LDFLAGS=""; \
60+
fi && \
61+
CGO_ENABLED=1 GOOS=$TARGETOS GOARCH=$TARGETARCH \
62+
CC="$CC" CGO_LDFLAGS="$CGO_LDFLAGS" \
63+
go build -ldflags="-s -w -linkmode=external" -o libvirt-provider ./cmd/libvirt-provider/main.go
3264

3365
# Install irictl-machine
3466
RUN --mount=type=cache,target=/root/.cache/go-build \
3567
--mount=type=cache,target=/go/pkg \
36-
CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH GO111MODULE=on go install github.com/ironcore-dev/ironcore/irictl-machine/cmd/irictl-machine@main
68+
CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH GO111MODULE=on \
69+
go install github.com/ironcore-dev/ironcore/irictl-machine/cmd/irictl-machine@main
70+
71+
# Ensure the binary is in a common location
72+
RUN if [ "$TARGETARCH" = "$BUILDARCH" ]; then \
73+
mv /go/bin/irictl-machine /workspace/irictl-machine; \
74+
else \
75+
mv /go/bin/linux_$TARGETARCH/irictl-machine /workspace/irictl-machine; \
76+
fi
3777

3878
# Since we're leveraging apt to pull in dependencies, we use `gcr.io/distroless/base` because it includes glibc.
3979
FROM gcr.io/distroless/base-debian11 AS distroless-base
@@ -42,12 +82,15 @@ FROM gcr.io/distroless/base-debian11 AS distroless-base
4282
FROM distroless-base AS distroless-amd64
4383
ENV LIB_DIR_PREFIX=x86_64
4484
ENV LIB_DIR_PREFIX_MINUS=x86-64
85+
ENV LIB_DIR_SUFFIX_NUMBER=2
86+
ENV LIB_DIR=lib64
4587

4688
# The distroless arm64 image has a target triplet of aarch64
4789
FROM distroless-base AS distroless-arm64
4890
ENV LIB_DIR_PREFIX=aarch64
4991
ENV LIB_DIR_PREFIX_MINUS=aarch64
50-
92+
ENV LIB_DIR_SUFFIX_NUMBER=1
93+
ENV LIB_DIR=lib
5194

5295
FROM busybox:1.37.0-uclibc AS busybox
5396
FROM distroless-$TARGETARCH AS libvirt-provider
@@ -84,14 +127,14 @@ COPY --from=builder /lib/${LIB_DIR_PREFIX}-linux-gnu/librados.so.2 \
84127
/lib/${LIB_DIR_PREFIX}-linux-gnu/libselinux.so.1 \
85128
/lib/${LIB_DIR_PREFIX}-linux-gnu/libpthread.so.0 \
86129
/lib/${LIB_DIR_PREFIX}-linux-gnu/libpcre2-8.so.0 /lib/${LIB_DIR_PREFIX}-linux-gnu/
87-
RUN mkdir -p /lib64
88-
COPY --from=builder /lib64/ld-linux-${LIB_DIR_PREFIX_MINUS}.so.2 /lib64/
130+
RUN mkdir -p /${LIB_DIR}
131+
COPY --from=builder /${LIB_DIR}/ld-linux-${LIB_DIR_PREFIX_MINUS}.so.${LIB_DIR_SUFFIX_NUMBER} /${LIB_DIR}/
89132
RUN mkdir -p /usr/lib/${LIB_DIR_PREFIX}-linux-gnu/ceph/
90133
COPY --from=builder /usr/lib/${LIB_DIR_PREFIX}-linux-gnu/ceph/libceph-common.so.2 /usr/lib/${LIB_DIR_PREFIX}-linux-gnu/ceph
91134
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
92135

93136
COPY --from=builder /workspace/libvirt-provider /libvirt-provider
94-
COPY --from=builder /go/bin/irictl-machine /irictl-machine
137+
COPY --from=builder /workspace/irictl-machine /irictl-machine
95138

96139
USER 65532:65532
97140

Makefile

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,9 @@ ENVTEST_K8S_VERSION = 1.28
77
# Docker image name for the mkdocs based local development setup
88
MKDOCS_IMG=onmetal/libvirt-provider-docs
99

10-
# Code depend on OS
11-
TARGET_OS ?= linux
12-
TARGET_ARCH ?= amd64
13-
CGO_ENABLED ?= 1
14-
1510
LIBVIRT_PROVIDER_BIN=$(LOCALBIN)/libvirt-provider
1611
LIBVIRT_PROVIDER_BIN_SOURCE=./cmd/libvirt-provider
1712

18-
GITHUB_PAT_PATH ?=
19-
ifeq (,$(GITHUB_PAT_PATH))
20-
GITHUB_PAT_MOUNT ?=
21-
else
22-
GITHUB_PAT_MOUNT ?= --secret id=github_pat,src=$(GITHUB_PAT_PATH)
23-
endif
24-
2513
# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
2614
ifeq (,$(shell go env GOBIN))
2715
GOBIN=$(shell go env GOPATH)/bin
@@ -35,6 +23,8 @@ endif
3523
# tools. (i.e. podman)
3624
CONTAINER_TOOL ?= docker
3725

26+
TARGET_OS ?= linux
27+
TARGET_ARCH ?= $(shell uname -m)
3828
CONTAINER_BUILDARGS ?= --platform $(TARGET_OS)/$(TARGET_ARCH)
3929

4030
# Setting SHELL to bash allows bash commands to be executed by recipes.
@@ -86,15 +76,15 @@ fmt: ## Run go fmt against code.
8676

8777
.PHONY: vet
8878
vet: ## Run go vet against code.
89-
GOOS=$(TARGET_OS) CGO_ENABLED=$(CGO_ENABLED) go vet ./...
79+
go vet ./...
9080

9181
.PHONY: lint
9282
lint: golangci-lint ## Run golangci-lint against code.
93-
GOOS=$(TARGET_OS) CGO_ENABLED=$(CGO_ENABLED) $(GOLANGCI_LINT) run
83+
CGO_ENABLED=1 $(GOLANGCI_LINT) run
9484

9585
.PHONY: lint-fix
9686
lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes
97-
GOOS=$(TARGET_OS) CGO_ENABLED=$(CGO_ENABLED) $(GOLANGCI_LINT) run --fix
87+
CGO_ENABLED=1 $(GOLANGCI_LINT) run --fix
9888

9989
.PHONY: check
10090
check: manifests generate fmt check-license lint test ## Generate manifests, code, lint, check licenses, test
@@ -122,7 +112,7 @@ clean-docs: ## Remove all local mkdocs Docker images (cleanup).
122112

123113
.PHONY: build
124114
build: manifests generate fmt vet add-license lint ## Build the binary
125-
GOOS=$(TARGET_OS) GOARCH=$(TARGET_ARCH) CGO_ENABLED=$(CGO_ENABLED) go build -o $(LIBVIRT_PROVIDER_BIN) $(LIBVIRT_PROVIDER_BIN_SOURCE)
115+
CGO_ENABLED=1 go build -o $(LIBVIRT_PROVIDER_BIN) $(LIBVIRT_PROVIDER_BIN_SOURCE)
126116

127117
.PHONY: run
128118
run: manifests generate fmt vet ## Run the binary
@@ -133,7 +123,7 @@ run: manifests generate fmt vet ## Run the binary
133123

134124
.PHONY: docker-build
135125
docker-build: ## Build docker image with partitionlet
136-
$(CONTAINER_TOOL) build $(CONTAINER_BUILDARGS) -t ${IMG} $(GITHUB_PAT_MOUNT) .
126+
$(CONTAINER_TOOL) build $(CONTAINER_BUILDARGS) -t ${IMG} .
137127

138128
.PHONY: docker-push
139129
docker-push: ## Push docker image with the manager.

0 commit comments

Comments
 (0)