Skip to content
This repository was archived by the owner on Aug 12, 2025. It is now read-only.

Commit 16281e0

Browse files
authored
Merge pull request #76 from packethost/multiarch
add support for building and pushing images per arch and multiarch
2 parents f95ea70 + d4369d3 commit 16281e0

File tree

2 files changed

+72
-6
lines changed

2 files changed

+72
-6
lines changed

.github/workflows/ci.yaml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,17 @@ jobs:
3232
run: make test KUBEBUILDER_DIR=${KUBEBUILDER_DIR}
3333
env:
3434
KUBEBUILDER_ASSETS: ${{ env.KUBEBUILDER_DIR }}/bin
35+
- name: Register binfmt_misc entries for qemu-user-static
36+
run: make register
37+
- name: set buildx cross-builder
38+
run: |
39+
docker buildx create --name cross-builder
40+
docker buildx use cross-builder
41+
docker buildx inspect --bootstrap
42+
- name: check buildx
43+
run: docker buildx ls
3544
- name: image
36-
run: make image KUBEBUILDER_DIR=${KUBEBUILDER_DIR}
45+
run: make image-all KUBEBUILDER_DIR=${KUBEBUILDER_DIR}
3746
env:
3847
KUBEBUILDER_ASSETS: ${{ env.KUBEBUILDER_DIR }}/bin
3948
- name: hub login

Makefile

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ ifneq ($(shell git status --porcelain),)
88
RELEASE_TAG := $(RELEASE_TAG)-next
99
endif
1010

11+
# which arches can we support
12+
ARCHES=arm64 amd64
13+
14+
QEMU_VERSION?=4.2.0-7
15+
QEMU_IMAGE?=multiarch/qemu-user-static:$(QEMU_VERSION)
16+
1117
KUBEBUILDER_VERSION ?= 2.3.1
1218
# default install location for kubebuilder; can be placed elsewhere
1319
KUBEBUILDER_DIR ?= /usr/local/kubebuilder
@@ -56,6 +62,13 @@ BUILD_IMAGE_TAG ?= $(BUILD_IMAGE):latest
5662
PUSH_IMAGE_TAG ?= $(BUILD_IMAGE):$(IMAGETAG)
5763
MANAGER ?= bin/manager-$(OS)-$(ARCH)
5864
KUBECTL ?= kubectl
65+
FROMTAG ?= latest
66+
67+
IMAGENAME ?= $(BUILD_IMAGE):$(IMAGETAG)-$(ARCH)
68+
69+
# Manifest tool, until `docker manifest` is fully ready. As of this writing, it remains experimental
70+
MANIFEST_VERSION ?= 1.0.0
71+
MANIFEST_URL = https://github.com/estesp/manifest-tool/releases/download/v$(MANIFEST_VERSION)/manifest-tool-$(BUILDOS)-$(BUILDARCH)
5972

6073
GO ?= GO111MODULE=on CGO_ENABLED=0 go
6174

@@ -72,6 +85,8 @@ else
7285
GOBIN=$(shell go env GOBIN)
7386
endif
7487

88+
MANIFEST_TOOL ?= $(GOBIN)/manifest-tool
89+
7590
# where we store downloaded core
7691
COREPATH ?= out/core
7792
CORE_VERSION ?= v0.3.5
@@ -126,16 +141,29 @@ ifndef IMAGETAG
126141
$(error IMAGETAG is undefined - run using make <target> IMAGETAG=X.Y.Z)
127142
endif
128143

144+
tag-images-all: $(addprefix sub-tag-image-, $(ARCHES))
145+
sub-tag-image-%:
146+
@$(MAKE) ARCH=$* IMAGETAG=$(IMAGETAG) tag-images
147+
129148
tag-image: imagetag
130149
docker tag $(BUILD_IMAGE_TAG) $(PUSH_IMAGE_TAG)
150+
tag-images: imagetag
151+
docker tag $(BUILD_IMAGE):$(FROMTAG)-$(ARCH) $(IMAGENAME)
131152

132153
confirm:
133154
ifndef CONFIRM
134155
$(error CONFIRM is undefined - run using make <target> CONFIRM=true)
135156
endif
136157

137-
cd: confirm
138-
$(MAKE) tag-image push IMAGETAG=$(GIT_VERSION)
158+
.PHONY: branchname
159+
branchname:
160+
ifndef BRANCH_NAME
161+
$(error BRANCH_NAME is undefined - run using make <target> BRANCH_NAME=var or set an environment variable)
162+
endif
163+
164+
cd: confirm branchname
165+
$(MAKE) tag-images-all push-all push-manifest IMAGETAG=${BRANCH_NAME}
166+
$(MAKE) tag-images-all push-all push-manifest IMAGETAG=${GIT_VERSION}
139167

140168
# needed kubebuilder for tests
141169
kubebuilder: $(KUBEBUILDER)
@@ -193,13 +221,42 @@ vet:
193221
generate: controller-gen
194222
$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..."
195223

196-
# Build the docker image
224+
## make the images for all supported ARCH
225+
image-all: $(addprefix sub-image-, $(ARCHES))
226+
sub-image-%:
227+
@$(MAKE) ARCH=$* image
228+
229+
# Build the docker image for a single arch
197230
image: test
198-
docker build . -t ${IMG}
231+
docker buildx build --load -t $(IMG)-$(ARCH) -f Dockerfile --build-arg ARCH=$(ARCH) --platform $(OS)/$(ARCH) .
232+
echo "Done. image is at $(IMG)-$(ARCH)"
233+
234+
# Targets used when cross building.
235+
.PHONY: register
236+
# Enable binfmt adding support for miscellaneous binary formats.
237+
# This is only needed when running non-native binaries.
238+
register:
239+
docker pull $(QEMU_IMAGE)
240+
docker run --rm --privileged $(QEMU_IMAGE) --reset -p yes || true
241+
242+
.PHONY: manifest-tool
243+
manifest-tool: $(MANIFEST_TOOL)
244+
$(MANIFEST_TOOL):
245+
curl -L -o $@ $(MANIFEST_URL)
246+
chmod +x $@
247+
248+
## push the multi-arch manifest
249+
push-manifest: manifest-tool imagetag
250+
# path to credentials based on manifest-tool's requirements here https://github.com/estesp/manifest-tool#sample-usage
251+
$(GOBIN)/manifest-tool push from-args --platforms $(call join_platforms,$(ARCHES)) --template $(BUILD_IMAGE):$(IMAGETAG)-ARCH --target $(BUILD_IMAGE):$(IMAGETAG)
252+
253+
push-all: imagetag $(addprefix sub-push-, $(ARCHES))
254+
sub-push-%:
255+
@$(MAKE) ARCH=$* push IMAGETAG=$(IMAGETAG)
199256

200257
# Push the docker image
201258
push:
202-
docker push ${IMG}
259+
docker push $(IMAGENAME)
203260

204261
# find or download controller-gen
205262
# download controller-gen if necessary

0 commit comments

Comments
 (0)