Skip to content

Commit a2911cd

Browse files
Merge pull request #24 from ThinkParQ/iamjoemccormick/add-multi-architecture-builds
Add support for multiarch builds (amd64 and arm64)
2 parents 4418dfe + 226f3bd commit a2911cd

20 files changed

+861
-283
lines changed

.github/workflows/build-test-publish.yaml

Lines changed: 163 additions & 144 deletions
Large diffs are not rendered by default.

Dockerfile

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,44 @@
11
# Modifications Copyright 2021 NetApp, Inc. All Rights Reserved.
2+
# Modifications Copyright 2024 ThinkParQ, GmbH. All Rights Reserved.
23
# Licensed under the Apache License, Version 2.0.
34

45
# Use distroless as minimal base image to package the driver binary. Refer to
56
# https://github.com/GoogleContainerTools/distroless for more details.
6-
FROM gcr.io/distroless/static:latest
7-
7+
FROM --platform=$TARGETPLATFORM gcr.io/distroless/static:latest
88
LABEL maintainers="ThinkParQ"
99
LABEL description="BeeGFS CSI Driver"
1010
LABEL org.opencontainers.image.description="BeeGFS CSI Driver"
1111
LABEL org.opencontainers.image.source="https://github.com/ThinkParQ/beegfs-csi-driver"
1212
LABEL org.opencontainers.image.licenses="Apache-2.0"
1313

14-
# Copy all built binaries to netapp/ directory.
15-
COPY bin/beegfs-csi-driver bin/chwrap netapp/
14+
# Multi-arch images can be built from this Dockerfile. When the container image is built it is
15+
# expected binaries and a chwrap tar file were already created under bin/ using Make. By default
16+
# calling Make with no arguments builds these files for the current architecture with no suffix
17+
# allowing the container image to be built without multiarch support by default.
18+
#
19+
# If Make is called with the `BUILD_PLATFORMS` build argument, then binaries and chwrap tar files
20+
# will be generated for each platform with an architecture suffix. These can then be used to build a
21+
# multiarch container image using `docker buildx build` by specifying the same list of platforms
22+
# using the `--platform` flag. Note the buildx flag and BUILD_PLATFORMS argument accept slightly
23+
# different values, for example to build for both amd64 and arm64:
24+
#
25+
# `make BUILD_PLATFORMS="linux amd64 amd64 amd64;linux arm64 arm64 arm64" all`
26+
# `docker buildx build --platform=linux/amd64,linux/arm64`
27+
ARG TARGETARCH
28+
# Work around the fact TARGETARCH is not set consistently when building multiarch images using
29+
# release-tools versus docker buildx. While release-tools isn't currently used by GitHub Actions to
30+
# publish multiarch images, this is the only thing preventing use of release-tools, which may be
31+
# useful for local testing.
32+
ARG ARCH=$TARGETARCH
33+
WORKDIR /
34+
35+
# Copy architecture specific BeeGFS CSI driver to the image.
36+
COPY bin/beegfs-csi-driver$ARCH /beegfs-csi-driver
1637

17-
# Add chwrap symbolic links to netapp/ directory.
18-
ADD bin/chwrap.tar /
38+
# Unpack architecture specific chwrap symbolic links into osutils directory.
39+
ADD bin/chwrap$ARCH.tar /
1940

2041
# Call chwrap linked binaries before container installed binaries.
21-
ENV PATH "/netapp:/$PATH"
42+
ENV PATH "/osutils:$PATH"
2243

23-
ENTRYPOINT ["beegfs-csi-driver"]
44+
ENTRYPOINT ["/beegfs-csi-driver"]

Makefile

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@
1515
# limitations under the License.
1616

1717
# Modifications Copyright 2021 NetApp, Inc. All Rights Reserved.
18+
# Modifications Copyright 2024 ThinkParQ, GmbH. All Rights Reserved.
1819
# Licensed under the Apache License, Version 2.0.
1920

2021
CMDS ?= beegfs-csi-driver
2122
# Speed up unit testing by explicitly NOT building anything in the e2e folder.
2223
# Do not run any operator tests during normal testing.
2324
TEST_GO_FILTER_CMD = -e '/test/e2e' -e '/operator'
24-
all: build
25+
all: build build-chwrap bin/chwrap.tar
2526

