Deploy workflow never builds the Endo release, so a cold revision always fails its first apply #4
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The
endo-releasechart gatesapplybehind abuildstage, which reads as"the release has been built and validated". It has not been. That stage runs a
nixos-rebuildDRY RUN of the system closure, which validates the NixOS configonly — the Endo release is not built by Nix.
endo-deploybuilds it atACTIVATION time (
git fetch,yarn install, package builds), inside the windowthe applier gives the daemon to come back healthy.
wait_healthyinmodules/endo-nixos-admin.nixallows 45 tries at 2s = 90s.A first-time revision spends most of that window building.
Observed
Run
r-6f886ae6d099, pinning206e5d24, approved and applied:The release finished building in the same second the health check gave up. The
auto-rollback worked correctly and restored generation 11 — the mechanism is
fine, the ordering is not.
Every earlier deploy passed because those revisions logged
already built; reusing. This was the first cold build, and it failed. Retryingthe same commit now succeeds precisely because the failed attempt left the
release cached — so the workflow is only reliable for revisions a previous
FAILED run happened to warm.
Expected
By the time the operator is asked to approve, the release exists and the apply
is an activation, not a build.
Actual
The operator approves a release that has never been built, and the build happens
during activation, competing with the health check that decides whether to roll
it back.
Suggested fix
Add a prebuild step and run it in the chart before
await-approval.endo-deploy-runhas onlybootstrapanddeploymodes today; aprebuildmode that fetches and builds the pinned revision WITHOUT activating it would
make the chart's
buildstage mean what its name says. Thenapplyreduces toa reuse of an already-built release and comfortably fits the health window.
Widening
wait_healthywould paper over it, but the honest fix is to stop doingunbounded build work inside the rollback window.
Related: floot/endo#3 (the approval form has no way to answer its boolean).
Correction: the cause in the original report is wrong.
I attributed the failure to
wait_healthyrunning out. It did not. The applierlogs two different lines, and the one both failures produced was:
which
endo-nixos-admin.nixonly reaches whennixos-rebuild switchitselfreturns non-zero. A health-check failure takes the other branch and logs
health check failed after switch; rolling back. The near-simultaneoustimestamps that suggested a photo finish were a coincidence of the build
finishing as activation gave up, not evidence of the window expiring.
Widening the health window to 5 minutes (generation 13) was therefore not the
fix. It is harmless and still reasonable, but it did not address this.
What still holds
The correlation with a cold build is real and now has three data points:
206e5d24(r-6f886ae6d099)206e5d24(r-2bace3d08cfa)f6506885(r-bc5da1aa5ded)f6506885(r-2e39c8f7b8d6)Same revision, same config, opposite outcomes — the only difference is whether
the release was already built. So building the release BEFORE the apply, which
is what this issue asks for, remains the right fix. It is now the difference
between a deploy that works and one that always fails on its first attempt.
What is still unknown
WHY the switch returns non-zero.
endo-deploy-bootstraplogs success and exits0, and
endo-daemonshowsResult=success, so the failing unit is not obviousfrom outside. Reading the systemd journal needs root and the daemon runs as its
own user, so the actual error is not visible from the agent side at all — a
failed deploy currently leaves no readable reason for anyone without root.
Capturing the
nixos-rebuildoutput intoapply.logis a prerequisite fordiagnosing this properly.
Deploy workflow never builds the Endo release, so a cold revision loses the health-check raceto Deploy workflow never builds the Endo release, so a cold revision always fails its first applyFixed, deployed, and exercised end to end.
Run
r-6a7ef1069be3was the first through the v2 chart, on a revision that hadnever been built:
The build happened in the prebuild stage with
currentuntouched, and the applywas a reuse in the same second. Generation 21, applied first try.
What landed
prebuildaction on the deploy spool — fetch andbuild a revision without flipping
currentor restarting the daemon.7fa3be2f):prebuildRevon the nixos-admin caplet, and theendo-releasechart at v2 —pin → prebuild → build → await-approval.A revision that will not build now costs an unpin, not an operator's attention
and not a rolled-back generation. Before this, a new revision could only be
deployed by proposing it twice and letting the first attempt fail.
Correction carried forward
The original report blamed
wait_healthy; that was wrong (see the correctioncomment above) — the switch itself was failing. Widening the health window to 5
minutes in generation 13 stays, but it was not the fix. WHY a cold-build
activation made
nixos-rebuild switchreturn non-zero is still unknown, and nowlargely moot: the build no longer happens during activation. Generations 17 and
18 added tee-ing of the switch and build output into
apply.log, so if itresurfaces there will be something to read.