Skip to content

Commit 18ba752

Browse files
committed
Install kubectl from the release binaries so it is version-stamped
The kitchen sink image installed kubectl via `apt-get install kubectl`. The same layer also adds the Google Cloud SDK apt repo, which publishes its own `kubectl` package, so which package provides /usr/bin/kubectl is an apt resolution outcome rather than an explicit choice. In the 3.256.0 image the resulting binary is not version-stamped: $ kubectl version --client Client Version: v0.0.0-master+$Format:%H$ `major` and `minor` are empty and gitVersion/gitCommit still contain the literal git-archive placeholders. That is not parseable as a version, and it breaks tooling that checks the kubectl client version - @pulumi/eks calls semver.clean() on it, gets null, and dies with a TypeError that never mentions kubectl. Install the official release binary and verify it against the published checksum instead, matching how aws-iam-authenticator is already installed in this layer, and drop the now-unused Kubernetes apt repo. Adds a test asserting kubectl reports a parseable, non-placeholder version, since this fails silently until something tries to parse it.
1 parent 1330859 commit 18ba752

3 files changed

Lines changed: 48 additions & 6 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
## Unreleased
44

5+
- Install `kubectl` in the `pulumi/pulumi` image from the upstream release binaries
6+
instead of apt, so it is version-stamped. The previous install could resolve to a
7+
build reporting `v0.0.0-master+$Format:%H$`, which is not parseable as a version and
8+
breaks tooling that checks the kubectl client version, such as `@pulumi/eks`.
9+
([#776](https://github.com/pulumi/pulumi-docker-containers/issues/776))
10+
511
- Add .NET 10 to the kitchen sink `pulumi/pulumi` image, alongside 8.0 and 9.0
612
([#763](https://github.com/pulumi/pulumi-docker-containers/issues/763))
713

docker/pulumi/Dockerfile

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,17 +71,25 @@ RUN \
7171
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | gpg --dearmor -o /etc/apt/keyrings/google-cloud.gpg && \
7272
echo "deb [arch=${TARGETARCH} signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list && \
7373
echo "deb [signed-by=/etc/apt/keyrings/google-cloud.gpg] http://packages.cloud.google.com/apt cloud-sdk-$(lsb_release -cs) main" | tee /etc/apt/sources.list.d/google-cloud-sdk.list && \
74-
KUBE_LATEST=$(curl -L -s https://dl.k8s.io/release/stable.txt | awk 'BEGIN { FS="." } { printf "%s.%s", $1, $2 }') && \
75-
curl -fsSL https://pkgs.k8s.io/core:/stable:/${KUBE_LATEST}/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg && \
76-
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/${KUBE_LATEST}/deb/ /" | tee /etc/apt/sources.list.d/kubernetes.list && \
77-
# Install azure-cli (from Debian repos), docker, gcloud, kubectl
74+
# kubectl, from the official release binaries and verified against the published checksum.
75+
# Installed this way rather than from apt so we get a version-stamped build: the Google Cloud
76+
# SDK repo added above also publishes a `kubectl` package, and resolving between the two can
77+
# yield a binary whose `kubectl version` reports `v0.0.0-master+$Format:%H$`, which breaks any
78+
# tooling that parses the client version.
79+
KUBE_LATEST=$(curl --proto "=https" --tlsv1.2 --fail --location --silent --show-error https://dl.k8s.io/release/stable.txt) && \
80+
KUBECTL_BASE_URL="https://dl.k8s.io/release/${KUBE_LATEST}/bin/linux/${TARGETARCH}" && \
81+
curl --proto "=https" --tlsv1.2 --fail --location --remote-name "${KUBECTL_BASE_URL}/kubectl" && \
82+
curl --proto "=https" --tlsv1.2 --fail --location --silent --show-error "${KUBECTL_BASE_URL}/kubectl.sha256" \
83+
| awk '{print $1" kubectl"}' | sha256sum --check - && \
84+
install --mode 755 kubectl /usr/bin/kubectl && \
85+
rm kubectl && \
86+
# Install azure-cli (from Debian repos), docker, gcloud
7887
apt-get update -y && \
7988
apt-get install -y \
8089
azure-cli \
8190
docker-ce \
8291
google-cloud-cli \
83-
google-cloud-cli-gke-gcloud-auth-plugin \
84-
kubectl && \
92+
google-cloud-cli-gke-gcloud-auth-plugin && \
8593
rm -rf /var/lib/apt/lists/*
8694

8795
# Install Go

tests/containers_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,34 @@ func TestCLIToolTests(t *testing.T) {
377377
}
378378
require.Equal(t, project, projectNumber)
379379
})
380+
381+
// kubectl must report a real, version-stamped build. A build without the version ldflags
382+
// reports `v0.0.0-master+$Format:%H$`, which is not parseable as semver and breaks tooling
383+
// that checks the client version (for example @pulumi/eks).
384+
// https://github.com/pulumi/pulumi-docker-containers/issues/776
385+
t.Run("Kubectl", func(t *testing.T) {
386+
if !isKitchenSink(t) {
387+
t.Skip("kubectl is only installed in the kitchen sink image")
388+
}
389+
t.Parallel()
390+
391+
cmd := exec.Command("kubectl", "version", "--client=true", "--output=json")
392+
out, err := cmd.Output()
393+
require.NoError(t, err)
394+
395+
var result struct {
396+
ClientVersion struct {
397+
GitVersion string `json:"gitVersion"`
398+
} `json:"clientVersion"`
399+
}
400+
require.NoError(t, json.Unmarshal(out, &result))
401+
402+
gitVersion := result.ClientVersion.GitVersion
403+
require.NotContains(t, gitVersion, "$Format:",
404+
"kubectl is not version-stamped, got gitVersion %q", gitVersion)
405+
require.Regexp(t, `^v\d+\.\d+\.\d+`, gitVersion,
406+
"kubectl gitVersion %q is not parseable as a version", gitVersion)
407+
})
380408
}
381409

382410
func TestEnvironment(t *testing.T) {

0 commit comments

Comments
 (0)