2627
check-go-version:
2728
./hack/check-go-version.sh
@@ -36,7 +37,7 @@ generate-notices:
3637
build-%: check-go-version-go
3738
# Commands are taken directly from build.make build-%.
3839
mkdir -p bin
39-
echo '$(BUILD_PLATFORMS)' | tr ';' '\n' | while read -r os arch suffix; do \
40+
echo '$(BUILD_PLATFORMS)' | tr ';' '\n' | while read -r os arch buildx_platform suffix base_image addon_image; do \
4041
if ! (set -x; CGO_ENABLED=0 GOOS="$$os" GOARCH="$$arch" go build $(GOFLAGS_VENDOR) -a -ldflags \
4142
'$(FULL_LDFLAGS)' -o "./bin/$*$$suffix" ./cmd/$*); then \
4243
echo "Building $* for GOOS=$$os GOARCH=$$arch failed, see error(s) above."; \
@@ -46,14 +47,22 @@ build-%: check-go-version-go
4647

4748
# Put symbolic links between various commands (e.g. beegfs-ctl, mount, and umount) and cmd/chwrap into a .tar file to
4849
# be unpacked in the container. chwrap.tar is obviously not a binary file, but bin/ is where release-tools/build.make
49-
# outputs files and it is cleaned out on "make clean".
50+
# outputs files and it is cleaned out on "make clean". If we BUILD_PLATFORMS is set then we will create multiple tar
51+
# files each suffixed with the appropriate architecture. Otherwise we will create a single tar file with no suffix
52+
# for the current architecture.
5053
bin/chwrap.tar: build-chwrap cmd/chwrap/chwrap.sh
51-
cmd/chwrap/chwrap.sh bin/chwrap bin/chwrap.tar
54+
echo '$(BUILD_PLATFORMS)' | tr ';' '\n' | while read -r os arch buildx_platform suffix base_image addon_image; do \
55+
if ! (set -x; cmd/chwrap/chwrap.sh bin/chwrap$$arch bin/chwrap$$arch.tar osutils); then \
56+
echo "Building $* for $$arch failed, see error(s) above."; \
57+
exit 1; \
58+
fi; \
59+
done
5260

53-
# The beegfs-csi-driver container requires chwrap to be built and included, so we build it anytime container or push
54-
# are made. Additional prerequisites and the recipes for container and push are defined in release-tools/build.make. A
55-
# different workaround will likely be required for multiarch builds.
61+
# The beegfs-csi-driver container requires chwrap to be built and included, so we build it anytime
62+
# container, push, or push-multiarch are made. Additional prerequisites and the recipes for
63+
# container and push are defined in release-tools/build.make.
5664
container: build-chwrap bin/chwrap.tar
65+
push-multiarch: build-chwrap bin/chwrap.tar
5766
push: container # not explicitly executed in release-tools/build.make
5867

5968
# For details on what licenses are disallowed see

cmd/chwrap/chwrap.sh

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,16 @@
44

55
# Copyright 2020 NetApp, Inc. All Rights Reserved.
66
# Modifications Copyright 2021 NetApp, Inc. All Rights Reserved.
7+
# Modifications Copyright 2024 ThinkParQ, GmbH. All Rights Reserved.
78
# Licensed under the Apache License, Version 2.0.
89

9-
[ -n "$1" ] && [ -n "$2" ] || exit 1
10+
[ -n "$1" ] && [ -n "$2" ] && [ -n "$3" ] || exit 1
1011

1112
PREFIX=/tmp/$(uuidgen)
12-
mkdir -p $PREFIX/netapp
13-
cp "$1" $PREFIX/netapp/chwrap
13+
mkdir -p $PREFIX/$3
14+
cp "$1" $PREFIX/$3/chwrap
1415
for BIN in beegfs-ctl lsmod modprobe mount touch umount; do
15-
ln -s chwrap $PREFIX/netapp/$BIN
16+
ln -s chwrap $PREFIX/$3/$BIN
1617
done
17-
tar --owner=0 --group=0 -C $PREFIX -cf "$2" netapp
18+
tar --owner=0 --group=0 -C $PREFIX -cf "$2" $3
1819
rm -rf $PREFIX

operator/Dockerfile

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,31 @@
66

