B2b: decommission orchestration + missing-storage indicator + re-enroll fix (v0.65.0)
agentapi.Decommission + handleStorageDecommission (migrate-all-or-none, Change 2): migrate-then-decommission via the migration done-hook, or decommission-anyway (stop apps, keep HDD_PATH). 'Hiányzó tárhely' badge on dashboard/stacks/app card when an app's drive is decommissioned/disconnected/absent. Change 4: registerStoragePath clears the decommissioned marker on re-enroll (ClearDecommissioned had no callers). Non-hollow tests incl. mutation-proven Change-4 companion. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,48 @@
|
||||
## Changelog
|
||||
|
||||
### v0.65.0 — data migration + self-serve decommission (B1+B2) (2026-06-14)
|
||||
|
||||
Customer-self-serve storage **migration** (move app data between drives) and **decommission** (retire
|
||||
a drive), implemented trunk-based with the locked spike design
|
||||
(`felhom.eu/documentation/audits/SPIKE-decommission-migration-2026-06-14.md`). Pairs with agent
|
||||
v0.32.0 (the self-serve `/disks/decommission` endpoint + intent-aware re-assert). Built + deployed to
|
||||
demo guest 9201. **Live decommission/migration of real data is NOT yet validated — that is the
|
||||
supervised B3 session.**
|
||||
|
||||
- **B1 — migration engine** (`internal/stacks/migrate.go`). In-process over the controller's
|
||||
`/mnt:/mnt:rslave` RW mount; crash-safe + resumable via a single journal (`<dataDir>/migration.json`).
|
||||
Two entry points share one pipeline: `MigrateAll` (whole namespace — every app + a conflict-merge
|
||||
walk for non-app/customer content) and `MigrateApp` (one app subtree; handles drive→drive AND
|
||||
SSD→drive). Pipeline: validate → stop → copy (`rsync -a --checksum`, additive, NO `--delete`) → verify
|
||||
(`rsync -ani --checksum`, zero pending) → flip+redeploy (`RedeployFromEnv`, one idempotent unit) →
|
||||
cleanup. **CLEANUP is the only destructive step and is gated on every unit verified AND every app
|
||||
redeployed.** Conflict-merge: skip-identical (checksum vs the target file AND its `(N)` siblings),
|
||||
rename-on-differ to the lowest-free `<base>(N)<ext>`, never overwrite; idempotent (no `(1)(1)`).
|
||||
Single-flight; **mutual exclusion with the backup orchestrator** (Change 3 — migration refuses while a
|
||||
backup runs; the scheduled DB-dump/Tier-2 skip while a migration runs).
|
||||
- **B1 UI** — `POST /api/storage/migrate` (whole-namespace), `POST /api/storage/migrate-app` (per-app),
|
||||
`GET /api/storage/migrate/status` (poll). The greyed migrate-all `<span>` in settings.html is now a
|
||||
real target-select + button; app_info.html gains a per-app "Áthelyezés másik tárhelyre" control; both
|
||||
share a Hungarian progress panel.
|
||||
- **B2b — decommission orchestration** (`handleStorageDecommission`, `POST /api/storage/decommission`).
|
||||
Two choices, no partial (Change 2): **migrate-all-then-decommission** (runs `MigrateAll`; the
|
||||
migration done-hook soft-marks the source + calls the agent once every app has moved) or
|
||||
**decommission-anyway** (type-to-confirm; stops the apps but KEEPS their `HDD_PATH` so they show
|
||||
"missing storage"). `agentapi.Decommission` added; both branches end at `SetDecommissioned` (soft
|
||||
marker retained — blocks A1 resurrection) + agent `Decommission`.
|
||||
- **"Hiányzó tárhely" indicator** — a deployed app whose `HDD_PATH` resolves to a decommissioned/
|
||||
disconnected/absent registry path now shows a distinct warning badge on the dashboard, stacks page,
|
||||
and app card (label via `GetStorageLabel`); persists until re-enroll or migrate.
|
||||
- **Change 4 — re-enroll clears the marker.** `registerStoragePath` now un-retires a re-plugged
|
||||
decommissioned drive (`ClearDecommissioned` + restore `Schedulable`) — previously `AddStoragePath`
|
||||
deduped the re-register into a no-op and the soft marker (and the apps' missing-storage badge) would
|
||||
persist forever. (`ClearDecommissioned` had zero callers before this.)
|
||||
- Non-hollow tests across `internal/stacks` (engine: collision-refuse, merge dedup/idempotency,
|
||||
cleanup-only-after-redeploy, verify-catches-corruption, resume, single-flight, SSD→drive, backup
|
||||
exclusion), `internal/backup` (scheduled backup skipped while migrating), and `internal/web`
|
||||
(finalize soft-mark+agent, re-enroll clears marker, missing-storage label). Companions for the
|
||||
collision guard, cleanup gate, and Change-4 clearing were mutation-proven to fail on the pre-fix code.
|
||||
|
||||
### v0.64.0 — storage-lifecycle cleanups (2026-06-14)
|
||||
|
||||
Two settings-layer cleanups from the F9 storage-registration diagnosis
|
||||
|
||||
Reference in New Issue
Block a user