cbaa53f565
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5.3 KiB
5.3 KiB
REPORT — TASK B1+B2 data migration + self-serve decommission → controller v0.65.0 (2026-06-14)
Customer-self-serve storage migration (move app data between drives) and decommission (retire a
drive), implemented trunk-based on main against the locked spike design
(felhom.eu/documentation/audits/SPIKE-decommission-migration-2026-06-14.md). Pairs with agent
v0.32.0. Each change carries non-hollow tests; the load-bearing companions were mutation-proven to
fail on the pre-fix code. Built + deployed both images to demo guest 9201 / felhom-pve.
Validate against pushed source, not this report. Live decommission/migration of real data is NOT yet validated — that is the supervised B3 session (see the end).
Confirmed baselines
- Controller
mainwasc37ee6d= v0.64.0 → shipped v0.65.0. - Agent
mainwas8e6d00a= v0.31.0 → shipped v0.32.0.
Commits (controller repo unless noted)
| # | Commit | Scope |
|---|---|---|
| 1 | b57150e |
B1 migration engine (internal/stacks/migrate.go, MigrateAll+MigrateApp) + tests + main wiring + backup mutual-exclusion (Change 3) |
| 2 | 16a4c3e |
B1 UI — /api/storage/migrate{,-app,/status} + settings.html & app_info.html + progress panel |
| 3 | f43697c (felhom-agent) |
v0.32.0 — POST /disks/decommission + intent-aware ReassertGuestBinds + GuestBindStore.Remove + tests |
| 4 | f2596ea |
B2b decommission orchestration + "Hiányzó tárhely" indicator + Change 4 re-enroll fix + tests |
What shipped
- B1 engine — crash-safe, resumable, journaled (
<dataDir>/migration.json). Pipeline validate → stop → copy (rsync -a --checksum, additive, no--delete; conflict-merge walk for non-app content) → verify (rsync -ani --checksum, zero pending) → flip+redeploy (RedeployFromEnv) → cleanup gated on all-verified AND all-redeployed. Two entry points (whole-namespace + per-app incl. SSD→drive) over one pipeline. Single-flight; mutually exclusive with the backup orchestrator (migration refuses while a backup runs; scheduled DB-dump/Tier-2 skip while a migration runs). - B1 UI — migrate-all (settings page) + per-app "Áthelyezés másik tárhelyre" (app-info page) + shared status poll/progress panel.
- B2a (agent) — self-serve
POST /disks/decommissionmirroring eject (user-data role gate, no signature, never formats): intent=decommissioned + bind-prune + unmount.ReassertGuestBindsis now intent-aware (skips non-enrolled) — the F9-reconnect correctness fix. Operator-signed path untouched. - B2b —
handleStorageDecommission(migrate-all-or-none): migrate-then-decommission via the migration done-hook, or decommission-anyway (stop apps, keep HDD_PATH).agentapi.Decommissionadded. Soft-marker retained. Change 4: re-enroll clears the marker (ClearDecommissionedhad zero callers before). "Hiányzó tárhely" badge for apps on a missing drive.
Tests (per-commit green: go build && go vet && go test ./...)
internal/stacks/migrate_test.go— siblingName, conflict-merge (differ→(1), identical→dedup, re-run idempotent no(1)(1), 3rd→(2)), assert-only verify, skip-dirs, cleanup-only-after-redeploy (+companion: redeploy-fail → source intact), verify-catches-corruption, resume (no re-copy), collision-refused, backup-exclusion, single-flight, SSD→drive resolution, cleanup gate.internal/backup/migration_exclusion_test.go— scheduled DB-dump skipped while migrating.internal/web/decommission_test.go— finalize soft-marks + calls agent (entry retained), re-enroll clears marker (Change 4), missing-storage label, unflagged-migration no-op.- Mutation-proven companions (fail on pre-fix, pass after revert): migration collision guard, cleanup
gate, Change-4 re-enroll clearing, and (agent) the intent-aware reassert (
disks.goguard removed → decommissioned drive re-bound → test FAILS).
Build / deploy / verify
- Built+pushed
gitea.dooplex.hu/admin/felhom-controller:0.65.0(192.168.0.180); deployed to guest 9201 via golden/bootstrap →docker ps::0.65.0 Up (healthy), clean startup (controller_started (0.65.0), no errors),GET /api/storage/migrate/status→{"job":null}(idle, wired). - Built agent v0.32.0 on 180; installed on felhom-pve (
/usr/local/bin/felhom-agent, backup.bak-0.31.0),systemctl restart felhom-agent→ active,--version0.32.0. - Live-proven (incidental, safe): on agent restart the new intent-aware re-assert logged
F9 re-assert: skipping non-enrolled drive (intent-gated) vmid=9201 durable_id=uuid:ce9d… intent=ejected— the exact drive that lingered inguest-binds.json(B0 spike finding) is now correctly NOT re-bound.
NOT yet live-validated — awaiting supervised B3
The real end-to-end UI flow with actual data was deliberately NOT run (per the task STOP):
- put data on a drive → decommission (migrate-to-another OR decommission-anyway) → verify data integrity end-to-end → drive un-enrolled and does NOT auto-mount/re-bind on reconnect → orphaned apps show "Hiányzó tárhely" → re-enroll clears it. Operator-present, real UI (no agent/CLI shortcuts, per the A4 rule). The engine/endpoint logic is unit-proven and the intent-aware reassert is already proven live by the restart log above; the data-bearing round-trip is what B3 covers.