Summary
The milo API server returns an invalid version string v0.0.0-master+$Format:%H$ which causes kubectl and datumctl to fail when querying the server version.
Problem
When running kubectl version or datumctl version against a milo API server:
$ kubectl --kubeconfig .milo/kubeconfig version
Client Version: v1.34.3
Kustomize Version: v5.7.1
Server Version: v0.0.0-master+$Format:%H$
error: server version error: could not parse pre-release/metadata (-master+$Format:%H$) in version "v0.0.0-master+$Format:%H$"
The $Format:%H$ is a git archive substitution placeholder that should be replaced at build time but is being served as a literal string.
Root Cause
The Dockerfile declares ARG variables for version information but never uses them in the go build command:
# Version information is injected via ldflags into k8s.io/component-base/version
ARG VERSION=v0.0.0-master+dev
ARG GIT_COMMIT=unknown
ARG GIT_TREE_STATE=dirty
ARG BUILD_DATE=unknown
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
go build -trimpath -o milo ./cmd/milo # <-- No ldflags passed!
Without ldflags, the binary retains the default placeholder values from k8s.io/component-base/version/base.go:
gitVersion = "v0.0.0-master+$Format:%H$"
gitCommit = "$Format:%H$"
Proposed Fix
Immediate Fix
Update the Dockerfile to pass ldflags:
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
go build -trimpath \
-ldflags="-w -s \
-X k8s.io/component-base/version.gitVersion=${VERSION} \
-X k8s.io/component-base/version.gitCommit=${GIT_COMMIT} \
-X k8s.io/component-base/version.gitTreeState=${GIT_TREE_STATE} \
-X k8s.io/component-base/version.buildDate=${BUILD_DATE}" \
-o milo ./cmd/milo
Versioning Strategy Consideration
There's an existing TODO in config.go:299:
// TODO(jreese) better version handling
c.Aggregator.GenericConfig.EffectiveVersion = utilversion.DefaultKubeEffectiveVersion()
The version value itself needs consideration. Options include:
- Kubernetes-aligned versioning (
v1.32.0-milo.0+commit) - Clearly communicates k8s API compatibility
- Independent milo versioning (
v0.1.0+commit) - Requires valid semver
- Custom EffectiveVersion - Decouple display version from feature gate version
Note: Feature gates use DefaultKubeBinaryVersion (hardcoded to 1.32 in k8s.io/component-base@v0.32.3), so they work correctly regardless of the gitVersion value. The immediate concern is ensuring the version string is valid semver.
Related
Summary
The milo API server returns an invalid version string
v0.0.0-master+$Format:%H$which causes kubectl and datumctl to fail when querying the server version.Problem
When running
kubectl versionordatumctl versionagainst a milo API server:The
$Format:%H$is a git archive substitution placeholder that should be replaced at build time but is being served as a literal string.Root Cause
The Dockerfile declares ARG variables for version information but never uses them in the
go buildcommand:Without ldflags, the binary retains the default placeholder values from
k8s.io/component-base/version/base.go:Proposed Fix
Immediate Fix
Update the Dockerfile to pass ldflags:
Versioning Strategy Consideration
There's an existing TODO in
config.go:299:The version value itself needs consideration. Options include:
v1.32.0-milo.0+commit) - Clearly communicates k8s API compatibilityv0.1.0+commit) - Requires valid semverNote: Feature gates use
DefaultKubeBinaryVersion(hardcoded to1.32ink8s.io/component-base@v0.32.3), so they work correctly regardless of the gitVersion value. The immediate concern is ensuring the version string is valid semver.Related