Skip to content

Commit 7a788d6

Browse files
authored
Rework how we apply patches to upstream sources (#4125)
1 parent 8a28e8e commit 7a788d6

18 files changed

Lines changed: 647 additions & 59 deletions

build-scripts/build-component.sh

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,6 @@ DIR=`realpath $(dirname "${0}")`
77
BUILD_DIRECTORY="${SNAPCRAFT_PART_BUILD:-${DIR}/.build}"
88
INSTALL_DIRECTORY="${SNAPCRAFT_PART_INSTALL:-${DIR}/.install}"
99

10-
STRICT="${STRICT:-false}"
11-
if [ "x${STRICT}" == "xfalse" ]; then
12-
PROJECT_DIR="${SNAPCRAFT_PROJECT_DIR:-${DIR}/..}"
13-
if cat "${PROJECT_DIR}/snap/snapcraft.yaml" | grep "confinement:" | grep strict > /dev/null; then
14-
STRICT="true"
15-
fi
16-
fi
17-
1810
mkdir -p "${BUILD_DIRECTORY}" "${INSTALL_DIRECTORY}"
1911

2012
COMPONENT_NAME="${1}"
@@ -46,23 +38,8 @@ if [ -e "${COMPONENT_DIRECTORY}/pre-patch.sh" ]; then
4638
bash -xe "${COMPONENT_DIRECTORY}/pre-patch.sh"
4739
fi
4840

49-
if echo "${GIT_TAG}" | grep -e rc -e alpha -e beta; then
50-
if [ -d "${COMPONENT_DIRECTORY}/pre-patches" ]; then
51-
for patch in "${COMPONENT_DIRECTORY}"/pre-patches/*; do
52-
git am < "${patch}"
53-
done
54-
fi
55-
else
56-
if [ -d "${COMPONENT_DIRECTORY}/patches" ]; then
57-
for patch in "${COMPONENT_DIRECTORY}"/patches/*; do
58-
git am < "${patch}"
59-
done
60-
fi
61-
fi
62-
if [ "x${STRICT}" == "xtrue" ] && [ -d "${COMPONENT_DIRECTORY}/strict-patches" ]; then
63-
for patch in "${COMPONENT_DIRECTORY}"/strict-patches/*; do
64-
git am < "${patch}"
65-
done
66-
fi
41+
for patch in $(python3 "${DIR}/print-patches-for.py" "${COMPONENT_NAME}" "${GIT_TAG}"); do
42+
git am "${patch}"
43+
done
6744

6845
bash -xe "${COMPONENT_DIRECTORY}/build.sh" "${INSTALL_DIRECTORY}" "${GIT_TAG}"

build-scripts/components/README.md

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,62 @@ build-scripts/
2020
binaries should be placed, second is the component version
2121
pre-patch.sh <-- runs as `pre-patch.sh`. takes any action needed before applying
2222
the component patches
23-
patches/
24-
... <-- list of patches to apply after checkout (for stable versions)
25-
pre-patches/
26-
... <-- list of patches to apply after checkout (for pre-releases)
27-
strict-patches/
28-
... <-- list of patches to apply when building strictly confined snap
23+
patches/ <-- list of patches to apply after checkout (see section below)
24+
...
25+
strict-patches/ <-- list of extra patches to apply when building strictly confined snap
26+
...
2927
```
28+
29+
## Applying patches
30+
31+
Most MicroK8s components are retrieved from an upstream source (specified in the `repository`), with a specific tag (specified in `version.sh`), have some patches applied to them (from the `patches/` and `strict-patches/` directories) and are then built (using `build.sh`).
32+
33+
34+
This section explains the directory format for the `patches` and `strict-patches` directories. The same rules apply for both. Note that the `strict-patches` (if any) are applied **after** any `patches` have been applied.
35+
36+
Our patches do not frequently change between versions, but they do have to be rebased from time to time, which breaks compatibility with older versions. For that reason, we maintain a set of patches for each version that introduces a breaking change. Consider the following directory structure for the Kubernetes component.
37+
38+
```
39+
patches/default/0.patch
40+
patches/v1.27.0/a.patch
41+
patches/v1.27.0/b.patch
42+
patches/v1.27.4/c.patch
43+
patches/v1.28.0/d.patch
44+
patches/v1.28.0-beta.0/e.patch
45+
```
46+
47+
The Kubernetes version to build may be decided dynamically while building the snap, or be pinned to a specified version. The following table shows which patches we would apply depending on the Kubernetes version that we build:
48+
49+
| Kubernetes version | Applied patches | Explanation |
50+
| ------------------ | ----------------------- | ------------------------------------------------------------------------------------------ |
51+
| `v1.27.0` | `a.patch` and `b.patch` | |
52+
| `v1.27.1` | `a.patch` and `b.patch` | In case there is no exact match, find the most recent older version |
53+
| `v1.27.4` | `c.patch` | Older patches are not applied |
54+
| `v1.27.12` | `c.patch` | In semver, `v1.27.12 > v1.27.4` so we again must get the most recent patches |
55+
| `v1.28.0-rc.0` | `d.patch` | Extra items from semver are ignored, so we can define the `v1.28.0` patch and be done |
56+
| `v1.28.0-beta.0` | `e.patch` | Extra items from semver are ignored, but due to exact match this patch is used instead |
57+
| `v1.28.0` | `d.patch` | Extra items from semver are ignored, so we can define the `v1.28.0` patch and be done |
58+
| `v1.28.4` | `d.patch` | Picks the patches from the stable versions only, not from beta |
59+
| `v1.29.1` | `d.patch` | Uses patches from most recent version, even if on a different minor |
60+
| `hack/branch` | `0.patch` | If not semver and no match, any patches from the `default/` directory are applied (if any) |
61+
62+
Same logic applies for all other components as well.
63+
64+
### Testing which patches would be applied
65+
66+
You can verify which set of patches would be applied in any case using the `print-patches-for.py` script directly:
67+
68+
```bash
69+
$ ./build-scripts/print-patches-for.py kubernetes v1.27.4
70+
/home/ubuntu/microk8s/build-scripts/components/kubernetes/patches/v1.27.4/0000-Kubelite-integration.patch
71+
$ ./build-scripts/print-patches-for.py kubernetes v1.27.3
72+
/home/ubuntu/microk8s/build-scripts/components/kubernetes/patches/v1.27.0/0000-Kubelite-integration.patch
73+
/home/ubuntu/microk8s/build-scripts/components/kubernetes/patches/v1.27.0/0001-Unix-socket-skip-validation-in-component-status.patch
74+
$ ./build-scripts/print-patches-for.py kubernetes v1.28.1
75+
/home/ubuntu/microk8s/build-scripts/components/kubernetes/patches/v1.28.0/0001-Set-log-reapply-handling-to-ignore-unchanged.patch
76+
/home/ubuntu/microk8s/build-scripts/components/kubernetes/patches/v1.28.0/0000-Kubelite-integration.patch
77+
```
78+
79+
### How to add support for newer versions
80+
81+
When a new release comes out which is no longer compatible with the existing latest patches, simply create a new directory under `patches/` with the new version number. This ensures that previous versions will still work, and newer ones will pick up the fixed patches.

build-scripts/components/cni/patches/0001-single-entrypoint-for-cni-tools.patch renamed to build-scripts/components/cni/patches/default/0001-single-entrypoint-for-cni-tools.patch

File renamed without changes.

build-scripts/components/containerd/patches/0001-microk8s-sideload-images-plugin.patch renamed to build-scripts/components/containerd/patches/default/0001-microk8s-sideload-images-plugin.patch

File renamed without changes.

build-scripts/components/flanneld/patches/0001-disable-udp-backend.patch renamed to build-scripts/components/flanneld/patches/default/0001-disable-udp-backend.patch

File renamed without changes.

build-scripts/components/helm/patches/0001-disable-warnings-for-kubeconfig-permissions.patch renamed to build-scripts/components/helm/patches/default/0001-disable-warnings-for-kubeconfig-permissions.patch

File renamed without changes.

0 commit comments

Comments
 (0)