Skip to content

Guard the kubelet image pin against drifting from kubernetesVersion #3855

Description

@devantler

🤖 Generated by the Agentic Engineer

Evidence

The Talos v1.14 migration (#3850) has to $patch: delete the generated KubeletConfig document,
because Longhorn's machine.kubelet.extraMounts has no v1.14 document equivalent (decided in
#3851). That document is where the base's kubelet image pin lives.

Deleting it silently drops the pin, and talosctl validate still passes. Measured against a
freshly generated v1.14 base:

render siderolabs/kubelet refs talosctl validate
unpatched base (control) 1 PASS
$patch: delete on KubeletConfig 0 PASS
$patch: delete + restated image 1 PASS

schemaRequired: true on KubeletConfig.image does not protect against this — it binds only while
the document exists, and deleting the document removes the requirement along with it.

Impact

With the pin restated by hand, the kubelet image and spec.cluster.kubernetesVersion become two
copies of one fact in two files. Nothing currently couples them, so a Kubernetes version bump that
misses the patch leaves nodes pulling a kubelet from the previous minor — and validation stays
green, so the first signal is node behaviour rather than CI.

Drop the restatement instead and the pin is gone entirely, which is worse and equally green.

Expected behaviour

The kubelet image pin cannot drift from the configured Kubernetes version without CI failing.

Acceptance criteria

  1. A test asserts the kubelet image tag in the Talos patch equals spec.cluster.kubernetesVersion
    in ksail.prod.yaml, in the shape already used by
    scripts/tests/refresh-flux-ghcr-auth/contracts_test.go for TALOS_VERSION.
  2. A negative control proves the assertion fails when the two disagree.
  3. The same coupling is covered for talos-local if it carries its own pin after Migrate the Talos machine config onto the v1.14 configuration documents #3850.
  4. The failure message names both files and the exact values, so the fix is obvious from the log.

Size and risk

Small. One contract test alongside an existing one of the same shape.

Only becomes live when #3850 lands — it guards a pin that does not exist in a patch yet, so it
should land with that migration or immediately after. Part of #3851's criterion 4.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions