Files
Myasnikov Daniil efa85a4f61 feat(platform): make the etcd-adoption skip-backup hatch reachable
Migration 50 has honoured ETCD_ADOPT_SKIP_BACKUP since it was written, and
its failure paths tell operators to "re-run with ETCD_ADOPT_SKIP_BACKUP=1".
But migration-hook.yaml passes only NAMESPACE/CURRENT_VERSION/
TARGET_VERSION, and the Job is a Helm hook the chart re-renders, so there
has never been a way to set it. The script advertised an escape the
platform made impossible. The endpoint-classification work landing
alongside this makes that worse: it adds refuse-rather-than-guess paths,
so more clusters can now legitimately stop here.

Plumb it through migrations.etcdAdoptSkipBackup, default false. Skipping
the pre-adoption snapshot rewires ownership of LIVE etcd storage with no
way back, so it stays opt-in and deliberate — the flag is the last resort
for a cluster that has nothing to fix, not the first response to a
refusal.

Render "1"/"0" rather than the bare bool. The script matches the literal
string "1", so a bool would render "true", sail through the Job spec
looking correct, and be ignored — a safety valve that is set but silently
disregarded is worse than one that was never offered, because the operator
believes they opted in. The value is normalised through a string, so a
bool, a quoted "true" out of the Package CR's Values JSON, or a numeric 1
all land on the same answer, while nil or garbage resolves to "0": taking
this hatch must require an affirmative spelling, never a typo. Resolved
with `dig` so a Platform Package predating the key renders "0" instead of
failing the render of the entire platform chart and bricking every
upgrade.

Widen the script's own check to accept 1/true/yes as well. The template
guarantees the GitOps path, but an operator running this image by hand
will reasonably type "true", and that is exactly the moment they are
already stuck. The two layers cover independent failure modes.

Emit the var unconditionally, including the "0" default, so the rendered
Job states the cluster's safety posture outright rather than leaving an
operator to diff values to find out whether a snapshot was skipped.

Point the failure messages at the values path that actually exists, and
describe it honestly: editing the Platform Package and letting Flux
re-render is a real operation, not a one-liner, and the flag has to be
reverted afterwards or the next etcd migration skips its snapshot too.
Fixing the condition the migration names remains the recommended path —
the migration is idempotent, so re-running after a fix is safe.

templates/migration-hook.yaml had no coverage at all, because the Job only
renders when a lookup of the cozystack-version ConfigMap reports a version
below targetVersion, and lookup is nil under helm template. The new suite
mocks that ConfigMap and asserts the RENDERED VALUE — enabled, disabled,
key absent, stringified true, garbage, and the pre-existing three env vars
— rather than merely that the variable exists, which is what let the trap
above go unnoticed in the first place.

Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-07-20 11:29:09 +05:00
..