From 6d267b3e4df9995322ac1a0f479cf31f7aca92b3 Mon Sep 17 00:00:00 2001 From: kisfenyo Date: Wed, 10 Jun 2026 13:59:26 +0200 Subject: [PATCH] slice 8C C.3: de-privilege the controller container (legacy docker-setup template) + CHANGELOG (v0.37.0) Dropped privileged:true + /mnt rshared + /sys + /dev + /etc/fstab + /run/udev from the bare-metal compose template (controller no longer does disk ops). The golden bootstrap run was already minimal (8A). Slice 8 CLOSED on the controller. Co-Authored-By: Claude Opus 4.8 --- CHANGELOG.md | 41 +++++++++++++++++++++++++++++++++++++++++ scripts/docker-setup.sh | 15 +++++---------- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0233929..c9933e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,46 @@ ## Changelog +### v0.37.0 — slice 8C: controller de-privileging + disk management via the agent (2026-06-10) + +The in-guest controller half of slice 8C (closes slice 8). The disk-execution subsystem moves to +the host agent (`felhom-agent` v0.12.0); the controller becomes **Docker-only with no disk +privileges** and drives disk management through the agent's local API. ~12.3k LOC retired. + +#### Added +- **`internal/web/agent_disk_handlers.go`** — agent-backed disk API (`ServeDiskAPI`): `GET + /api/disks` (list + data-bearing flags), `POST /api/disks/assign` (mount), `POST /api/disks/eject` + (unmount + dependent-guest warning), `POST /api/disks/format`. Thin proxies over the slice-8A + `agentapi` client (leaf-pinned, own token). **Execution is the agent's**; the UX stays here. + A data-bearing format refusal (`agentapi.ErrFormatRefused`) is surfaced as **HTTP 409 "operator + authorization required"** (the 8C invariant — the agent inspects the device; the controller's + claim is irrelevant). +- **`internal/agentapi`**: `Disks`/`AssignDisk`/`EjectDisk`/`FormatDisk` + `ErrFormatRefused`. + +#### Retired (moved to the host agent / obsolete) +- **`internal/storage/`** — the entire package (scan/format/attach/migrate/safety, DriveMigrator). +- **`internal/backup/`** — restic (`ResticManager`), `crossdrive` (`CrossDriveRunner`), + `restore_drives*`, `disk_layout`, `local_infra`, `restore_scan`, the restic path helpers, and the + drive-restore `restore_app*`. **`backup.Manager` surgically split to app-data only**: kept DB + dumps, Docker-volume tars, and per-app restore; dropped restic snapshots, cross-drive, per-drive + repo stats, integrity check, snapshot history. `RestoreApp` now restores from the on-disk + volume-tar dumps (snapshot/restic restore is the agent's domain). +- **`internal/report/infra_backup*` + `infra_pull`** (kept the setup fresh-install config download as + `config_pull.go`); **`internal/setup/scanner.go`** + the wizard's drive-recovery flows (restore is + the agent's job now); **`internal/monitor/watchdog.go` + `pinger.go`** (storage watchdog → + agent; Healthchecks.io pinging → the Hub owns monitoring); **`web/storage_handlers.go` + + `handler_restore.go`** (replaced by the thin agent-backed disk API). +- Wiring dropped from `main.go` / `api/router.go` / `web/server.go`: CrossDriveRunner, DriveMigrator, + storage watchdog, infra-backup push, the restic backup scheduler jobs (kept the **db-dump** job). + +#### De-privileged +- `scripts/docker-setup.sh` controller compose template: dropped `privileged: true`, the `/mnt` + rshared bind, `/sys`, `/dev`, `/etc/fstab`, `/run/udev`. The golden's bootstrap `docker run` + (felhom-agent `build-golden.sh`) was already minimal (bootstrap config + data + docker socket). + +#### Tests / build +- `go build ./...` + `go test ./...` green (app-data backup / stacks / quiesce / bootstrap / agentapi + / disk-client tests pass). The data-bearing-format refusal is proven in `agentapi` tests. + ### v0.36.0 — slice 8B: app-consistent backup quiesce loop (stack-stop) (2026-06-10) The in-guest controller half of slice 8B (doc 03 §6/§8). Pairs with `felhom-agent` v0.11.0. An diff --git a/scripts/docker-setup.sh b/scripts/docker-setup.sh index da27307..d8c8532 100644 --- a/scripts/docker-setup.sh +++ b/scripts/docker-setup.sh @@ -1698,7 +1698,11 @@ services: image: gitea.dooplex.hu/admin/felhom-controller:latest container_name: felhom-controller restart: unless-stopped - privileged: true + # slice 8C: DE-PRIVILEGED. The disk-execution subsystem (scan/format/mount/migrate, restic, + # cross-drive) moved to the host agent — the controller is Docker-only and holds NO disk + # privileges. Dropped: privileged:true, the /mnt rshared bind, /sys, /dev, /etc/fstab, + # /run/udev. Kept: the docker socket (app/stack management), config, data, the stacks dir, + # and the app-data backup dir. ports: - "8080:8080" - "8081:8081" @@ -1708,17 +1712,8 @@ services: - controller-data:/opt/docker/felhom-controller/data - /opt/docker/stacks:/opt/docker/stacks - /srv/backups:/srv/backups - - type: bind - source: /mnt - target: /mnt - bind: - propagation: rshared - - /sys:/host/sys:ro - /etc/os-release:/host/etc/os-release:ro - /etc/hostname:/host/etc/hostname:ro - - /dev:/host-dev:rw - - /etc/fstab:/host-fstab - - /run/udev:/run/udev:ro environment: - TZ=Europe/Budapest - HOST_IP=$(get_server_ip)