From 476a97376f6677ed33f6cef08939eea42144ba7c Mon Sep 17 00:00:00 2001 From: kisfenyo Date: Sat, 13 Jun 2026 13:35:43 +0200 Subject: [PATCH] =?UTF-8?q?v0.56.0:=20Phase=204=20=E2=80=94=20FileBrowser?= =?UTF-8?q?=20scoping=20+=20deploy=20DB-on-SSD=20note=20+=20monitoring=20d?= =?UTF-8?q?escriptions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 4A: scope FileBrowser bind to /appdata (recovery units + Tier 2 copies under backups/ are no longer mounted into FileBrowser — customer can't browse/delete the thing that restores them). 4B: deploy storage-selection step states the chosen drive holds files while the DB runs on the fast internal SSD + is backed up with the app. 4C: buildStorageBars stable sort + purpose description on the monitoring storage list. Co-Authored-By: Claude Opus 4.8 (1M context) --- CHANGELOG.md | 18 +++++++++++++ controller/internal/web/handlers.go | 26 ++++++++++++++++--- controller/internal/web/templates/deploy.html | 4 +++ .../internal/web/templates/monitoring.html | 1 + 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8656e15..13e5b49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ ## Changelog +### v0.56.0 — Phase 4: FileBrowser scoping + deploy DB-on-SSD note + monitoring storage descriptions (2026-06-13) + +Polish layer closing the slice. + +- **4A FileBrowser scoping (safety):** the FileBrowser bind mount is now scoped to each drive's + `appdata/` subtree (`/appdata:/srv/`) instead of the whole drive root. The recovery + units + Tier 2 copies under `backups/` are therefore **not mounted into FileBrowser at all** — the + customer browses their userdata but cannot reach (or even see) the thing that restores them. The + appdata dir is `mkdir`-ed before the bind so the source exists. (`syncFileBrowserMounts`.) +- **4B Deploy-UI communication:** the storage-selection step now states plainly (Hungarian) that the + chosen drive holds the app's **files**, while its **database runs on the fast internal SSD** and is + backed up alongside the app — so "the DB is on the SSD" stops being a surprise. (`deploy.html`.) +- **4C Monitoring storage list:** `buildStorageBars` now sorts deterministically (by path) and carries a + **purpose description** explaining the user-data drives (rendered on the monitoring "Tárolók + kapacitása" list). Note: this list is the controller's registered user-data drives only (the agent's + local/local-lvm/pbs storage is not in this registry), so the role-tier sort/`local`-vs-`local-lvm` + descriptions belong to the agent-backed storage-management page, not here. + ### v0.55.0 — Phase 3: auto off-drive Tier 2 (rootfs-headroom guard, durable off-disk target) (2026-06-13) Tier 2 = an **off-drive copy** of each HDD app's recovery unit + bulk userdata to a **different physical diff --git a/controller/internal/web/handlers.go b/controller/internal/web/handlers.go index 8bb2a02..7bcbc01 100644 --- a/controller/internal/web/handlers.go +++ b/controller/internal/web/handlers.go @@ -8,6 +8,7 @@ import ( "os" "os/exec" "path/filepath" + "sort" "strings" "time" @@ -31,13 +32,21 @@ var protectedStackSubdomains = map[string]string{ type StorageBarInfo struct { Label string // e.g., "USB HDD 1TB", "SYS Storage 350G" Path string // e.g., "/mnt/hdd_1" + Purpose string // Hungarian explanation of what this drive holds (monitoring page) TotalGB float64 UsedGB float64 Percent float64 Disconnected bool } -// buildStorageBars returns usage bars for all registered storage paths. +// storageBarPurpose is the Hungarian description for the registered user-data drives shown in the +// monitoring "Tárolók kapacitása" list. These are all external/user-data drives (the agent's +// system/PBS storage is not in the controller's storage-path registry), matching the user-data +// purpose text on the storage-management page (Phase 4C). +const storageBarPurpose = "Külső adattároló — a telepített alkalmazások nagy méretű fájljai (média, dokumentumok) ide kerülnek; az adatbázisok a belső SSD-n vannak." + +// buildStorageBars returns usage bars for all registered storage paths, in a stable order +// (by path) with a purpose description. func (s *Server) buildStorageBars() []StorageBarInfo { var bars []StorageBarInfo for _, sp := range s.settings.GetStoragePaths() { @@ -49,6 +58,7 @@ func (s *Server) buildStorageBars() []StorageBarInfo { bars = append(bars, StorageBarInfo{ Label: sp.Label, Path: sp.Path, + Purpose: storageBarPurpose, Disconnected: true, }) continue @@ -60,11 +70,14 @@ func (s *Server) buildStorageBars() []StorageBarInfo { bars = append(bars, StorageBarInfo{ Label: sp.Label, Path: sp.Path, + Purpose: storageBarPurpose, TotalGB: di.TotalGB, UsedGB: di.UsedGB, Percent: di.UsedPercent, }) } + // Deterministic order regardless of registry insertion order. + sort.Slice(bars, func(i, j int) bool { return bars[i].Path < bars[j].Path }) return bars } @@ -1369,11 +1382,18 @@ func (s *Server) syncFileBrowserMounts(resetDBOnChange bool) { return } - // Build volume mount lines + // Build volume mount lines. SCOPE to the drive's `appdata/` subtree only (Phase 4A): the customer + // browses their userdata, but the recovery units + Tier 2 copies under `backups/` are NOT mounted + // into FileBrowser at all — so the thing that restores them can't be browsed or (even read-only) + // surfaced. mkdir the appdata dir first so the bind source exists with sane ownership. var storageMounts []string for _, sp := range paths { mountName := filepath.Base(sp.Path) // "/mnt/hdd_1" → "hdd_1" - line := fmt.Sprintf(" - %s:/srv/%s", sp.Path, mountName) + appdataSrc := filepath.Join(sp.Path, "appdata") + if err := os.MkdirAll(appdataSrc, 0755); err != nil { + s.logger.Printf("[WARN] [web] FileBrowser: could not ensure appdata dir %s: %v", appdataSrc, err) + } + line := fmt.Sprintf(" - %s:/srv/%s", appdataSrc, mountName) storageMounts = append(storageMounts, line) } diff --git a/controller/internal/web/templates/deploy.html b/controller/internal/web/templates/deploy.html index 889d581..358384a 100644 --- a/controller/internal/web/templates/deploy.html +++ b/controller/internal/web/templates/deploy.html @@ -538,6 +538,10 @@ +
+ ℹ️ A kiválasztott meghajtón az alkalmazás fájljai (média, dokumentumok) tárolódnak. + Az adatbázis a gyors belső SSD-n fut — és az alkalmazással együtt készül róla biztonsági mentés. +
{{else}}
+ {{if .Purpose}}
{{.Purpose}}
{{end}} {{end}} {{end}}