Forcing a kubernetes version during build
Tags: kubernetes, versions, bazel, bash
Published: 2018-11-19 21:06:09

---
title: Forcing a kubernetes version during build
published: true
description: kubernetes sets versions unhelpfully by default. Sometimes you want a specific version. This is how.
cover_image: https://thepracticaldev.s3.amazonaws.com/i/11edc57jmaeobg47bm50.jpeg
tags: kubernetes, versions, bazel, bash
---

```
Date: November, 19th, 2018
Kubernetes: https://github.com/kubernetes/kubernetes/commit/8848740f6d0f84c2c4c5165736e12425551a6207
The current release is just before v1.13.0 so the newest tag is v1.14.0-alpha.
```

When a [Kubernetes](https://github.com/kubernetes/kubernetes/) binary is built with [bazel](https://bazel.build/) it will set a default version on the binary for you. That is, when you run `kubectl version` the version is populated automatically.

However, sometimes you want a custom version, probably for testing purposes. For example, if you are testing [kubeadm](https://github.com/kubernetes/kubernetes/tree/master/cmd/kubeadm)'s upgrade feature it helps to force a version to avoid some annoying behavior.

Bazel calculates this version through a script that is defined by a flag called `--workspace_status_command`. That argument is specified in the [`.bazelrc` file](https://github.com/kubernetes/kubernetes/blob/8848740f6d0f84c2c4c5165736e12425551a6207/build/root/.bazelrc).

`print-workspace-status.sh` calls [a bash function](https://github.com/kubernetes/kubernetes/blob/8848740f6d0f84c2c4c5165736e12425551a6207/hack/lib/version.sh#L34) and prints some version information in a very specific format that bazel uses.

If you want to customize this, you have two options.

#### Option 1 You can define a custom `--workspace_status_command` script that generates these versions with whatever versions you want

Create this file as `workspace-status.sh` and make it executable `chmod +x workspace-status.sh`.

```bash
#!/usr/bin/env bash

cat <<EOF
gitCommit $(git rev-parse "HEAD^{commit}")
gitTreeState clean
gitVersion v2.0.0
gitMajor 2
gitMinor 0
buildDate $(date \
  ${SOURCE_DATE_EPOCH:+"--date=@${SOURCE_DATE_EPOCH}"} \
 -u +'%Y-%m-%dT%H:%M:%SZ')
EOF
```

Now run `bazel build --workspace_status_command=./workspace-status.sh //cmd/kubeadm` and you can see it works when you run `kubeadm version` and get this output:

```
kubeadm version
kubeadm version: &version.Info{Major:"2", Minor:"0", GitVersion:"v2.0.0", GitCommit:"679d4397cfdb386ebd3ae4bcb9972273b3f75ca3", GitTreeState:"clean", BuildDate:"2018-11-19T20:43:30Z", GoVersion:"go1.11.2", Compiler:"gc", Platform:"darwin/amd64"}
```

#### Option 2

You can define an environment variable, `KUBE_GIT_VERSION_FILE`, that defines a file in which the versions are already specified.

Create a file called `version.txt` and put the following contents in it:

```
KUBE_GIT_COMMIT=abcd
KUBE_GIT_TREE_STATE="clean"
KUBE_GIT_VERSION="v2.0.3"
KUBE_GIT_MAJOR=2
KUBE_GIT_MINOR=0
```

Now get that file as an environment variable with `export KUBE_GIT_VERSION_FILE=version.txt` and run `bazel build //cmd/kubeadm`.

Then when you run `kubeadm version` you will see:

```
$ kubeadm version
kubeadm version: &version.Info{Major:"2", Minor:"0", GitVersion:"v2.0.3", GitCommit:"abcd", GitTreeState:"clean", BuildDate:"2018-11-19T20:58:25Z", GoVersion:"go1.11.2", Compiler:"gc", Platform:"darwin/amd64"}
```