77
# Use distroless as minimal base image to package the manager binary. Refer to
88
# https://github.com/GoogleContainerTools/distroless for more details.
9-
FROM gcr.io/distroless/static:nonroot
9+
FROM --platform=$TARGETPLATFORM gcr.io/distroless/static:nonroot
10+
LABEL maintainers="ThinkParQ"
11+
LABEL description="BeeGFS CSI Driver Operator"
1012
LABEL org.opencontainers.image.description="BeeGFS CSI Driver Operator"
1113
LABEL org.opencontainers.image.source="https://github.com/ThinkParQ/beegfs-csi-driver/operator"
1214
LABEL org.opencontainers.image.licenses="Apache-2.0"
15+
16+
# Multi-arch images can be built from this Dockerfile. When the container image is built it is
17+
# expected the controller binary was already created and exists bin/ using Make. By default calling
18+
# Make with no arguments builds these files for the current architecture with no suffix allowing the
19+
# container image to be built without multiarch support by default.
20+
#
21+
# If Make is called with the `BUILD_PLATFORMS` build argument, a controller binary will be
22+
# compiled for each platform with an architecture suffix. These can then be used to build a
23+
# multiarch container image using `docker buildx build` by specifying the same list of platforms
24+
# using the `--platform` flag. Note the buildx flag and BUILD_PLATFORMS argument accept slightly
25+
# different values, for example to build for both amd64 and arm64:
26+
#
27+
# `make BUILD_PLATFORMS="linux amd64 amd64 amd64;linux arm64 arm64 arm64" all`
28+
# `docker buildx build --platform=linux/amd64,linux/arm64`
29+
ARG TARGETARCH
1330
WORKDIR /
14-
COPY bin/manager .
31+
32+
# Copy architecture specific manager to the image.
33+
COPY bin/manager$TARGETARCH /manager
1534
USER 65532:65532
1635

1736
ENTRYPOINT ["/manager"]

operator/Makefile

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55
# - use environment variables to overwrite this value (e.g export VERSION=0.0.2)
66
VERSION ?= 1.5.0
77

8+
# BUILD_PLATFORMS contains a set of tuples [os arch buildx_platform suffix base_image addon_image]
9+
# separated by semicolon. An empty variable or empty entry (= just a
10+
# semicolon) builds for the default platform of the current Go
11+
# toolchain. This approach was adapted from the CSI driver release-tools.1
12+
BUILD_PLATFORMS =
13+
814
# CHANNELS define the bundle channels used in the bundle.
915
# Add a new line here if you would like to change its default config. (E.g CHANNELS = "candidate,fast,stable")
1016
# To re-generate a bundle for other specific channels without changing the standard setup, you can:
@@ -110,15 +116,24 @@ test: manifests generate fmt vet envtest ## Run tests.
110116
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test -v ./... -coverprofile cover.out
111117

112118
##@ Build
113-
114119
.PHONY: build
115120
build: generate fmt vet ## Build manager binary.
116-
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o bin/manager main.go
121+
mkdir -p bin
122+
echo '$(BUILD_PLATFORMS)' | tr ';' '\n' | while read -r os arch buildx_platform suffix base_image addon_image; do \
123+
if ! (set -x; CGO_ENABLED=0 GOOS="$$os" GOARCH="$$arch" go build $(GOFLAGS_VENDOR) -a -ldflags \
124+
'$(FULL_LDFLAGS)' -o "./bin/manager$$suffix" main.go); then \
125+
echo "Building manager for GOOS=$$os GOARCH=$$arch failed, see error(s) above."; \
126+
exit 1; \
127+
fi; \
128+
done
117129

118130
.PHONY: run
119131
run: manifests generate fmt vet ## Run a controller from your host.
120132
go run ./main.go --zap-devel=true --zap-log-level=5
121133

134+
# Note the Makefile doesn't build multiarch images (only the current architecture).
135+
# Multiarch images are currently built/published using GitHub actions or manually.
136+
122137
.PHONY: docker-build
123138
docker-build: test ## Build docker image with the manager.
124139
docker build -t ${IMG} .
@@ -249,9 +264,14 @@ PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le
249264
.PHONY: docker-buildx
250265
docker-buildx: test ## Build and push docker image for the manager for cross-platform support
251266
# copy existing Dockerfile and insert --platform=${BUILDPLATFORM} into Dockerfile.cross, and preserve the original Dockerfile
252-
sed -e '1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' Dockerfile > Dockerfile.cross
253-
- docker buildx create --name project-v3-builder
254-
docker buildx use project-v3-builder
255-
- docker buildx build --push --platform=$(PLATFORMS) --tag ${IMG} -f Dockerfile.cross
256-
- docker buildx rm project-v3-builder
257-
rm Dockerfile.cross
267+
# sed -e '1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' Dockerfile > Dockerfile.cross
268+
# - docker buildx create --name project-v3-builder
269+
# docker buildx use project-v3-builder
270+
# - docker buildx build --push --platform=$(PLATFORMS) --tag ${IMG} -f Dockerfile.cross
271+
# - docker buildx rm project-v3-builder
272+
# rm Dockerfile.cross
273+
# This has not been updated to work with how we build multiarch images using GitHub actions.
274+
# Fail the target to prevent accidental usage.
275+
@echo "Using the docker-buildx target is not currently supported"
276+
@exit 1
277+

operator/docs/developer-docs.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,9 @@ chmod +x install.sh
333333
* All prerequisites for the BeeGFS CSI driver must be installed on your
334334
Kubernetes nodes. If you are using Minikube there is a script to do this at
335335
`hack/minikube_install_driver_prerequisites.sh`.
336+
* You must also provide Minikube its own base client configuration file. For example you might
337+
bind mount /etc/beegfs from the host OS into the Minikube container using `minikube mount
338+
/etc/beegfs:/etc/beegfs` (note the command must stay running for the mount to stay active).
336339

337340
Steps:
338341

operator/hack/minikube_install_driver_prerequisites.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/bin/bash
22
set -euo pipefail
33

4-
export BEEGFS_VERSION=7.3.4
4+
export BEEGFS_VERSION=7.4.2
55

66
# Install the BeeGFS beegfs-ctl tool into the Minikube container:
77
minikube ssh "sudo apt-get update"

release-tools/KUBERNETES_CSI_OWNERS_ALIASES

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,24 @@ aliases:
1818
# when they are temporarily unable to review PRs.
1919
kubernetes-csi-reviewers:
2020
- andyzhangx
21+
- carlory
2122
- chrishenzie
2223
- ggriffiths
2324
- gnufied
2425
- humblec
26+
- mauriciopoppe
2527
- j-griffith
26-
- Jiawei0227
2728
- jingxu97
2829
- jsafrane
2930
- pohly
31+
- RaunakShah
32+
- sunnylovestiramisu
3033
- xing-yang
3134

3235
# This documents who previously contributed to Kubernetes-CSI
3336
# as approver.
3437
emeritus_approvers:
38+
- Jiawei0227
3539
- lpabon
3640
- sbezverk
3741
- vladimirvivien

release-tools/SIDECAR_RELEASE_PROCESS.md

Lines changed: 45 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ The release manager must:
1717
Whenever a new Kubernetes minor version is released, our kubernetes-csi CI jobs
1818
must be updated.
1919

