60 lines
3.9 KiB
Markdown
60 lines
3.9 KiB
Markdown
# felhom.eu — task reports
|
|
|
|
> **Overwrite** this file with a summary of the most recent task only (uniform with the other repos; not cumulative). The cumulative hub history lives in [hub/CHANGELOG.md](hub/CHANGELOG.md); the scripts history lives in [scripts/CHANGELOG.md](scripts/CHANGELOG.md).
|
|
|
|
## Hub v0.61.0 + felhom-tenantsync v1.1.0 — Customer RESET (middle lifecycle tier) — 2026-07-17
|
|
|
|
**Commits:** `4009401` (code), `e144c5e` (manifest). **Live:** hub **0.61.0** on k3s (Synced/Healthy);
|
|
felhom-tenantsync **v1.1.0** on ep0 (`felhom-hetzner`).
|
|
|
|
### What shipped
|
|
|
|
The **middle lifecycle tier** between *host delete* and *customer Delete*. One operator action returns a
|
|
customer to **pre-first-install**: every OPERATIONAL trace dies — offsite repo (Hetzner sub-account/box),
|
|
PBS namespace + all backup groups + token, DR recipe, one-time secret, claim state, retained escrow
|
|
custody — while **identity + basic config survive** (`customer_configs` incl. the offsite tier CHOICE, all
|
|
provenance rows, and the audit-event stream).
|
|
|
|
Viktor's rulings, all implemented: (1) destroying retained escrow custody gets its **own separate
|
|
acknowledgment**; (2) RESET clears claim state → fresh code next onboarding; (3) RESET **refuses while any
|
|
host row exists** (delete hosts first — reset never deletes hosts); (4) the confirm surface shows a
|
|
**live-counted** inventory.
|
|
|
|
### Discipline
|
|
|
|
External teardown FIRST, DB purge LAST (publish-last). Every leg idempotent → a partial run is re-run from
|
|
the top; a failed external leg is a clean journal entry and the DB purge (which erases the descriptors that
|
|
say what still needs tearing down) is **withheld** until every external leg is `ok`. Provenance + events
|
|
are never wiped.
|
|
|
|
### Components
|
|
|
|
- **store/customer_reset.go**: `customer_resets` journal (per-attempt, per-leg, resumable);
|
|
`CustomerResetInventory` (live counts incl. retained blobs via the F-14 `host_deletions` UNION);
|
|
`Start/UpdateResetLeg/Finish/LatestCustomerReset`; ack-gated `PurgeCustomerResetDBState`; `DeleteClaim`.
|
|
- **claim.ResetToUnclaimed**: deletes the claim row → `EnsureIssued` mints a fresh first code next onboarding.
|
|
- **offsite**: `Deprovision` (idempotent label-lookup delete), `OffsiteIdentifier`, `ClearProvisionedDescriptor`.
|
|
- **tenantsync + scripts/felhom-tenantsync.sh v1.1.0**: `deprovision` op destroys the namespace + backup
|
|
groups + token; shared `felhom@pbs` user untouched; idempotent.
|
|
- **web/customer_reset.go**: `GET /configs/{id}/reset` → inventory JSON; `POST` → orchestration (all gates
|
|
before any write/external call). A distinct **amber** RESET card + `reset_done` flash.
|
|
|
|
### Verification
|
|
|
|
- **Green gate:** `go build ./... && go vet ./... && go test ./...` all pass. Hub confirm gate OK.
|
|
- **Red-proofs (run-fail-revert, both proven red then restored):** (a) escrow-ack gate — defeat it →
|
|
reset proceeds & destroys blobs → FAIL; (b) partial-failure resumability — don't withhold the purge →
|
|
DB purged despite an external failure → FAIL. Plus store ack-gating + journal round-trip; offsite
|
|
Deprovision idempotency + descriptor clear; RESET-card render.
|
|
- **Live drill on ep0 (throwaway `drill-reset-01`, real PBS data):** provision → **real backup written into
|
|
the namespace** → deprovision (`deleted:true`; namespace + backup group + token destroyed) → token/ns
|
|
confirmed gone → idempotent re-run (`deleted:false`) → **all 3 real tenants + the shared user survived**.
|
|
|
|
### Not live-drilled (covered otherwise)
|
|
|
|
The web RESET POST and the Hetzner sub-account delete are covered by the httptest-driven orchestration
|
|
tests + offsite unit tests (the offsite `Deprovision` faithfully mirrors the live-proven
|
|
`ReissueCredentials`, swapping reset→delete). The hub UI is operator-password-gated → CC verifies the UI
|
|
via render tests, not a live click. A live Hetzner create/delete drill was not run (billed external
|
|
service; mirror-of-live-proven + idempotency-tested).
|