Files
felhom-controller/REPORT.md
T
2026-06-14 20:17:47 +02:00

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 main was c37ee6d = v0.64.0 → shipped v0.65.0.
  • Agent main was 8e6d00a = 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/decommission mirroring eject (user-data role gate, no signature, never formats): intent=decommissioned + bind-prune + unmount. ReassertGuestBinds is now intent-aware (skips non-enrolled) — the F9-reconnect correctness fix. Operator-signed path untouched.
  • B2bhandleStorageDecommission (migrate-all-or-none): migrate-then-decommission via the migration done-hook, or decommission-anyway (stop apps, keep HDD_PATH). agentapi.Decommission added. Soft-marker retained. Change 4: re-enroll clears the marker (ClearDecommissioned had 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.go guard 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, --version 0.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 in guest-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.