v0.75.0: gate userdata MkdirAll on a live mountpoint (no writes into an absent drive)
Belt (ensureUserdataMounts) + FileBrowser sync skip ensure/mount when an external drive root is not a live mountpoint -> no 'mkdir userdata: permission denied' + no rootfs-shadow during a drive-absent window. System/local path never gated. Reuses system.IsMountPoint; matches planDriveGates external-only rule. T1-T4 + red-proofs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,26 @@
|
||||
## Changelog
|
||||
|
||||
### v0.75.0 — gate userdata MkdirAll on a live mountpoint (no writes into an absent drive) (2026-06-22)
|
||||
|
||||
**Bugfix — two `MkdirAll`-into-`<drive>/userdata` sites fired without checking the drive was mounted**,
|
||||
producing `mkdir …/userdata: permission denied` + transient `Created` flapping during a drive-absent
|
||||
window (campaign-#2 findings #2/#3). Worse than noise: writing into an unmounted mountpoint lands app
|
||||
data on the guest **rootfs**, shadowed when the drive returns (data-integrity + rootfs-fill hazard).
|
||||
|
||||
- `internal/stacks/manager.go` — `ensureUserdataMounts` (the deploy belt) now skips when the
|
||||
`HDD_PATH` drive root is an **external** path (not `sysDataPath`) that is **not a live mountpoint**;
|
||||
the app is held by `planDriveGates` instead. New injectable `Manager.isMountPoint` seam (defaults to
|
||||
`system.IsMountPoint`) for testability. The system/local path is never gated (it's legitimately not a
|
||||
mountpoint).
|
||||
- `internal/web/handlers.go` — the FileBrowser sync loop skips (and does not mount) a registered path
|
||||
under `StableParentDir` that isn't a live mountpoint, via a new pure `skipFileBrowserPath` helper.
|
||||
Matches `planDriveGates`' external-only rule.
|
||||
- `EnsureUserdataDir`/`EnsureUserdataSkeleton`/`planDriveGates` unchanged (gated the callers).
|
||||
- Tests: `TestEnsureUserdataMounts_{SkipsAbsentExternalDrive,EnsuresWhenMounted,SystemPathNeverSkipped}`
|
||||
+ `TestSkipFileBrowserPath` (both red-proofed against the pre-fix code).
|
||||
- **Boot-time** occurrence (docker boot-restore starting drive-backed apps before the agent mounts the
|
||||
drives) is a separate cause — documented as a design note (CONTEXT.md), not changed here.
|
||||
|
||||
### v0.74.0 — fix the controller→agent connection leak (per-call agentapi client) (2026-06-22)
|
||||
|
||||
**Bugfix — agent local-API socket leak that took down the whole agent-backed feature set after ~5 days.**
|
||||
|
||||
Reference in New Issue
Block a user