From 563c9515d9ba23e5f73e66f96d63a27b7efb048c Mon Sep 17 00:00:00 2001 From: kisfenyo Date: Wed, 18 Feb 2026 18:47:39 +0100 Subject: [PATCH] v0.14.0: Per-drive backup architecture + storage path overhaul MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Major refactor of backup and storage paths: - Per-drive restic repos at /backups/primary/restic/ - Per-app DB dumps at /backups/primary//db-dumps/ - Remove global BackupDir, DBDumpDir, ResticRepo config fields - Add SystemDataPath config (fallback for apps without HDD) - New backup/paths.go with pure path computation helpers - Add GetStackHDDPath to StackDataProvider interface - Restic methods now accept repoPath as parameter - Cross-drive backup uses new secondary path structure - Rename storage/ to appdata/ in scripts and compose templates - Update protected HDD paths (storage → appdata + backups) - Simplify backup UI (remove global path displays) Co-Authored-By: Claude Opus 4.6 --- TASK.md | 679 +++++++++++------- controller/cmd/controller/main.go | 16 +- controller/configs/controller.yaml.example | 8 +- controller/internal/backup/appdata.go | 1 + controller/internal/backup/backup.go | 513 ++++++++----- controller/internal/backup/crossdrive.go | 72 +- controller/internal/backup/paths.go | 38 + controller/internal/backup/restic.go | 76 +- controller/internal/backup/restore.go | 17 +- controller/internal/config/config.go | 14 +- controller/internal/stacks/delete.go | 6 +- controller/internal/web/handlers.go | 3 +- .../internal/web/templates/backups.html | 34 +- scripts/docker-setup.sh | 4 +- scripts/hdd-setup.sh | 26 +- 15 files changed, 937 insertions(+), 570 deletions(-) create mode 100644 controller/internal/backup/paths.go diff --git a/TASK.md b/TASK.md index 608d733..50e69de 100644 --- a/TASK.md +++ b/TASK.md @@ -1,319 +1,504 @@ -# TASK.md — v0.13.1 UI Polish Fixes (Round 2) +# TASK.md — v0.14.0 Storage & Backup Architecture Overhaul -**Version:** v0.13.1 -**Type:** UI polish — 4 fixes -**Files likely affected:** `deploy.html`, `backups.html`, `dashboard.html`, `monitoring.html`, `layout.html`, `style.css`, `handlers.go`, `alerts.go`, `funcmap.go` - -Read `CLAUDE.md`, `controller/README.md`, and `CONTEXT.md` before starting. +**Version:** v0.14.0 +**Type:** Architecture overhaul — storage paths, backup structure, multi-drive support +**Scope:** Controller Go code + app catalog compose files + setup scripts +**Note:** Demo node will be reinstalled from scratch — no migration needed --- -## Fix 1: Backup section on deploy page needs card/box styling +## Design Overview -**Problem:** The "Biztonsági mentés" section on app deploy/settings pages (e.g., `/stacks/immich/deploy`) has no visible border or card styling, unlike the "Adattárolás" section above it and other card sections on the page. It looks flat and out of place. +### New directory structure (per drive) -**Where:** `deploy.html` line ~96: `
` and the `.deploy-cross-drive` CSS class in `style.css`. +Every drive mount (`/mnt/sys_drive`, `/mnt/hdd_1`, `/mnt/hdd_2`, ...) uses the same layout: -**Solution:** Add card-like styling to `.deploy-cross-drive` in `style.css`. Look at how `.deploy-storage-info` (the "Adattárolás" card above it on the same page) is styled and match it: -- `border: 1px solid var(--border)` -- `background: var(--card-bg)` -- `border-radius: 12px` -- `padding: 1.5rem` +``` +/mnt// + appdata// ← live app data (renamed from "storage") + backups/ + primary/ + /db-dumps/ ← raw DB dumps per app (accessible for testing) + restic/ ← per-drive restic repo (all apps on this drive) + secondary/ + /rsync/ ← rsync copies from apps on OTHER drives + restic/ ← restic repo for secondary copies + Dokumentumok/ + media/ + Download/ + movies/ + series/ + music/ + audiobooks/ +``` -If `.deploy-cross-drive` already exists in CSS, add the missing border/background properties. If it doesn't exist, create it with the above properties. +### Key rules + +1. **An app's "home drive"** = the drive from its `HDD_PATH` env var, or `cfg.Paths.SystemDataPath` if no HDD_PATH +2. **Primary backup** lives on the SAME drive as the app — protects against accidental deletion, app bugs +3. **Secondary backup** lives on a DIFFERENT drive — protects against drive failure +4. **One restic repo per drive** (in both primary and secondary) — same password for all repos +5. **DB dumps** are raw SQL files per-app, always on the app's home drive, also included in restic +6. **Compose configs + controller.yaml** go into EVERY primary restic repo (small, ensures self-contained restore) +7. **`storage/` → `appdata/`** rename across all compose templates +8. **Filebrowser** mounts per-drive subdirectories: `media/`, `Dokumentumok/`, `backups/secondary/` (for file recovery) --- -## Fix 2: Clean up auto-generated env values section on deploy page +## Phase 1: Config & path helpers -**Problem:** The "Automatikusan generált értékek" section on the deploy page is cluttered. Each field currently shows: input + "Megjelenítés" button (for passwords) + "Másolás" button + badge. Too many elements stacked together. +### 1a. `internal/config/config.go` -**Current code location:** `deploy.html` lines ~254-281, inside the `{{if .AutoFields}}` block. +**Add:** +- `SystemDataPath string \`yaml:"system_data_path"\`` to `PathsConfig` — default `/mnt/sys_drive` -**Current structure per field:** -```html -
- - {{if and $isDeployed $val}} - {{if eq .Type "secret"}} -
- - - -
- {{else}} -
- - -
- {{end}} - {{end}} - ✓ Automatikusan generálva -
-``` +**Remove from struct:** +- `BackupDir string` from PathsConfig +- `DBDumpDir string` from PathsConfig +- `ResticRepo string` from BackupConfig -**Changes:** +**Keep:** +- `ResticPasswordFile string` in BackupConfig (shared across all repos) +- `HDDPath string` in PathsConfig (legacy, still used as default storage) -1. **Remove ALL "Másolás" buttons** — users can select+copy natively, dedicated button adds clutter -2. **Keep** the "Megjelenítés"/"Elrejtés" toggle button for secret/password fields (essential) -3. **Move the badge inline with the label** — instead of on a separate line below the input, put it next to the label text +**Update `applyDefaults()`:** +- Remove: `d(&cfg.Paths.BackupDir, "/srv/backups")` +- Remove: `d(&cfg.Paths.DBDumpDir, "/srv/backups/db-dumps")` +- Remove: `d(&cfg.Backup.ResticRepo, "/srv/backups/restic-repo")` +- Add: `d(&cfg.Paths.SystemDataPath, "/mnt/sys_drive")` -**New structure per field:** -```html -
- - {{if and $isDeployed $val}} - {{if eq .Type "secret"}} -
- - -
- {{else}} - - {{end}} - {{end}} -
-``` +**Gotcha:** All code referencing `cfg.Paths.BackupDir`, `cfg.Paths.DBDumpDir`, `cfg.Backup.ResticRepo` will break. Grep for all references and update. -4. **Remove the `copyAutoField` JS function** — search for `function copyAutoField` in deploy.html's `