v0.308.0 (R-554, held-back-able): recovery-info.txt points at the dashboard's Restore page and the recovery code; the first-boot setup wizard is deleted
Operator ruling 2026-10-12 (S27, 09 §3 decision 222). The operator approves the Hungarian text before release. A box whose first ingestion failed now serves one bilingual waiting page and retries every minute instead of the wizard. Own commit so the lead can hold it back. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
+24
-104
@@ -112,7 +112,7 @@ backups, monitoring and notifications. All Proxmox/disk operations are delegated
|
||||
component; state chips are `.tag`; informational pills are `.metarow`. **Fonts (Plus Jakarta Sans +
|
||||
JetBrains Mono, variable woff2, latin+latin-ext) and a 30-icon Lucide sprite are vendored in the
|
||||
binary** (`internal/web/static/fonts/` served at `/static/fonts/`; `templates/icons.html`) — no CDN,
|
||||
no emoji. The setup wizard serves the same embedded stylesheet via `web.StyleCSS()`.
|
||||
no emoji.
|
||||
- **Guest RAM resize (v0.143.0, R-24; MinAgent 0.90.0)** — the Rendszer page's "Szerver memória (RAM)"
|
||||
card shows the guest's current/used memory + the allowed range and lets the customer resize it. The
|
||||
controller only proxies + maps the agent's machine `code` to Hungarian; **the agent (felhom-agent
|
||||
@@ -3364,77 +3364,18 @@ The hub service (separate Go app in the `felhom.eu` repo) provides:
|
||||
- Color coding: green (<30min), yellow (30-60min), red (>60min since last report)
|
||||
- 90-day report + event retention with daily prune at 04:30 Budapest time
|
||||
|
||||
### 10. First-Run Setup Wizard
|
||||
### 10. Not configured yet — the waiting page (the setup wizard is deleted, v0.308.0, R-554)
|
||||
|
||||
When the controller starts with no valid customer configuration (`customer.id` empty), it enters **setup mode** — a web-based wizard that handles all initial configuration. This replaces the old interactive shell wizard in `docker-setup.sh`.
|
||||
|
||||
#### Setup Mode Detection (`internal/setup/setup.go`)
|
||||
|
||||
`NeedsSetup(cfg)` returns true when `customer.id` is empty or a `.needs-setup` marker file exists. In setup mode, the controller skips normal startup (no scheduler, no backup, no stacks) and serves only the wizard UI on two listeners:
|
||||
- `:8080` — behind Traefik (accessible via domain, e.g. `https://felhom.example.com`)
|
||||
- `:8081` — direct HTTP (accessible via LAN IP, e.g. `http://192.168.0.100:8081`)
|
||||
|
||||
#### Wizard Flow
|
||||
|
||||
```
|
||||
┌──────────────────────────────────┐
|
||||
│ 1. Welcome │
|
||||
│ Choose: Restore / Fresh install │
|
||||
└─────────┬───────────┬────────────┘
|
||||
│ │
|
||||
┌─────▼─────┐ ┌──▼───────────────┐
|
||||
│ 2a. Scan │ │ 2b. Hub download │
|
||||
│ drives for│ │ (customer ID + │
|
||||
│ local │ │ password) │
|
||||
│ backups │ │ │
|
||||
└─────┬─────┘ └──────┬────────────┘
|
||||
│ │
|
||||
┌─────▼─────┐ │
|
||||
│ 2a.2 Hub │ │
|
||||
│ recovery │ │
|
||||
│ (fallback)│ │
|
||||
└─────┬─────┘ │
|
||||
│ │
|
||||
┌─────▼─────┐ ┌──────▼───────────┐
|
||||
│ Execute │ │ Execute fresh │
|
||||
│ restore │ │ install │
|
||||
└─────┬─────┘ └──────┬───────────┘
|
||||
│ │
|
||||
└───────┬───────┘
|
||||
▼
|
||||
os.Exit(0) → Docker restarts
|
||||
→ normal mode
|
||||
```
|
||||
|
||||
#### Hub Pre-Seeding
|
||||
|
||||
When `docker-setup.sh` is run with `--hub-customer` / `--hub-password`, the controller receives
|
||||
pre-seeded credentials via environment variables:
|
||||
|
||||
| Env var | Purpose |
|
||||
|---------|---------|
|
||||
| `FELHOM_SETUP_CUSTOMER_ID` | Pre-fills customer ID in wizard forms |
|
||||
| `FELHOM_SETUP_PASSWORD` | Pre-fills retrieval password for auto-processing |
|
||||
|
||||
In hub mode, the welcome page shows three cards instead of two:
|
||||
1. **"Visszaállítás a Hub-ról"** — auto-calls `PullRecovery()`, shows infra backup details
|
||||
2. **"Visszaállítás helyi meghajtóról"** — standard drive scan
|
||||
3. **"Friss telepítés"** — auto-calls `PullConfig()`, downloads config only
|
||||
|
||||
Both hub paths auto-process when credentials are pre-seeded (no form entry needed).
|
||||
On error, the wizard falls back to the manual form with the error displayed.
|
||||
|
||||
#### Key Components
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `setup/setup.go` | `NeedsSetup()` detection, `SetupState` persistence to `setup-state.json` |
|
||||
| `setup/handlers.go` | HTTP handlers for each wizard step (welcome, scan, hub-restore, fresh, manual) |
|
||||
| `setup/scanner.go` | Scans all block devices for `.felhom-infra-backup/` directories (current + `history/`) via `lsblk` + temp mounts; returns rich info (app names, disk count) |
|
||||
| `setup/hub.go` | Hub recovery pull (`GET /api/v1/recovery/{id}`) and config download |
|
||||
| `setup/csrf.go` | Lightweight CSRF protection (cookie + hidden field, `SameSite=Strict`) |
|
||||
| `setup/network.go` | Detects local IPs for LAN access URL display |
|
||||
| `setup/templates/` | 8 embedded HTML templates (Hungarian, dark theme matching main UI) — includes `setup_hub_versions.html` for Hub backup version picker |
|
||||
The host agent provisions every box: at first boot the controller ingests its configuration from the hub
|
||||
(`internal/bootstrap`, `MaybeIngest`). The first-boot **setup wizard** (`internal/setup/`, the docker-setup.sh era,
|
||||
port 8081) was obsolete by design (`02-controller-module-map.md`) and is **deleted** (`09` §3 decision 222). A box whose
|
||||
ingestion failed (no or bad `bootstrap.json`, a hub it cannot reach, a failed write) — `bootstrap.Unconfigured(cfg)`,
|
||||
i.e. `customer.id` empty — now serves ONE page on its listener, in both languages („A Felhom még nem érte el a
|
||||
központot" / "Felhom has not reached the central service yet"), answers `/api/health` with
|
||||
`waiting_for_hub: true`, and retries the ingestion every minute (`bootstrap.WaitForConfig`). Once configured it closes
|
||||
the page and starts normally on the same listener. The `.needs-setup` marker and the debug page's „DR / Telepítő
|
||||
varázsló" trigger are gone; `web.setup_listen` is still read so an old `controller.yaml` loads, and is unused.
|
||||
Pinned by `TestWaitForConfig_ServesWaitingPageThenStarts`.
|
||||
|
||||
#### Local Infra Backup (`internal/backup/local_infra.go`)
|
||||
|
||||
@@ -3445,11 +3386,15 @@ The controller writes infrastructure snapshots to **every connected drive** afte
|
||||
- `{timestamp}-backup.json` + `{timestamp}-metadata.json` pairs (timestamp format: `20060102T150405Z`)
|
||||
- Oldest entries pruned when count exceeds 5
|
||||
|
||||
During setup wizard drive scan, both current and historical backups are discovered, integrity-verified, and offered for one-click restore. The scan results table shows app names/count, disk count, and a "korábbi" badge for historical versions.
|
||||
(The setup wizard's drive scan that offered these for one-click restore is deleted, v0.308.0, R-554.)
|
||||
|
||||
#### Recovery Info (`internal/recovery/info.go`)
|
||||
|
||||
Generates `recovery-info.txt` on the system data partition with customer ID, Hub URL, retrieval password, and recovery instructions in Hungarian. Updated on startup and after config changes. Also displayed on the Settings page in a "Vészhelyzeti információk" section.
|
||||
Generates `recovery-info.txt` (0600) in the data directory at every start when a retrieval password is set: customer
|
||||
ID, Hub URL, retrieval password, support contacts, and — since v0.308.0 (R-554) — what to do: the dashboard's
|
||||
**Biztonsági mentés → Visszaállítás** page, and after a reinstall the **Adatok visszaszerzése** page with the
|
||||
household's recovery code (ten words). Written in the box's language from the bundle key `recovery_info.body`; it no
|
||||
longer points at the deleted setup wizard. Pinned by `TestRecoveryInfo_PointsAtDashboardNotWizard`.
|
||||
|
||||
**No secret is rendered into a page's response body (v0.207.0 + v0.208.0, R-249/R-254).** Three endpoints implement one rule — the page carries a BOOLEAN, the value comes from an explicit authenticated POST with `Cache-Control: no-store`, and the reveal is LOGGED (reading a value off markup left no trace at all):
|
||||
|
||||
@@ -3465,29 +3410,11 @@ They are deliberately **per-secret**, not one generic "reveal any named secret"
|
||||
|
||||
### 11. Disaster Recovery
|
||||
|
||||
When a system drive fails and is replaced, the recovery flow uses the setup wizard:
|
||||
|
||||
```
|
||||
1. docker-setup.sh deploys fresh controller with minimal config
|
||||
- With --hub-customer: credentials pre-seeded via env vars
|
||||
- Without: user enters credentials manually in wizard
|
||||
2. Controller detects empty customer.id → enters setup mode
|
||||
3. User opens wizard at http://<LAN-IP>:8081
|
||||
4. Hub mode: welcome page shows Hub restore / local scan / fresh install
|
||||
Non-hub mode: welcome page shows restore / fresh install
|
||||
5. Hub restore: auto-connects to Hub, shows version picker if multiple versions
|
||||
Local restore: scans all drives for .felhom-infra-backup/ directories (current + history/)
|
||||
6. User selects backup version → restore: config, settings, passwords, disk layout
|
||||
7. Controller restarts into normal mode with full config
|
||||
8. Controller auto-mounts surviving drives by UUID from disk layout
|
||||
9. Dashboard shows "Visszaállítás" (Restore) page for app-level recovery
|
||||
10. User confirms → sequential restore: rsync first, restic fallback, DB import
|
||||
```
|
||||
|
||||
**Backup sources (priority order):**
|
||||
1. **Local infra backup** (`.felhom-infra-backup/` on surviving drives) — fastest, no network needed
|
||||
2. **Hub recovery endpoint** (`GET /api/v1/recovery/{id}`) — requires retrieval password, supports `?version=ID` for specific versions; Hub retains ~14 versions via GFS pruning (7 daily / 4 weekly / 3 monthly)
|
||||
3. **Manual config** (wizard form) — enter all details manually as last resort
|
||||
Whole-guest recovery is the host agent's and the hub's (PBS restore, provisioning a replacement guest); the controller
|
||||
has no recovery wizard any more (R-554, v0.308.0). On a box that is running, an app is restored on the dashboard's
|
||||
**Biztonsági mentés → Visszaállítás** page. After a reinstall the earlier off-site backups are reopened on the
|
||||
**Adatok visszaszerzése** page (`/recovery`) with the household's recovery code. A box that cannot reach the hub at its
|
||||
first boot waits on the page described in §10.
|
||||
|
||||
**Hub verification:** After setup, the controller periodically verifies customer standing via the Hub report push response (`customer_blocked` field). If blocked or Hub unreachable for >7 days, the controller enters limited mode (no new deployments).
|
||||
|
||||
@@ -4259,13 +4186,6 @@ controller/
|
||||
│ │ ├── builder.go # Hub report builder (all subsystems → JSON)
|
||||
│ │ ├── pusher.go # HTTP POST to hub (retry, Bearer auth, parses customer_blocked)
|
||||
│ │ └── infra_pull.go # DR: pull recovery/config from Hub (retrieval password auth)
|
||||
│ ├── setup/ # First-run setup wizard (web-based, replaces docker-setup.sh wizard)
|
||||
│ │ ├── setup.go # NeedsSetup() detection, state persistence
|
||||
│ │ ├── handlers.go # HTTP handlers for all wizard steps
|
||||
│ │ ├── scanner.go # Drive scanner for local infra backups
|
||||
│ │ ├── csrf.go # Lightweight CSRF (cookie + hidden field)
|
||||
│ │ ├── network.go # Local IP detection for LAN access URLs
|
||||
│ │ └── templates/ # 7 wizard HTML templates (Hungarian)
|
||||
│ ├── recovery/info.go # Recovery info file generator (recovery-info.txt)
|
||||
│ └── web/
|
||||
│ ├── server.go # HTTP server, routing, static files, catch-all middleware, executeTemplate wrapper
|
||||
@@ -4363,7 +4283,7 @@ monitoring:
|
||||
|
||||
web:
|
||||
listen: ":8080"
|
||||
setup_listen: ":8081" # Plain HTTP for setup wizard LAN access
|
||||
setup_listen: ":8081" # UNUSED since v0.308.0 (the setup wizard is deleted, R-554)
|
||||
|
||||
hub:
|
||||
enabled: true
|
||||
|
||||
Reference in New Issue
Block a user