0088. A renderer change is a desired-state change, not drift

Status: Accepted · Date: 2026-10-27 · Design section: Configuration reconcile

Decided: render.Version (an integer in pkg/render/version.go) is part of every machine's input hash (desiredInputsHash), so an Ichor release whose renderer emits different output for the same CRs reads as a desired-state change and is applied like any other, while a node that changed on its own with the same version is still drift; the version is bumped by hand in any change that alters render output, and TestRenderVersionMatchesOutput fails when the output of a fixed set of inputs (secrets removed) changes without Version and the pinned fingerprint moving together

Context

The input hash (status.observedInputsHash) covered only the generations of the cluster, machine, applicable patches and storage. After a self-upgrade (ADR 0059) to a release that renders spec.hostname into a HostnameConfig, every node differed from the render while no generation had moved, so each was reported NodeDrifted and, under the default driftPolicy: warnOnly, never corrected. Nobody changed the node; Ichor's own desired state changed.

Decision

  • desiredInputsHash includes render=<render.Version>. A new version makes the hash differ from status.observedInputsHash, so the reconcile takes the desired-state path: reboot-free changes are applied with NO_REBOOT; reboot-requiring ones set RebootRequired and wait for ichor config apply (ADR 0080); install-time-only and unsupported ones are reported as before. The hash is recorded again once the node matches.
  • A controller restart on the same release recomputes the same hash, so nothing is re-applied. Only a release with a different render.Version applies, once per node. The first release carrying this ADR changes every hash once (the render= part is new), which at worst applies the pending render difference, the intended outcome.
  • The build version is not used: a rebuild with unchanged rendering must not touch nodes.
  • Enforcement is a test, not a review habit. TestRenderVersionMatchesOutput renders a control plane and a worker under two different secrets bundles and fingerprints every key path of the output, keeping a value only where both renders agree (so secrets drop out and Ichor's own decisions stay in). The test pins Version and that fingerprint; a render change fails it with instructions to bump Version and update both pins. It sees only what its inputs exercise, so a change visible only under other inputs (a CNI, a storage layout) must bump Version by the author's judgment, and the inputs can be widened when one is missed.
  • Docs: an Ichor upgrade may apply configuration to nodes when the renderer changed; changes that need a reboot wait for a config rollout. Nothing about this is in the upgrade plan (the new release's render version is not known to the old controller), so the note lives here and in the design's Configuration reconcile step 5.

Search the docs

Search pages and headings