20-
[Our CI jobs](https://k8s-testgrid.appspot.com/sig-storage-csi-ci) have the
20+
[Our CI jobs](https://testgrid.k8s.io/sig-storage-csi-ci) have the
2121
naming convention `<hostpath-deployment-version>-on-<kubernetes-version>`.
2222

2323
1. Jobs should be actively monitored to find and fix failures in sidecars and
@@ -46,63 +46,59 @@ naming convention `<hostpath-deployment-version>-on-<kubernetes-version>`.
4646
## Release Process
4747
1. Identify all issues and ongoing PRs that should go into the release, and
4848
drive them to resolution.
49-
1. Download the latest version of the
50-
[K8s release notes generator](https://github.com/kubernetes/release/tree/HEAD/cmd/release-notes)
51-
1. Create a
52-
[Github personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token)
53-
with `repo:public_repo` access
54-
1. Generate release notes for the release. Replace arguments with the relevant
55-
information.
56-
* Clean up old cached information (also needed if you are generating release
57-
notes for multiple repos)
58-
```bash
59-
rm -rf /tmp/k8s-repo
60-
```
61-
* For new minor releases on master:
62-
```bash
63-
GITHUB_TOKEN=<token> release-notes \
64-
--discover=mergebase-to-latest \
65-
--org=kubernetes-csi \
66-
--repo=external-provisioner \
67-
--required-author="" \
68-
--markdown-links \
69-
--output out.md
70-
```
71-
* For new patch releases on a release branch:
72-
```bash
73-
GITHUB_TOKEN=<token> release-notes \
74-
--discover=patch-to-latest \
75-
--branch=release-1.1 \
76-
--org=kubernetes-csi \
77-
--repo=external-provisioner \
78-
--required-author="" \
79-
--markdown-links \
80-
--output out.md
81-
```
82-
1. Compare the generated output to the new commits for the release to check if
83-
any notable change missed a release note.
84-
1. Reword release notes as needed. Make sure to check notes for breaking
85-
changes and deprecations.
86-
1. If release is a new major/minor version, create a new `CHANGELOG-<major>.<minor>.md`
87-
file. Otherwise, add the release notes to the top of the existing CHANGELOG
88-
file for that minor version.
89-
1. Submit a PR for the CHANGELOG changes.
90-
1. Submit a PR for README changes, in particular, Compatibility, Feature status,
91-
and any other sections that may need updating.
49+
1. Update dependencies for sidecars via
50+
[go-modules-update.sh](https://github.com/kubernetes-csi/csi-driver-host-path/blob/HEAD/release-tools/go-modules-update.sh),
51+
and get PRs approved and merged.
9252
1. Check that all [canary CI
93-
jobs](https://k8s-testgrid.appspot.com/sig-storage-csi-ci) are passing,
53+
jobs](https://testgrid.k8s.io/sig-storage-csi-ci) are passing,
9454
and that test coverage is adequate for the changes that are going into the release.
55+
1. Check that the post-\<sidecar\>-push-images builds are succeeding.
56+
[Example](https://testgrid.k8s.io/sig-storage-image-build#post-external-snapshotter-push-images)
57+
1. Generate release notes.
58+
1. Download the latest version of the [K8s release notes generator](https://github.com/kubernetes/release/tree/HEAD/cmd/release-notes)
59+
1. Create a
60+
[Github personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token)
61+
with `repo:public_repo` access
62+
1. For patch release, use the script generate_patch_release_notes.sh. Read the instructions at the top of the
63+
script. The script also creates PRs for each branch.
64+
1. For new minor releases, follow these steps and replace arguments with the relevant
65+
information.
66+
* Clean up old cached information (also needed if you are generating release
67+
notes for multiple repos)
68+
```bash
69+
rm -rf /tmp/k8s-repo
70+
```
71+
* For new minor releases on master:
72+
```bash
73+
GITHUB_TOKEN=<token> release-notes \
74+
--discover=mergebase-to-latest \
75+
--org=kubernetes-csi \
76+
--repo=external-provisioner \
77+
--required-author="" \
78+
--markdown-links \
79+
--output out.md
80+
```
81+
1. Compare the generated output to the new commits for the release to check if
82+
any notable change missed a release note.
83+
1. Reword release notes as needed, ideally in the original PRs so that the
84+
release notes can be regnerated. Make sure to check notes for breaking
85+
changes and deprecations.
86+
1. If release is a new major/minor version, create a new `CHANGELOG-<major>.<minor>.md`
87+
file.
88+
1. Submit a PR for the CHANGELOG changes.
89+
1. Submit a PR for README changes, in particular, Compatibility, Feature status,
90+
and any other sections that may need updating.
9591
1. Make sure that no new PRs have merged in the meantime, and no PRs are in
9692
flight and soon to be merged.
9793
1. Create a new release following a previous release as a template. Be sure to select the correct
9894
branch. This requires Github release permissions as required by the prerequisites.
9995
[external-provisioner example](https://github.com/kubernetes-csi/external-provisioner/releases/new)
10096
1. If release was a new major/minor version, create a new `release-<minor>`
10197
branch at that commit.
102-
1. Check [image build status](https://k8s-testgrid.appspot.com/sig-storage-image-build).
103-
1. Promote images from k8s-staging-sig-storage to k8s.gcr.io/sig-storage. From
98+
1. Check [image build status](https://testgrid.k8s.io/sig-storage-image-build).
99+
1. Promote images from k8s-staging-sig-storage to registry.k8s.io/sig-storage. From
104100
the [k8s image
105-
repo](https://github.com/kubernetes/k8s.io/tree/HEAD/k8s.gcr.io/images/k8s-staging-sig-storage),
101+
repo](https://github.com/kubernetes/k8s.io/tree/HEAD/registry.k8s.io/images/k8s-staging-sig-storage),
106102
run `./generate.sh > images.yaml`, and send a PR with the updated images.
107103
Once merged, the image promoter will copy the images from staging to prod.
108104
1. Update [kubernetes-csi/docs](https://github.com/kubernetes-csi/docs) sidecar
@@ -118,7 +114,7 @@ naming convention `<hostpath-deployment-version>-on-<kubernetes-version>`.
118114

119115
The following jobs are triggered after tagging to produce the corresponding
120116
image(s):
121-
https://k8s-testgrid.appspot.com/sig-storage-image-build
117+
https://testgrid.k8s.io/sig-storage-image-build
122118

123119
Clicking on a failed build job opens that job in https://prow.k8s.io. Next to
124120
the job title is a rerun icon (circle with arrow). Clicking it opens a popup

0 commit comments

Comments
 (0)