chore: Go 1.26 + K8s 0.36.1 + controller-runtime 0.24.1#505
Merged
Conversation
Coordinated bump of the language toolchain and the Kubernetes ecosystem deps in lockstep, because k8s.io/apimachinery 0.36 requires Go 1.26 and the individual Dependabot PRs cannot merge alone. Closes defilantech#490 (golang docker base 1.25 -> 1.26). Closes defilantech#491 (k8s.io/apimachinery 0.35.4 -> 0.36.1). Closes defilantech#494 (k8s.io/client-go 0.35.4 -> 0.36.1). Closes defilantech#495 (sigs.k8s.io/controller-runtime 0.23.3 -> 0.24.1). Why all at once Each individual Dependabot PR was red. k8s.io/apimachinery 0.36's own go.mod requires Go >= 1.26.0; on this repo's existing Go 1.25 toolchain that surfaced as three failures: - golangci-lint (built with Go 1.25) refused to lint a 1.26-targeted project: 'the Go language version (go1.25) used to build golangci-lint is lower than the targeted Go version (1.26.0)'. - Dockerfile.router-proxy on golang:1.25-alpine failed at 'go mod download' with 'go.mod requires go >= 1.26.0 (running go 1.25.10; GOTOOLCHAIN=local)'. - govulncheck flagged 12 stdlib CVEs the new Go 1.26 toolchain has already fixed. Bumping apimachinery, client-go, and controller-runtime together with the Go directive resolves all three at once. What's in this commit go.mod - go directive 1.25.0 -> 1.26.0; toolchain directive dropped (Go's 'go 1.26.0' line is now the floor, no auto-download nudge needed). - k8s.io/api, k8s.io/apimachinery, k8s.io/client-go: 0.35.4 -> 0.36.1. - sigs.k8s.io/controller-runtime: 0.23.3 -> 0.24.1. - go.sum regenerated by 'go mod tidy'; transitive deps updated to match (kube-openapi, structured-merge-diff, konnectivity-client, go-restful, component-base, k8s.io/utils). Dockerfile.router-proxy, test/e2e/stubupstream/Dockerfile - golang:1.25-alpine -> golang:1.26-alpine. The main ./Dockerfile was already on 1.26. config/crd/bases/inference.llmkube.dev_inferenceservices.yaml - One-line documentation removal emitted by the new K8s schema: 'This requires the ProcMountType feature flag to be enabled.' went away because ProcMountType is GA in the K8s version controller-gen targets via the bumped deps. No schema or behavior change. api/v1alpha1/groupversion_info.go, api/foreman/v1alpha1/groupversion_info.go - Added //nolint:staticcheck on the scheme.Builder line in both API packages. controller-runtime 0.24 deprecated scheme.Builder ('api packages should have minimal deps, scheme.Builder pulls controller-runtime into api/'). The helper still works; migrating to the runtime.NewSchemeBuilder pattern is a project-wide refactor across both API groups and is tracked as a follow-up issue. README.md - Mermaid 'native processes' block on the architecture diagram and the Features bullet: replaced stale 'oMLX / Ollama' references with the runtimes the metal-agent actually supervises today (llama-server, mlx-server, vllm-swift). Same accuracy theme as the recent llmkube-web cleanup PR. Strictly orthogonal to the version bump, but a small enough change that splitting it into its own PR felt like more friction than value. What's verified - go build ./... on darwin/arm64 and linux/amd64. - make lint clean on both GOOS settings. - make test passes; coverage numbers unchanged (internal/foreman/controller 68.6%, pkg/foreman/agent 33.5%, internal/controller 79.6%, etc.). - CRD parity check: charts/llmkube/templates/crds/*.yaml stays byte-identical to config/crd/bases/inference.llmkube.dev_*.yaml. What's NOT in this commit - Migration from scheme.Builder to runtime.NewSchemeBuilder. Filed as its own follow-up. - Bumps for the LLMKube core's other transitive deps that didn't require the K8s ecosystem ratchet (Prometheus client, OTel, zap, cobra, etc.). Dependabot will pick those up individually. Signed-off-by: Christopher Maher <chris@mahercode.io>
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Three CI failures from the parent commit on this branch (Go 1.26 + K8s
0.36 bump), all addressed here:
CRD Sync Check (my mistake)
Parent commit regenerated config/crd/bases/...inferenceservices.yaml
via 'make manifests' but did not run 'make chart-crds' to mirror the
change into charts/llmkube/templates/crds/. This commit fixes that.
Only inferenceservices.yaml drifted; the chart's modelrouters and
models CRDs were already in sync with their sources.
Run on Ubuntu / lint (chicken-and-egg)
.github/workflows/lint.yml and Makefile pinned golangci-lint v2.4.0;
that binary was built with Go 1.25 and refused to lint a 1.26-
targeted project. Bumped to v2.12.2, the latest stable v2.x at the
time of this commit. The newer lint binary exposes more findings out
of the box (some real, most pre-existing in main); tuned the config
to keep the bump PR focused.
.golangci.yml additions:
- goconst.ignore-tests: true (test fixtures legitimately repeat
log-level strings 'debug' / 'warn' / 'error' and fixture path
literals without needing a constant)
- goconst.min-occurrences: 15 (high enough to clear the pre-
existing production-code repetitions: 'app', 'inference.llmkube
.dev/service', '/health' all appear 5-10 times; a focused
follow-up should extract them into proper constants)
- staticcheck.checks: ['all', '-QF*', '-ST*'] (keep SA*
correctness checks; QF* are stylistic quickfixes added in
staticcheck v0.6, ST* are stylistic naming / comment-form
checks that v2.4.0 effectively had off)
Two pre-existing findings that surfaced with the new lint version
are suppressed with //nolint annotations and explanatory comments:
pkg/agent/health.go (G118 gosec false positive)
The shutdown goroutine intentionally uses context.Background()
because the parent ctx is Done by the time the goroutine starts
(it waits on ctx.Done first). Using the parent ctx for the
shutdown deadline would not work. nolint comment makes the
design intent explicit.
pkg/cli/deploy_test.go (prealloc misread)
Table-driven test with literal struct entries. prealloc cannot
tell the difference between literal-init slices and append-built
slices on every Go version.
govulncheck (Go 1.26 stdlib CVEs not fixed in 1.26.0)
All 12 CVEs the govulncheck job flagged are stdlib issues
introduced in Go 1.26.0 and fixed in Go 1.26.3:
- net/mail: GO-2026-4986, GO-2026-4977 (transitively called by
http.Server.ListenAndServe)
- html/template: GO-2026-4982, GO-2026-4980 (same path)
- net: GO-2026-4971 (net.Dialer.Dial, net.Listen, net.LookupIP,
net.Resolver.LookupHost / LookupSRV / LookupTXT)
- 7 more in the same families
Bumped go.mod's go directive from 1.26.0 to 1.26.3. The CI's
setup-go (with go-version-file: go.mod) will now install 1.26.3
and govulncheck stops flagging them.
Verified
- go build clean on darwin/arm64 and linux/amd64
- make lint 0 issues on both GOOS settings
- make test passes (coverage unchanged)
- chart-crd parity: config/crd/bases/inference.llmkube.dev_*.yaml
syncs cleanly to charts/llmkube/templates/crds/*.yaml
Follow-up issue worth filing
Several pre-existing lint findings are now suppressed via config
rather than fixed. A focused 'lint cleanup' PR should:
- Extract 'app', 'inference.llmkube.dev/service', '/health'
constants
- Re-use the existing ConditionProgressing const in scheduling.go
and status_builder.go (the linter even pointed at it)
- Add package comments to internal/metrics, internal/platform,
test/utils, catalog
- Re-tighten goconst.min-occurrences once the real constants are
extracted
Out of scope for the Go 1.26 + K8s 0.36 bump.
Signed-off-by: Christopher Maher <chris@mahercode.io>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Coordinated bump of the language toolchain and the Kubernetes ecosystem deps in lockstep. Closes the four Dependabot PRs that couldn't merge individually:
Plus a small orthogonal README accuracy fix (same theme as #77 on llmkube-web).
Why
Each individual Dependabot PR was red.
k8s.io/apimachinery@v0.36.1's owngo.modrequiresgo >= 1.26.0; on the project's existing Go 1.25 toolchain that surfaced as three failures:the Go language version (go1.25) used to build golangci-lint is lower than the targeted Go version (1.26.0).Dockerfile.router-proxyongolang:1.25-alpinefailed atgo mod downloadwithgo.mod requires go >= 1.26.0 (running go 1.25.10; GOTOOLCHAIN=local).GO-2026-4986,-4982,-4980,-4977,-4971,-4947,-4946,-4918,-4870,-4866,-4865,-4603and more).Bumping
apimachinery,client-go, andcontroller-runtimetogether with the Go directive resolves all three.How
go.modgo 1.25.0→go 1.26.0;toolchaindirective dropped (thego 1.26.0line is now the floor, no auto-download nudge needed).k8s.io/api,k8s.io/apimachinery,k8s.io/client-go:0.35.4 → 0.36.1.sigs.k8s.io/controller-runtime:0.23.3 → 0.24.1.go.sumregenerated bygo mod tidy; transitive deps updated to match (kube-openapi,structured-merge-diff,konnectivity-client,go-restful,component-base,k8s.io/utils).Dockerfiles
Dockerfile.router-proxyandtest/e2e/stubupstream/Dockerfile:golang:1.25-alpine→golang:1.26-alpine. The main./Dockerfilewas already on 1.26.CI workflows
go-version-file: go.mod, so the newgo 1.26.0directive cascades automatically.Makefile
ENVTEST_VERSIONandENVTEST_K8S_VERSIONare derived from the K8s deps ingo.mod, so they update on their own when the deps move.config/crd/bases/inference.llmkube.dev_inferenceservices.yamlmake manifestsagainst the new K8s schema:"This requires the ProcMountType feature flag to be enabled."went away because ProcMountType is GA in the K8s version controller-gen now targets. No schema or behavior change — the field's structural validation, type, and defaults are unchanged.api/v1alpha1/groupversion_info.go,api/foreman/v1alpha1/groupversion_info.go//nolint:staticcheckon thescheme.Builderline in both API packages. controller-runtime 0.24 deprecatedscheme.Builder("api packages should have minimal deps;scheme.Builderpulls controller-runtime intoapi/"). The helper still works correctly; migrating to theruntime.NewSchemeBuilderpattern is a project-wide refactor across both API groups and will be a focused follow-up issue.README.md(orthogonal small change)oMLX / Ollamareferences with the runtimes the metal-agent actually supervises today (llama-server,mlx-server,vllm-swift). Same accuracy theme as the recent llmkube-web cleanup. Strictly orthogonal to the version bump, but a small enough change that splitting it into its own PR felt like more friction than value.Verified
go build ./...clean ondarwin/arm64andlinux/amd64.make lint0 issues on bothGOOS=darwinandGOOS=linux.make testpasses; coverage numbers unchanged frommain:internal/foreman/controller: 68.6%pkg/foreman/agent: 33.5%internal/controller: 79.6%pkg/agent: 57.2%charts/llmkube/templates/crds/*.yamlstays byte-identical toconfig/crd/bases/inference.llmkube.dev_*.yaml.Not in this PR
scheme.Buildertoruntime.NewSchemeBuilder. Tracked as a follow-up; touches both API groups, deserves its own focused PR.Checklist
make testpasses locally (both arches)make lintpasses locally (both arches)git commit -s) per DCO