diff --git a/controller/README.md b/controller/README.md index 1aeaa13..52636f6 100644 --- a/controller/README.md +++ b/controller/README.md @@ -4,7 +4,7 @@ A single, lightweight Go container that replaces Portainer + scattered systemd scripts with a unified, Hungarian-language web dashboard for managing Docker Compose stacks, backups, storage, monitoring, and notifications on customer hardware. -**Current version: v0.26.0** +**Current version: v0.27.2** --- @@ -138,6 +138,7 @@ The app catalog lives in a separate Git repository. The controller: 3. `checkBeforeDeploy()` JS guard fetches live state first (prevents double-deploy from another tab) 4. **Memory validation** checks `mem_request` against available RAM: - `usable_memory = total_ram - reserved_memory_mb` (default 384MB reserved) + - `CommittedMemory()` only counts running/starting/unhealthy apps — stopped/exited apps are excluded (they don't consume RAM) - Hard block if requests exceed usable memory - Soft warning if limits exceed total RAM (overcommit OK) 5. Pre-generated secret values are submitted as hidden form inputs so the **same values** the user saw are saved to `app.yaml` (no silent re-generation on submit). Controller saves `app.yaml`, sets in-memory `Deployed` flag **before** `docker compose up -d` (avoids stale UI during slow image pulls), reverts on failure @@ -149,7 +150,7 @@ The app catalog lives in a separate Git repository. The controller: Each app can define rich metadata in `.felhom.yml`: - `app_info`: tagline, use_cases, first_steps, prerequisites, default_creds, docs_url - `optional_config`: groups of post-deploy configurable env vars (e.g., API keys for metadata providers) -- `resources`: mem_request, mem_limit, pi_compatible, needs_hdd +- `resources`: mem_request, mem_limit, pi_compatible, needs_hdd, hungarian_ui The `/apps/{slug}` page renders hero section, screenshots, setup guide, and optional config form. @@ -157,7 +158,7 @@ The `/apps/{slug}` page renders hero section, screenshots, setup guide, and opti | Operation | What it does | |-----------|-------------| -| Start | `docker compose up -d` | +| Start | `docker compose up -d` — pre-start memory check rejects with 409 if insufficient RAM | | Stop | `docker compose stop` (blocked for protected stacks) | | Restart | `docker compose restart` | | Update | `docker compose pull` + `docker compose up -d` | @@ -333,6 +334,7 @@ data back up config + DB + user data; apps without HDD back up config + DB dumps - **Restic backup paths:** includes HDD mounts (if any) + config dir + per-app DB dump dir from home drive + stacks dir + controller.yaml (infra, v0.14.1) - Safety guards: destination ≠ source, path-overlap check (HDD mounts only), writable check - **Chained execution:** runs immediately after nightly restic — daily apps every night, weekly apps on Sundays +- **Hub reporting after manual triggers (v0.27.2):** `OnCrossDriveComplete` callback on Router pushes infra backup snapshot to Hub + writes local infra backup after both single-app and run-all manual triggers complete (previously only automatic scheduled runs reported) - Per-app concurrency lock prevents overlapping runs - Status (last_run, duration, size, error) persisted to settings.json @@ -511,7 +513,7 @@ Continuously monitors registered storage paths for disconnection/reconnection (p - Disconnected card: dashed border, red badge, timestamp, stopped apps list, "Csatlakoztatás" (reconnect) button - After reconnect: "Alkalmazások indítása" button to restart auto-stopped stacks -**USB detection** (`system.IsUSBDevice`): Reads `/host/sys/block/` symlink — if target path contains `/usb`, it's a USB device. The `removable` sysfs flag is unreliable for USB HDDs (returns 0). +**USB detection** (`system.IsUSBDevice`): Reads `/host/sys/block/` symlink — if target path contains `/usb`, it's a USB device. The `removable` sysfs flag is unreliable for USB HDDs (returns 0). USB drives show an orange "USB" badge on their storage card alongside Aktív/Alapértelmezett badges (v0.27.2). **Backup guards**: Nightly DB dumps, restic snapshots, and cross-drive backups all skip disconnected drives with WARN log (not treated as failures). @@ -847,7 +849,7 @@ Bearer token authentication, 3-attempt retry with 5-second backoff. Push status #### Infrastructure Backup to Hub (`internal/report/infra_backup.go`) -After each backup cycle, the controller pushes a full infrastructure snapshot to the Hub for disaster recovery. This snapshot includes: +After each backup cycle (including manual Tier 2 triggers via `OnCrossDriveComplete` callback), the controller pushes a full infrastructure snapshot to the Hub for disaster recovery. This snapshot includes: - `controller.yaml` (base64-encoded, full config including secrets) - `settings.json` (base64-encoded, backup prefs, storage paths, cross-drive configs) - Disk layout (UUIDs, labels, mount points, fstab options, bind-mount topology) @@ -1231,7 +1233,7 @@ All daily jobs use Europe/Budapest timezone. Skip-if-running prevents concurrent | GET | `/api/stacks` | List all stacks | | GET | `/api/stacks/{name}` | Stack details | | POST | `/api/stacks/{name}/deploy` | First-time deploy | -| POST | `/api/stacks/{name}/start` | Start stack | +| POST | `/api/stacks/{name}/start` | Start stack (409 if insufficient memory) | | POST | `/api/stacks/{name}/stop` | Stop stack | | POST | `/api/stacks/{name}/restart` | Restart stack | | POST | `/api/stacks/{name}/update` | Pull + recreate |