Patch series for kcp modifications to kubernetes/kubernetes.
The patches in patches/ are maintained as git format-patch output and are applied with git am.
Clone this repository, then fill out the .env file run the setup script:
git clone https://github.com/kcp-dev/kubernetes-patches
cd kubernetes-patches
# edit .env
./hack/setup.bash bothNote
Using the setup script is optional - it is just a helper and a suggestion on branch management. Only important bit is that kcp/ is a kcp repository and kubernetes/ is a kubernetes repository.
This will clone or update the repositories and make feature branches in the kubernetes and the kcp clones.
The script is non-destructive, meaning it will checkout a new branch off of the base branch with every call, adding a number to the templated branch with every iteration.
That means its always possible to start over without loosing previous
work. If only kube or only kcp needs to be reset run ./hack/setup.bash kube and ./hack/setup.bash kcp respectively.
The kubernetes and kcp directories are gitignored.
Note
Using submodules instead of gitignoring the directories would also be an option, however for the moment this approach is simpler and sufficient.
After that run build the go.work file:
./hack/build-gowork.bashThis builds a functioning go.work based on the modules in both repositories.
First the soft forks must be updated. Some modules in the staging directories in the kcp repository contain modified copies of upstream files. These are dependencies used both in kcp and the kubernetes fork.
Use the bump-soft.bash script to bump and commit the kube dependencies
in the modules containing soft forks.
./hack/bump-soft.bashYou may run into messages like this:
go: github.com/kcp-dev/client-go/kubernetes/fake imports
k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1: module k8s.io/client-go@latest found (v0.36.0), but does not contain package k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1
go: github.com/kcp-dev/client-go/kubernetes/typed/autoscaling/v2beta1/fake imports
k8s.io/client-go/applyconfigurations/autoscaling/v2beta1: module k8s.io/client-go@latest found (v0.36.0), but does not contain package k8s.io/client-go/applyconfigurations/autoscaling/v2beta1
go: github.com/kcp-dev/client-go/kubernetes/typed/autoscaling/v2beta2/fake imports
k8s.io/client-go/applyconfigurations/autoscaling/v2beta2: module k8s.io/client-go@latest found (v0.36.0), but does not contain package k8s.io/client-go/applyconfigurations/autoscaling/v2beta2
go: github.com/kcp-dev/client-go/kubernetes/typed/scheduling/v1alpha1/fake imports
k8s.io/client-go/applyconfigurations/scheduling/v1alpha1: module k8s.io/client-go@latest found (v0.36.0), but does not contain package k8s.io/client-go/applyconfigurations/scheduling/v1alpha1
This happens when upstream removes APIs that are still references. These issues will be fixed when updating the generated code so they can be ignored at this step.
Afterwards each of the soft forks needs to be updated and reviewed.
apimachinery contains modified copies of upstream files.
To update the copies use a three way git merge.
If hunks fail to apply they need to be reviewed and adjusted manually.
git -C kubernetes show v${OLD_KUBE_1_TAG}:staging/src/k8s.io/client-go/tools/cache/reflector.go \
> "$PATCHES_ROOT/kcp/staging/src/github.com/kcp-dev/apimachinery/third_party/reflector/reflector_base.go"
git -C kubernetes show v${NEW_KUBE_1_TAG}:staging/src/k8s.io/client-go/tools/cache/reflector.go \
> "$PATCHES_ROOT/kcp/staging/src/github.com/kcp-dev/apimachinery/third_party/reflector/reflector_upstream.go"
git -C kcp merge-file staging/src/github.com/kcp-dev/apimachinery/third_party/reflector/reflector.go \
"$PATCHES_ROOT/kcp/staging/src/github.com/kcp-dev/apimachinery/third_party/reflector/reflector_base.go" \
"$PATCHES_ROOT/kcp/staging/src/github.com/kcp-dev/apimachinery/third_party/reflector/reflector_upstream.go"git -C kubernetes show v${OLD_KUBE_1_TAG}:staging/src/k8s.io/client-go/tools/cache/controller.go \
> "$PATCHES_ROOT/kcp/staging/src/github.com/kcp-dev/apimachinery/third_party/reflector/controller_base.go"
git -C kubernetes show v${NEW_KUBE_1_TAG}:staging/src/k8s.io/client-go/tools/cache/controller.go \
> "$PATCHES_ROOT/kcp/staging/src/github.com/kcp-dev/apimachinery/third_party/reflector/controller_upstream.go"
git -C kcp merge-file staging/src/github.com/kcp-dev/apimachinery/third_party/reflector/controller.go \
"$PATCHES_ROOT/kcp/staging/src/github.com/kcp-dev/apimachinery/third_party/reflector/controller_base.go" \
"$PATCHES_ROOT/kcp/staging/src/github.com/kcp-dev/apimachinery/third_party/reflector/controller_upstream.go"Review the changes and fix any merge conflicts. After deleting the _base.go and _upstream.go files go vet can be used to validate that the code would at least build.
git -C kubernetes show v${OLD_KUBE_1_TAG}:staging/src/k8s.io/client-go/tools/cache/shared_informer.go \
> "$PATCHES_ROOT/kcp/staging/src/github.com/kcp-dev/apimachinery/third_party/informers/shared_informer_base.go"
git -C kubernetes show v${NEW_KUBE_1_TAG}:staging/src/k8s.io/client-go/tools/cache/shared_informer.go \
> "$PATCHES_ROOT/kcp/staging/src/github.com/kcp-dev/apimachinery/third_party/informers/shared_informer_upstream.go"
git -C kcp merge-file staging/src/github.com/kcp-dev/apimachinery/third_party/informers/shared_informer.go \
"$PATCHES_ROOT/kcp/staging/src/github.com/kcp-dev/apimachinery/third_party/informers/shared_informer_base.go" \
"$PATCHES_ROOT/kcp/staging/src/github.com/kcp-dev/apimachinery/third_party/informers/shared_informer_upstream.go"Proceed as for reflector and check if scoped_shared_informer.go needs updates.
Repeat for examples/go.mod.
Manually review upstream to check for any changes to these generators in the kubernetes repository:
staging/src/k8s.io/code-generator/cmd/client-genstaging/src/k8s.io/code-generator/cmd/informer-genstaging/src/k8s.io/code-generator/cmd/lister-gen
cd kubernetes
git diff v${NEW_KUBE_1_TAG}...v${OLD_KUBE_1_TAG} -- staging/src/k8s.io/code-generator
popdOnce there are no changes required run the code generator and commit that as a standalone commit:
make -C kcp code-generator-codegenRun the code generator:
make -C kcp client-go-codegenAnd commit.
client-go has a helper script populate-copies.sh - cd into the
staging directory and run it:
cd kcp/staging/src/github.com/kcp-dev/client-go/
./hack/populate-copies.shThis will copy files originally copied from upstream over the local copies. Review the resulting changes and ensure upstream modifications are addressed. In most cases its just a matter of adding cluster awareness.
Commit the changes.
Now the patches are applied to the kubernetes fork.
The patches are maintained in the patches/ directory and are applied
using git-am.
Note
At any point git am --abort can be run to stop any reconciliation,
remove all commits applied to the branch until that point and restore
the previous base branch.
cd kubernetes
git am --3way ../patches/*.patchWhen a patch fails to apply, git will stop and report the conflict:
Applying: UPSTREAM: <carry>: ...
error: patch failed: ...
Resolve the conflict in the affected files, stage the changes and run
git am --continue. Do not run git commit - that will create a new
commit instead of updating the patch commit.
Repeat until all patches are applied.
Note
TODO: add scripts automating some of the finalizing steps mentioned here: https://docs.kcp.io/kcp/main/contributing/guides/rebasing-kubernetes/#rebase-process
Specifically check that staging/src/k8s.io/apiserver/pkg/clientsethack/adapter.go satisfies kubernetes.Interface.
Now the vendor directories and codegen for kube must be updated - be
sure that this has the GOWORK set so the kube fork uses the updated
local copies:
../hack/pin-local-replace.bash
git add . && git commit -m 'CARRY: <drop>: Add kcp dependencies'
GOWORK= ./hack/update-vendor.sh
git add . && git commit -m 'CARRY: <drop>: vendor'
GOWORK= ./hack/update-codegen.sh
git add . && git commit -m 'CARRY: <drop>: codegen'
Go into kcp, ensure GOWORK is set, update k8s.io/kubernetes to the
targeted tag and run go work sync to update the go.mod/go.sum files.
Then run the code generation:
cd kcp
./hack/update-codegen-client.sh
./hack/gen-patch-defaultrestmapper.shNote
There's the codegen recipe and that will have to be run later when making the pull requests for the changes.
And commit the generated code:
git add . && git commit -m "codegen"Now run the tests in kcp to see if any breakages occur:
make fix-lint
make test
make test-e2e
make test-e2e-sharded-minimalPR changes in apimachinery, code-generator and client-go against the rebase-staging branch in kcp-dev/kcp
Once reviewed a maintainer manually pushes the changes to the branch.
The publishing bot will then publish this branch to the staging repositories.
Now drop the previous drop commits with the local replaces and update the kcp deps:
cd kubernetes/
GOWORK= ./hack/pin-dependency.sh github.com/kcp-dev/logicalcluster/v3 v3.0.5
GOWORK= ./hack/pin-dependency.sh github.com/kcp-dev/apimachinery/v2 rebase-staging
GOWORK= ./hack/pin-dependency.sh github.com/kcp-dev/client-go rebase-staging
git add . && git commit -m 'CARRY: <drop>: Add kcp dependencies'Update the vendor directories:
GOWORK= ./hack/update-vendor.sh
git add . && git commit -m 'CARRY: <drop>: vendor'And run the code generator:
GOWORK= ./hack/update-codegen.sh
git add . && git commit -m 'CARRY: <drop>: codegen'During the vendoring go likes to replace the v0 tags of the kubernetes
deps - that however breaks when kcp then tries to import the kube fork.
To prevent this replace all the changed versions:
../hack/kube-repin-staging.bash
git add . && git commit -m 'CARRY: <drop>: fix v0 tags'This can't happen beforehand though as resetting the tags then breaks code generation.
And then push this to your fork and create a PR in kcp-dev/kubernetes.
While the kcp-dev/kubernetes PR is up go ahead and update the kcp branch to use the updated kubernetes fork:
cd kcp/
GITHUB_USER=<user> GITHUB_REPO=kubernetes BRANCH=<your branch> ./hack/bump-k8s.shIf that fails upstream probably added a new staging repository. Compare the replacements in the go.mod with the directories in the staging dir.
Once all patches apply cleanly on the new base tag, re-export them to update the patch files:
./hack/format-kube-patches.bash "$KUBE_TAG"TODO: export before rebase as well
Commit the updated patches in this repository.