fix: harden embedded Pi lifecycle recovery
This commit is contained in:
@@ -75,7 +75,10 @@ Before inventory, update activates the durable maintenance gate. Activation writ
|
||||
all leases. A recreated candidate reads that marker at startup and therefore starts gated. The
|
||||
loopback-only control endpoints cannot be reached through the frontend proxy and do not depend on
|
||||
the configured authentication principal mode. Lost activation/deactivation responses are resolved
|
||||
by querying gate status.
|
||||
by querying gate status only when the original result is unknown. An explicit file or directory
|
||||
durability failure is never converted to success by matching readback: the control API reports
|
||||
`maintenance_durability_failed`, keeps or restores the safest durable marker state, and requires
|
||||
recovery.
|
||||
|
||||
Open, unarchived sessions stop an update. After an operator has completed or otherwise drained
|
||||
their work, `--drain` makes the command poll the authenticated bare-array
|
||||
@@ -91,9 +94,10 @@ Rollback atomically promotes the previous selector. Terminal cleanup removes onl
|
||||
files and never deletes the durable selector.
|
||||
|
||||
Only `core` is recreated, with `--no-deps --force-recreate`; `frontend` is not recreated and no
|
||||
volume-replacement flags are used. Verification checks health, exact requested Pi version, the
|
||||
provider/model/settings smoke, unchanged non-secret rendered configuration, and the complete
|
||||
persistence-mount fingerprint.
|
||||
volume-replacement flags are used. Verification checks health; exact requested Pi version at all
|
||||
three declared boundaries (the candidate executable, `PI_VERSION` environment, and
|
||||
`org.opencontainers.image.version` image label); the provider/model/settings smoke; unchanged
|
||||
non-secret rendered configuration; and the complete persistence-mount fingerprint.
|
||||
|
||||
## Recovery, rollback, and maintenance cleanup
|
||||
|
||||
@@ -114,6 +118,11 @@ Any post-candidate failure explicitly confirms or reactivates maintenance and re
|
||||
before compensation. Automatic rollback selects the transaction's previous image through the
|
||||
lifecycle override and clears maintenance only after the previous image, configuration, mounts,
|
||||
health, Pi smoke, and terminal recovery write are verified. Ambiguous compensation remains gated.
|
||||
If the candidate core is stopped and cannot serve the maintenance endpoint, rollback proves that
|
||||
state with Compose and writes the marker through a one-off previous-image `core` container sharing
|
||||
the settings volume. It does not require the failed candidate, a host Node runtime, or the Docker
|
||||
socket inside a container. The restored core is then recreated, verified, and rescanned before the
|
||||
gate can open.
|
||||
|
||||
For an interrupted transaction, first run:
|
||||
|
||||
@@ -140,12 +149,22 @@ Missing confirmation, invalid arguments, active sessions, and an interrupted tra
|
||||
`2`. Docker and verification failures exit nonzero with concise, redacted guidance. Direct
|
||||
read-only/log commands preserve the original Docker child exit code.
|
||||
|
||||
## Go 1.24 dependency security boundary
|
||||
## Go dependency security boundary
|
||||
|
||||
`golang.org/x/sys` is a direct dependency for the Windows durable-replace implementation. The
|
||||
newest release compatible with the required Go 1.24 toolchain is pinned (`v0.41.0`). Releases
|
||||
`v0.42.0` through `v0.44.0` require Go 1.25, so `v0.44.0` cannot be selected without changing the
|
||||
product toolchain contract. Govulncheck reports GO-2026-5024 at module level for `v0.41.0`, but no
|
||||
thothctl call trace reaches the vulnerable `windows.NewNTUnicodeString`; thothctl calls only
|
||||
`UTF16PtrFromString` and `MoveFileEx` in that package. Upgrade to at least `v0.44.0` together with
|
||||
the planned Go 1.25-or-newer toolchain migration.
|
||||
The supported toolchain is Go `1.26.5`, released 2026-07-07, with module language version
|
||||
`1.26.0`. The Docker builder is pinned by both patch tag and the multi-platform manifest-list
|
||||
digest:
|
||||
|
||||
```text
|
||||
golang:1.26.5-bookworm@sha256:1ecb7edf62a0408027bd5729dfd6b1b8766e578e8df93995b225dfd0944eb651
|
||||
```
|
||||
|
||||
That manifest provides both `linux/amd64` and `linux/arm64/v8` builders. Go's official release
|
||||
history is the authority for the patch level (`https://go.dev/doc/devel/release`); the Docker
|
||||
Official Image is the authority for the builder (`https://hub.docker.com/_/golang`).
|
||||
`golang.org/x/sys`, used by the Windows durable-replace implementation, is pinned to `v0.47.0`.
|
||||
The directly used `github.com/sirupsen/logrus` is pinned to `v1.9.1`, which removes
|
||||
GO-2025-4188 from the imported package set. The build contract verifies the exact toolchain,
|
||||
dependencies, digest, and all five supported target builds (Windows amd64, Darwin amd64/arm64, and
|
||||
Linux amd64/arm64). `go mod verify`, tests including the race detector, `go vet`, and
|
||||
`govulncheck` are release gates.
|
||||
|
||||
Reference in New Issue
Block a user