fix(patch): gate phases on the window deadline, queue undelivered results, retry startup inventory
Agent Release / build (push) Successful in 3m40s
Agent Release / msi (push) Successful in 4m54s

The window deadline no longer kills a running package manager: it only gates
the start of each phase, and a started upgrade runs under a 2 hour backstop
that sends SIGTERM on Linux. A PatchResult whose send fails is queued and
flushed on the next command stream, retaking the reboot decision. deb822
folded Suites continuation lines are filtered with the field. The startup
static inventory report is retried until it succeeds.
This commit is contained in:
2026-09-15 13:43:03 +00:00
parent ecd703d502
commit b5b9775d2b
12 changed files with 404 additions and 46 deletions
+17
View File
@@ -140,6 +140,23 @@ deletes every other list file). apk and pacman have no security metadata and
report `unsupported`; security-only never falls back to installing
everything. One run at a time: a second command answers `busy`.
The deadline (`deadline_unix`, the window end) only gates the **start** of each
phase: the apt index refresh, the upgrade command, the Windows install script.
A phase that has not started by then is refused with "the maintenance window
ended before <phase> could start" (`canStart` in `internal/updates/phase.go`).
A started upgrade is never killed by the window: it runs under a 2 hour
backstop from its own start (`defaultApplyCap`), which on Linux sends SIGTERM
and waits 5 minutes before a kill. Interrupting a package manager mid-transaction
is worse than letting it finish late.
A `PatchResult` whose send fails (the command stream reconnected while the
patch ran) is kept in a bounded queue (32, oldest dropped) and flushed on the
next stream right after `AgentReady`. A queued result that announced a reboot
has the reboot decision taken again at flush time, and the host still reboots
only once the result is delivered. The startup static inventory report is
retried every 30 seconds, up to 10 attempts: it carries the boot time the
control plane uses to prove a patch reboot.
## Two constants that mirror the control plane
Neither can be shared - this is a separate module and the control plane's are