1. set env variable PATH_TO_KUBERNETES_REPO to the path to your local kubernetes/kubernetes copy: `export PATH_TO_KUBERNETES_REPO="/Users/mtrachier/go/src/github.com/kubernetes/kubernetes"`
1. set env variable GOVERSION to the expected version of go for the kubernetes/kubernetes version checked out: `export GOVERSION=$(yq -e '.dependencies[] | select(.name == "golang: upstream version").version' $PATH_TO_KUBERNETES_REPO/build/dependencies.yaml)`
1. set env variable GOIMAGE to the expected container image to base our custom build image on: `export GOIMAGE="golang:${GOVERSION}-alpine3.15"`
1. set env variable BUILD_CONTAINER to the contents of a dockerfile for the build container: `export BUILD_CONTAINER="FROM ${GOIMAGE}\nRUN apk add --no-cache bash git make tar gzip curl git coreutils rsync alpine-sdk"`
1. use Docker to create the build container: `echo -e $BUILD_CONTAINER | docker build -t ${GOIMAGE}-dev -`
Once the release is verified, the channel server config needs to be updated to reflect the new version for “stable”.
1. Channel.yaml can be found at the [root of the K3s repo.](https://github.com/k3s-io/k3s/blob/master/channel.yaml)
1. When updating the channel server a single-line change will need to be performed.
1. Release Captains responsible for this change will need to update the following stanza to reflect the new stable version of kubernetes relative to the release in progress.
1. click the "show all logs" to see all of the logs
1. search for " failed." this will find a line like "Test bEaiAq failed."
1. search for "err=" and look for a log with the id "bEaiAq" in it
1. example error:
```
#- Tail: /tmp/bEaiAq/agents/1/logs/system.log
[LATEST-SERVER] E0921 19:16:55.430977 57 cri_stats_provider.go:455] "Failed to get the info of the filesystem with mountpoint" err="unable to find data in memory cache" mountpoint="/var/lib/rancher/k3s/agent/containerd/io.containerd.snapshotter.v1.overlayfs
[LATEST-SERVER] I0921 19:16:55.431186 57 proxier.go:667] "Failed to load kernel module with modprobe, you can ignore this message when kube-proxy is running inside container without mounting /lib/modules" moduleName="ip_vs_rr"
```
1. the first part of the log gives a hint to the log level: "E0921" is an error log "I0921" is an info log
1. you can also look for "Summarizing \d Failure" (I installed a plugin on my browser to get regex search: "Chrome Regex Search")
1. example error:
```
[Fail] [sig-network] DNS [It] should support configurable pod DNS nameservers [Conformance]
```
1. example PR: https://github.com/k3s-io/k3s/pull/6164
1. many errors are flakey/transitive, it is usually a good idea to simply retry the CI on the first failure
1. if the same error occurs multiple times then it is a good idea to escalate to the team
1. After the CI passes (or the team dismisses the CI as "flakey"), and you have at least 2 approvals you can merge it
1. make sure you have 2 approvals on the latest changes
1. make sure the CI passes or the team approves merging without it passing
1. make sure the use the "squash and merge" option in GutHub
1. make sure to update the SLACK channel with the new Publish/Merge CI
- Help! My memory usage is off the charts and everything has slowed to a crawl!
- I found rebooting after running tag.sh was the only way to solve this problem, seems like a memory leak in VSCode on Mac or maybe some weird behavior between all of the added/removed files along with VSCode's file parser, the Crowdstrike virus scanner, and Docker (my top memory users)
1. clear out any cached or old files: `git add -A; git reset --hard HEAD`
1. clear out any cached or older outputs: `rm -rf _output`
1. rebase your local copy to move the old k3s tag from the old k8s tag to the new k8s tag
1. so there are three copies of the code involved in this process:
1. the upstream kubernetes/kubernets copy on GitHub
1. the k3s-io/kubernetes copy on GitHub
1. and the local copy on your laptop which is a merge of those
1. the local copy has every branch and every tag from the remotes you have added
1. there are custom/proprietary commits in the k3s-io copy that are not in the kubernetes copy
1. there are commits in the kubernetes copy do not exist in the k3s-io copy
1. we want the new commits added to the kubernetes copy to be in the k3s-io copy
1. we want the custom/proprietary commits from the k3s-io copy on top of the new kubernetes commits
1. before rebase our local copy has all of the commits, but the custom/proprietary k3s-io commits are between the old kubernetes version and the new kubernetes version
1. after the rebase our local copy will have the k3s-io custom/proprietary commits after the latest kubernetes commits
1.`git rebase --onto $NEW_K8S $OLD_K8S $OLD_K3S_VER~1`
1. After rebase you will be in a detached head state, this is normal
- the version.sh script found in the k3s repo at scripts/version.sh is the source of truth for version information
1. go to [the k3s repo](https://github.com/k3s-io/k3s) and browse the release tag for the notes you are verifying, [example](https://github.com/k3s-io/k3s/blob/v1.23.13-rc2+k3s1)
1. start by searching the version.sh file for the component
1. if you do not find anything, search the build script found in ./scripts/build [example](https://github.com/k3s-io/k3s/blob/v1.23.13-rc2+k3s1/scripts/build)
1. if you still do not find anything, search the go.mod found in the root of the k3s repo [example](https://github.com/k3s-io/k3s/blob/v1.23.13-rc2+k3s1/go.mod#L93)
1. some things are in the k3s repo's manifests directory, see ./manifests [example](https://github.com/k3s-io/k3s/blob/v1.23.13-rc2%2Bk3s1/manifests/local-storage.yaml#L66)
- example info for v1.23.13-rc2+k3s1
```
kubernetes: version.sh pulls from k3s repo go.mod see https://github.com/k3s-io/k3s/blob/v1.23.13-rc2+k3s1/scripts/version.sh#L35
kine: go.mod, see https://github.com/k3s-io/k3s/blob/v1.23.13-rc2+k3s1/go.mod#L93
sqlite: go.mod, see https://github.com/k3s-io/k3s/blob/v1.23.13-rc2+k3s1/go.mod#L97
etcd: go.mod, use the /api/v3 mod, see https://github.com/k3s-io/k3s/blob/v1.23.13-rc2+k3s1/go.mod#L25
containerd: version.sh sets an env variable based on go.mod, then the build script builds it
see https://github.com/k3s-io/k3s/blob/v1.23.13-rc2%2Bk3s1/scripts/version.sh#L25
and https://github.com/k3s-io/k3s/blob/v1.23.13-rc2%2Bk3s1/scripts/build#L36
runc: set in the version.sh
this one is weird, it ignores the go.mod, preferring the version.sh instead
the version.sh sets an env variable which is picked up by the download script
the build script runs 'make' on whatever was downloaded
see https://github.com/k3s-io/k3s/blob/v1.23.13-rc2%2Bk3s1/scripts/version.sh#L40
and https://github.com/k3s-io/k3s/blob/v1.23.13-rc2+k3s1/scripts/download#L29
and https://github.com/k3s-io/k3s/blob/master/scripts/build#L138
flannel: version.sh sets an env variable based on go.mod, then the build script builds it
see https://github.com/k3s-io/k3s/blob/v1.23.13-rc2+k3s1/go.mod#L83
metrics-server: version is set in the manifest at manifests/metric-server
see https://github.com/k3s-io/k3s/blob/v1.23.13-rc2+k3s1/manifests/metrics-server/metrics-server-deployment.yaml#L42
traefik: version is set in the manifest at manifests/traefik.yaml
see https://github.com/k3s-io/k3s/blob/v1.23.13-rc2%2Bk3s1/manifests/traefik.yaml#L36
coredns: version is set in the manifest ar manifests/coredns.yaml
see https://github.com/k3s-io/k3s/blob/v1.23.13-rc2%2Bk3s1/manifests/coredns.yaml#L122
helm-controller: go.mod, see https://github.com/k3s-io/k3s/blob/v1.23.13-rc2%2Bk3s1/go.mod#L92
local-path-provisioner: version is set in the manifest at manifests/local-storage.yaml
see https://github.com/k3s-io/k3s/blob/v1.23.13-rc2%2Bk3s1/manifests/local-storage.yaml#L66
```
## Understanding Release Notes
Here are the major sections in the release notes:
- changes since
- this relates all changes since the previous release
- more specifically every merge issue (PR) generated should have an entry
- developers may add a special "User-Facing Change" section to their PR to give custom notes
- these notes will appear as sub entries on the issue title
- released components
- this relates all kubernetes 'components' in the release
- components are generally non-core kubernetes options that we install using Helm charts
1. make sure the $HOME/go/src/github.com/k3s-io directory exists
1. clear out (remove) k3s repo if is already there (just makes things smoother with a new clone)
1. clone k3s-io/k3s repo into that directory as "upstream"
1. fork that repo so that you have a private fork of it
1. if you already have a fork, sync it
1. add your fork repo as "origin"
1. fetch all objects from both repos into your local copy
1. it is important to follow these steps because Go is very particular about the file structure (it uses the the file structure to infer the urls it will pull dependencies from)
1. this is why it is important that the repo is in the github.com/k3s-io directory, and that the repo's directory is "k3s" matching the upstream copy's name
1. make sure the $HOME/go/src/github.com/kubernetes directory exists
1. clear out (remove) kubernetes repo if is already there (just makes things smoother with a new clone)
1. clone kubernetes/kubernetes repo into that directory as "upstream"
1. add k3s-io/kubernetes repo as "k3s-io"
1. fetch all objects from both repos into your local copy
1. it is important to follow these steps because Go is very particular about the file structure (it uses the the file structure to infer the urls it will pull dependencies from)
1. this is why it is important that the repo is in the github.com/kubernetes directory, and that the repo's directory is "kubernetes" matching the upstream copy's name `$HOME/go/src/github.com/kubernetes/kubernetes`
The scripts and tools involved in release require specific environment variables,
the value of these variables is not always obvious.
This guide helps you navigate the creation of those variables.
1. set GLOBAL_GIT_CONFIG_PATH environment variable (to the path of your git config, ex. '$HOME/.gitconfig'), this will be mounted into a docker container
1. set SSH_MOUNT_POINT environment variable (to the path of your SSH_AUTH_SOCK or your ssh key), this will be mounted into a docker container
1. set OLD_K8S to the previous k8s version
1. set NEW_K8S to the newly released k8s version
1. set OLD_K8S_CLIENT to the kubernetes/go-client version which corresponds with the previous k8s version
1. set NEW_K8S_CLIENT to the client version which corresponds with the newly released k8s version
1. set OLD_K3S_VER to the previous k3s version (the one which corresponds to the previous k8s version), replacing the plus symbol with a dash (eg. for "v1.25.0+k3s1" use "v1.25.0-k3s1")
1. set NEW_K3S_VER to the k3s version which corresponds to the newly released k8s version, replacing the plus symbol with a dash
1. set RELEASE_BRANCH to the the k3s release branch which corresponds to the newly released k8s version
1. set GOPATH to the path to the "go" directory (usually $HOME/go)
1. set GOVERSION to the version of go which the newly released k8s version uses
1. you can find this in the kubernetes/kubernetes repo
1. go to the release tag in the proper release branch
1. go to the build/dependencies.yaml
1. search for the "golang: upstream version" stanza and the go version is the "version" in that stanza
After the RCs are cut you need to generate the KDM PR within a few hours
## Set up Repo
1. make sure the $HOME/go/src/github.com/rancher directory exists
1. clear out (remove) kontainer-driver-metadata repo if is already there (just makes things smoother with a new clone)
1. fork kdm repo
1. clone your fork into that directory as "origin" (you won't need a local copy of upstream)
1. it is important to follow these steps because Go is very particular about the file structure (it uses the the file structure to infer the urls it will pull dependencies from)
1. go generate needs to be able to fully use Go as expected, so it is important to get the file structure correct
1. this is why it is important that the repo is in the github.com/rancher directory, and that the repo's directory is "kontainer-driver-metadata" matching the upstream copy's name
1. checkout a new branch (something like "k3s-release-september")
## Update The Channels
1. Edit the "channels.yaml" file in the root of the repo
1. copy and paste the previous version's info directly below it
1. if a version was skipped, there should be a comment stating that
1. ask QA captain what the min and max channel server versions should be
1. generate the change to the channel.yaml and commit it
## Go Generate
1. Generate json data changes
1. as a separate commit, run the command `go generate`
1. this will alter the data/data.json file
1. commit this change by itself with the commit message "go generate" (exactly that message)
1. push the changes to your fork
## Squashing Your Changes
ok, so you have all the commits and you are ready to go, suddenly someone asks you to squash all the changes to the channels.yaml and the data/data.json together.
The goal is to have 2 commits, one with all the changes to channels.yaml, and one with the changes to data/data.json.
They might also ask you to rebase from the upstream branch...
1. Rebasing from upstream: `git pull --rebase upstream <branch to rebase from>` for example: `git pull --rebase upstream dev-v2.7`
1. this will pull in all of the commits from upstream's 'dev-v2.7' branch into your local copy
1. this will rebase your local copy's history on top of that pull
1. you will need to verify your files and force push your local copy to your origin copy `git push -f origin <branch name>`, for example: `git push -f origin k3s-release-september`
1. you will see all of the commits for the PR re-added as part of this process, take a note of how many commits are in the PR (needed for next step)
1. force push the rebase to your origin before moving to the next step, this will prevent a diverged head state.
1. Reset local copy: `git reset --hard HEAD~<commit number>`, for example if you had 20 commits: `git reset --hard HEAD~20`
1. this resets your local copy to the point in git history just before your first commit
1. before you reset make sure you are at the tip of HEAD (important for next step)
1. look in the history in GitHub and verify that you are at the proper commit so that you don't squash anyone else's commits into your own
1. Pull in the commits after reset and squash them in your local copy: `git merge --squash HEAD@{1}`
1. the `HEAD@{1}` is returning to where HEAD was before reset
1. this does not actually make a commit for you, it only merges the commits into a single staged but uncommitted state
1. remove the data/data.json from the staged for commit files: `git restore --staged data/data.json`
1. this does not actually restore anything, it simply moves the file from staged for commit to unstaged
1. you want to commit the channels.yaml in a separate commit from the data.json
1. commit the channels.yaml changes
1. this single commit will replace any/all of the previous commits
1. I put a message like "updating channels"
1. stage the data/data.json: `git add data/data.json`
1. this adds a new commit with just the changes to the data.json, replacing the previous commits