Skip to content

Commit 3c7cbaf

Browse files
scripts: change strategy for GNU patch files
1 parent 521bae0 commit 3c7cbaf

File tree

6 files changed

+281
-191
lines changed

6 files changed

+281
-191
lines changed

BUMPING.md

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ This guide is applied for both `metalk8s-operator` and `storage-operator`.
130130

131131
### Prerequisites
132132

133-
- `go` and `curl` in `PATH`.
133+
- `go`, `curl`, and `patch` in `PATH`.
134134
- A GitHub personal access token is optional but strongly recommended: without it,
135135
GitHub API calls are subject to a 60 requests/hour anonymous rate limit. The token
136136
must be **exported** so child processes inherit it:
@@ -201,6 +201,67 @@ After a successful run:
201201
rm -rf operator.bak/ storage-operator.bak/
202202
```
203203

204+
### Patch files
205+
206+
MetalK8s-specific customizations to scaffold-generated files (`Dockerfile`, `Makefile`)
207+
are stored as standard GNU unified diff files in `scripts/patches/<operator>/`:
208+
209+
```
210+
scripts/patches/
211+
operator/
212+
Dockerfile.patch # extra COPY dirs, ldflags, Scality LABEL block
213+
Makefile.patch # GOTOOLCHAIN export, metalk8s make target
214+
storage-operator/
215+
Dockerfile.patch # extra COPY salt/, Scality LABEL block
216+
Makefile.patch # GOTOOLCHAIN export, metalk8s make target
217+
```
218+
219+
The script applies them with `patch -p1` after scaffolding. If a patch does not
220+
apply cleanly (e.g. because the scaffold changed significantly), the script warns
221+
but continues — look for `.rej` files in the operator directory and resolve manually.
222+
223+
#### Placeholders
224+
225+
Patch files use `__PLACEHOLDER__` tokens for values that are only known at runtime.
226+
The script replaces them after applying the patches:
227+
228+
| Placeholder | Replaced with | File |
229+
|---|---|---|
230+
| `__GOTOOLCHAIN__` | Detected Go toolchain (e.g. `go1.25.8`) | `Makefile` |
231+
| `__IMAGE__` | Jinja2 `build_image_name(...)` expression | `Makefile` |
232+
233+
The `FROM golang:X.Y` line in `Dockerfile` and `GOLANGCI_LINT_VERSION` in `Makefile`
234+
are updated by simple regex substitutions (not via patches), since their values change
235+
with every upgrade.
236+
237+
#### How to add or update a patch
238+
239+
Patches are plain `diff -u` output — you can edit them by hand or regenerate them.
240+
To regenerate after modifying an operator customization:
241+
242+
```bash
243+
# 1. Run the upgrade script with --skip-backup to get a fresh scaffold
244+
python3 scripts/upgrade-operator-sdk.py --operator-only --skip-backup --yes
245+
246+
# 2. The script applies existing patches; to start fresh, reset the file:
247+
git checkout operator/Dockerfile
248+
249+
# 3. Make your changes to the scaffold file
250+
vim operator/Dockerfile
251+
252+
# 4. Generate the new patch (a/ b/ prefixes are required for patch -p1)
253+
diff -u <(git show HEAD:operator/Dockerfile) operator/Dockerfile \
254+
| sed '1s|.*|--- a/Dockerfile|;2s|.*|+++ b/Dockerfile|' \
255+
> scripts/patches/operator/Dockerfile.patch
256+
257+
# 5. Verify it applies cleanly
258+
git checkout operator/Dockerfile
259+
patch -p1 --dry-run -d operator < scripts/patches/operator/Dockerfile.patch
260+
```
261+
262+
To add a patch for a new file (e.g. `README.md`), create a new `.patch` file in
263+
the same directory — the script automatically picks up all `*.patch` files.
264+
204265
### Stale compatibility fixes
205266

206267
The `OPERATORS` dict in `scripts/upgrade-operator-sdk.py` contains a `fixes` tuple
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
--- a/Dockerfile
2+
+++ b/Dockerfile
3+
@@ -15,13 +15,20 @@
4+
COPY cmd/main.go cmd/main.go
5+
COPY api/ api/
6+
COPY internal/ internal/
7+
+COPY pkg/ pkg/
8+
+COPY version/ version/
9+
+
10+
+# Version of the project, e.g. `git describe --always --long --dirty --broken`
11+
+ARG METALK8S_VERSION
12+
13+
# Build
14+
# the GOARCH has not a default value to allow the binary be built according to the host where the command
15+
# was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO
16+
# the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore,
17+
# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform.
18+
-RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager cmd/main.go
19+
+RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager \
20+
+ -ldflags "-X 'github.com/scality/metalk8s/operator/version.Version=${METALK8S_VERSION}'" \
21+
+ cmd/main.go
22+
23+
# Use distroless as minimal base image to package the manager binary
24+
# Refer to https://github.com/GoogleContainerTools/distroless for more details
25+
@@ -31,3 +38,40 @@
26+
USER 65532:65532
27+
28+
ENTRYPOINT ["/manager"]
29+
+
30+
+# Timestamp of the build, formatted as RFC3339
31+
+ARG BUILD_DATE
32+
+# Git revision o the tree at build time
33+
+ARG VCS_REF
34+
+# Version of the image
35+
+ARG VERSION
36+
+# Version of the project, e.g. `git describe --always --long --dirty --broken`
37+
+ARG METALK8S_VERSION
38+
+
39+
+# These contain BUILD_DATE so should come 'late' for layer caching
40+
+LABEL maintainer="squad-metalk8s@scality.com" \
41+
+ # http://label-schema.org/rc1/
42+
+ org.label-schema.build-date="$BUILD_DATE" \
43+
+ org.label-schema.name="metalk8s-operator" \
44+
+ org.label-schema.description="Kubernetes Operator for managing MetalK8s cluster config" \
45+
+ org.label-schema.url="https://github.com/scality/metalk8s/" \
46+
+ org.label-schema.vcs-url="https://github.com/scality/metalk8s.git" \
47+
+ org.label-schema.vcs-ref="$VCS_REF" \
48+
+ org.label-schema.vendor="Scality" \
49+
+ org.label-schema.version="$VERSION" \
50+
+ org.label-schema.schema-version="1.0" \
51+
+ # https://github.com/opencontainers/image-spec/blob/master/annotations.md
52+
+ org.opencontainers.image.created="$BUILD_DATE" \
53+
+ org.opencontainers.image.authors="squad-metalk8s@scality.com" \
54+
+ org.opencontainers.image.url="https://github.com/scality/metalk8s/" \
55+
+ org.opencontainers.image.source="https://github.com/scality/metalk8s.git" \
56+
+ org.opencontainers.image.version="$VERSION" \
57+
+ org.opencontainers.image.revision="$VCS_REF" \
58+
+ org.opencontainers.image.vendor="Scality" \
59+
+ org.opencontainers.image.title="metalk8s-operator" \
60+
+ org.opencontainers.image.description="Kubernetes Operator for managing MetalK8s cluster config" \
61+
+ # https://docs.openshift.org/latest/creating_images/metadata.html
62+
+ io.openshift.tags="metalk8s,operator" \
63+
+ io.k8s.description="Kubernetes Operator for managing MetalK8s cluster config" \
64+
+ # Various
65+
+ com.scality.metalk8s.version="$METALK8S_VERSION"
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--- a/Makefile
2+
+++ b/Makefile
3+
@@ -1,5 +1,9 @@
4+
#ENVTEST_K8S_VERSION is the version of Kubernetes to use for setting up ENVTEST binaries (i.e. 1.31)
5+
+
6+
+# Force Go toolchain version to prevent automatic selection issues
7+
+# See: https://go.dev/doc/toolchain
8+
+export GOTOOLCHAIN = __GOTOOLCHAIN__
9+
ENVTEST_K8S_VERSION ?= $(shell go list -m -f "{{ .Version }}" k8s.io/api | awk -F'[v.]' '{printf "1.%d", $$3}')
10+
GOLANGCI_LINT_VERSION ?= v1.0.0
11+
12+
@@ -7,3 +11,9 @@
13+
.PHONY: catalog-push
14+
catalog-push: ## Push a catalog image.
15+
$(MAKE) docker-push IMG=$(CATALOG_IMG)
16+
+
17+
+.PHONY: metalk8s
18+
+metalk8s: manifests kustomize ## Generate MetalK8s resulting manifests
19+
+ mkdir -p deploy
20+
+ $(KUSTOMIZE) build config/metalk8s | \
21+
+ sed 's/BUILD_IMAGE_CLUSTER_OPERATOR:latest/__IMAGE__/' > deploy/manifests.yaml
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
--- a/Dockerfile
2+
+++ b/Dockerfile
3+
@@ -15,6 +15,7 @@
4+
COPY cmd/main.go cmd/main.go
5+
COPY api/ api/
6+
COPY internal/ internal/
7+
+COPY salt/ salt/
8+
9+
# Build
10+
# the GOARCH has not a default value to allow the binary be built according to the host where the command
11+
@@ -31,3 +32,40 @@
12+
USER 65532:65532
13+
14+
ENTRYPOINT ["/manager"]
15+
+
16+
+# Timestamp of the build, formatted as RFC3339
17+
+ARG BUILD_DATE
18+
+# Git revision o the tree at build time
19+
+ARG VCS_REF
20+
+# Version of the image
21+
+ARG VERSION
22+
+# Version of the project, e.g. `git describe --always --long --dirty --broken`
23+
+ARG METALK8S_VERSION
24+
+
25+
+# These contain BUILD_DATE so should come 'late' for layer caching
26+
+LABEL maintainer="squad-metalk8s@scality.com" \
27+
+ # http://label-schema.org/rc1/
28+
+ org.label-schema.build-date="$BUILD_DATE" \
29+
+ org.label-schema.name="storage-operator" \
30+
+ org.label-schema.description="Kubernetes Operator for managing PersistentVolumes in MetalK8s" \
31+
+ org.label-schema.url="https://github.com/scality/metalk8s/" \
32+
+ org.label-schema.vcs-url="https://github.com/scality/metalk8s.git" \
33+
+ org.label-schema.vcs-ref="$VCS_REF" \
34+
+ org.label-schema.vendor="Scality" \
35+
+ org.label-schema.version="$VERSION" \
36+
+ org.label-schema.schema-version="1.0" \
37+
+ # https://github.com/opencontainers/image-spec/blob/master/annotations.md
38+
+ org.opencontainers.image.created="$BUILD_DATE" \
39+
+ org.opencontainers.image.authors="squad-metalk8s@scality.com" \
40+
+ org.opencontainers.image.url="https://github.com/scality/metalk8s/" \
41+
+ org.opencontainers.image.source="https://github.com/scality/metalk8s.git" \
42+
+ org.opencontainers.image.version="$VERSION" \
43+
+ org.opencontainers.image.revision="$VCS_REF" \
44+
+ org.opencontainers.image.vendor="Scality" \
45+
+ org.opencontainers.image.title="storage-operator" \
46+
+ org.opencontainers.image.description="Kubernetes Operator for managing PersistentVolumes in MetalK8s" \
47+
+ # https://docs.openshift.org/latest/creating_images/metadata.html
48+
+ io.openshift.tags="metalk8s,storage,operator" \
49+
+ io.k8s.description="Kubernetes Operator for managing PersistentVolumes in MetalK8s" \
50+
+ # Various
51+
+ com.scality.metalk8s.version="$METALK8S_VERSION"
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--- a/Makefile
2+
+++ b/Makefile
3+
@@ -1,5 +1,9 @@
4+
#ENVTEST_K8S_VERSION is the version of Kubernetes to use for setting up ENVTEST binaries (i.e. 1.31)
5+
+
6+
+# Force Go toolchain version to prevent automatic selection issues
7+
+# See: https://go.dev/doc/toolchain
8+
+export GOTOOLCHAIN = __GOTOOLCHAIN__
9+
ENVTEST_K8S_VERSION ?= $(shell go list -m -f "{{ .Version }}" k8s.io/api | awk -F'[v.]' '{printf "1.%d", $$3}')
10+
GOLANGCI_LINT_VERSION ?= v1.0.0
11+
12+
@@ -7,3 +11,9 @@
13+
.PHONY: catalog-push
14+
catalog-push: ## Push a catalog image.
15+
$(MAKE) docker-push IMG=$(CATALOG_IMG)
16+
+
17+
+.PHONY: metalk8s
18+
+metalk8s: manifests kustomize ## Generate MetalK8s resulting manifests
19+
+ mkdir -p deploy
20+
+ $(KUSTOMIZE) build config/metalk8s | \
21+
+ sed 's/BUILD_IMAGE_CLUSTER_OPERATOR:latest/__IMAGE__/' > deploy/manifests.yaml

0 commit comments

Comments
 (0)