E-2 Part 1: the backup-target role on StoragePath (foundation, not yet wired)
Foundation only, no version bump -- nothing customer-visible changes yet. The
offer UI (Part 3), the degraded banner (Part 4) and the controller half of the
absent-target signal (Part 5) are NOT here; they are tracked as E-2 in
OPEN-ITEMS.md so this cannot become a sixth "seam built but never wired". The
fifth was found by E-2's own Phase 0: NotifyStorageDisconnected is defined and
called nowhere, so a drive going absent emits no event at all today.
StoragePath gains BackupTarget bool -- the sibling role to Schedulable/
IsDefault/Kind. It is INTENT, not truth: the authority is the agent's
backup.local_backup_target, and truth is read from GET /backup/tiers. This
records what the customer ASSIGNED so the controller can render the state,
notice the drive going absent, and detect drift.
Invariants, each pinned by a test asserting the CONSEQUENCE not the mechanism:
- a drive NEVER acquires the role by appearing (registration does not set it)
- exactly one carrier; assigning moves rather than duplicates
- sticky: a new bigger/faster drive does not steal an assigned target
- an absent target STAYS assigned -- clearing on disconnect would be a silent
retarget by omission ("no target configured" instead of "drive missing")
- a network share is refused (R-108 risk model; the role is about LOCAL disk
failure)
Red-proof C: adding auto-elevation to AddStoragePath fails
TestRegisteringDrivesNeverAssignsTheBackupTarget with
registering drives assigned the backup target "/mnt/hdd_1"
Attributes may suggest and refuse the absurd, never select: demo-felhom's backup
drive is an external USB HDD and BOTH demo boxes report removable=0, so a
transport rule disqualifies the reference drive and a removable rule finds no
candidate at all.
Green gate: build + vet + test rc=0, run separately from this commit.
This commit is contained in:
@@ -1,5 +1,42 @@
|
||||
## Changelog
|
||||
|
||||
### UNRELEASED — E-2 Part 1: the backup-target role (foundation; NOT yet wired to a UI)
|
||||
|
||||
**Status: foundation only. No version bump — nothing customer-visible changes yet.** The field is
|
||||
written by `SetBackupTarget` and read by `BackupTargetPath`/`BackupTargetAssigned`, and by nothing
|
||||
else. **The offer UI (Part 3), the degraded banner (Part 4) and the absent-target signal's
|
||||
controller half (Part 5) are NOT in this commit** — tracked as E-2 in `OPEN-ITEMS.md` so this cannot
|
||||
become a sixth "seam built but never wired" (the fifth, `NotifyStorageDisconnected`, was found by
|
||||
E-2's own Phase 0 and is one of the things still to wire).
|
||||
|
||||
`StoragePath` gains `BackupTarget bool` — the sibling role to `Schedulable`/`IsDefault`/`Kind`,
|
||||
marking the drive the whole-guest vzdump is written to.
|
||||
|
||||
**It is INTENT, not truth.** The authority is the agent's `backup.local_backup_target`; this records
|
||||
what the customer ASSIGNED so the controller can render the state, notice the drive going absent,
|
||||
and detect drift. Truth comes from the agent's `GET /backup/tiers`.
|
||||
|
||||
Invariants, each pinned by a test asserting the CONSEQUENCE rather than the mechanism:
|
||||
|
||||
- **A drive never acquires the role by appearing.** Registration does not set it; only an explicit
|
||||
customer choice through `SetBackupTarget` does. Red-proofed: adding auto-elevation to
|
||||
`AddStoragePath` fails `TestRegisteringDrivesNeverAssignsTheBackupTarget` with
|
||||
`registering drives assigned the backup target "/mnt/hdd_1"`.
|
||||
- **Exactly one carrier** — assigning moves the role rather than duplicating it.
|
||||
- **Sticky** — a new, bigger, faster drive appearing does not steal an assigned target.
|
||||
- **An absent target stays assigned.** Clearing on disconnect would be a silent retarget by
|
||||
omission: the box would read "no target configured" instead of "your target drive is missing".
|
||||
- **A network share is refused** — the role exists to survive a LOCAL disk failure, and a remote,
|
||||
credential-bound share mounted at its own root (R-108) is a different risk model.
|
||||
|
||||
Attributes may suggest and may refuse the absurd; they may never select. The reference hardware
|
||||
settles it: demo-felhom's backup drive is an external **USB HDD**, and **both** demo boxes' drives
|
||||
report `removable=0` — a transport rule would disqualify the reference drive, a removable rule would
|
||||
find no candidate at all.
|
||||
|
||||
Green gate: `go build` + `go vet` + `go test ./internal/{settings,web,quiesce}` all rc=0, run
|
||||
separately from the commit.
|
||||
|
||||
### v0.183.0 — C9-F1 + C9-F2: a restore that restored nothing, and a crash loop nobody saw (2026-07-28)
|
||||
|
||||
Both are the same shape — the system reporting healthy while the customer is not — and both were
|
||||
|
||||
Reference in New Issue
Block a user