Controller now includes its external URL in periodic hub reports so the
hub can trigger self-updates remotely via the /api/selfupdate/update endpoint.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add StorageBars to backupsHandler so all registered storage paths appear
- Update backups.html to use StorageBars loop (replacing single HDDConfigured block)
- Rename "SSD (/)" → "Rendszer (/)" on backup, monitoring, and dashboard pages
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace bufio.Scanner with bufio.Reader.ReadLine() which gracefully
skips lines exceeding the buffer (isPrefix=true) instead of failing.
Fixes validation of Immich's PostgreSQL dump which contains COPY lines
with binary-encoded image data exceeding the 256KB scanner limit.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
FileBrowser reads config.yaml from its working directory
(/home/filebrowser/), not from the data subdirectory.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add server.database to generated config.yaml pointing to the
persistent data volume. Previously the database was at
/home/filebrowser/database.db (outside the volume) and was lost
on every container recreation.
- Call syncFileBrowserMounts after manual storage path add, so newly
registered drives (like sys_drive) also appear in FileBrowser.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Ensures config.yaml and docker-compose.yml are regenerated on
controller startup, so new drives added while the controller was
down still get their FileBrowser sources configured.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Generate config.yaml with a separate source per registered storage path.
Each source uses the drive's label as its display name, making it appear
automatically in FileBrowser's sidebar. The config.yaml is bind-mounted
into the container (read-only) alongside the data volume.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CreateDirectory now returns an error when the folder already exists
instead of silently succeeding. JS validates folder name format
(alphanumeric + underscore, max 32 chars) before sending the request.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
After an interrupted attach wizard, the raw mount stays behind,
causing the device to appear as "mounted" in scan results. Now the
scan button calls cancel first, which unmounts any stale raw mounts
that have no bind mount in fstab.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Document the new v0.15.0 attach wizard: bind-mount approach,
API endpoints, file tree, and roadmap entry.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
rename() fails with EBUSY on Docker bind-mounted files. Add safeWriteFile()
helper that tries atomic rename first, falls back to direct write. Fixes
both init wizard and attach wizard fstab operations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New Settings wizard to attach drives with existing filesystems without
formatting. Mounts partition at staging path, lets user browse and pick
a subfolder, then bind-mounts it at /mnt/<name> with fstab entries.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Bug 1 (HIGH): add --exclude _* to rsync --delete so _db/ and _config/
directories are never deleted between backup runs (crossdrive.go)
Bug 2 (MEDIUM): refactor RunDBDumps/RunBackup/RunFullBackup to use
acquireRunning/releaseRunning helpers; extract runDBDumpsInternal and
runBackupInternal so all three public entry points set m.running and
RunFullBackup no longer deadlocks calling the public methods (backup.go)
Bug 3 (MEDIUM): log [WARN] when GetDiskUsage returns nil in
ValidateDestination instead of silently skipping space checks (crossdrive.go)
Bug 4 (MEDIUM): add [WARN] on empty SystemDataPath in NewManager; add
[ERROR] in GetAppDrivePath; guard DumpStackDB against empty/relative paths
(backup.go)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Auto-enable daily rsync Tier 2 for apps without HDD mounts when ≥2
storage paths exist (AutoEnableSmallApps)
- Sync infrastructure config (stacks dir + controller.yaml) to all
secondary destinations via _infra/ directory (syncInfraConfig)
- Include infra paths in cross-drive restic snapshots
- Add SecondaryInfraPath() helper to paths.go
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Major refactor of backup and storage paths:
- Per-drive restic repos at <drive>/backups/primary/restic/
- Per-app DB dumps at <drive>/backups/primary/<app>/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 <noreply@anthropic.com>
- Tier 2 cross-drive backup now configurable for all apps (not just HDD apps)
- Non-HDD apps (Mealie, Gokapi) can back up config + DB to secondary drive
- Status dot: removed "auto" gray — all apps start yellow, green = 2+ tiers OK
- Backup page: Tier 2 row always shown, Tier 3 placeholder added
- Deploy page: cross-drive config visible for all deployed apps
- Meta badges: non-HDD apps show "Konfig" or "Konfig + DB" instead of "Auto"
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Cross-drive now copies DB dumps (_db/) and config (_config/) alongside user data
- restic cross-drive includes config dir + full DB dump dir
- UI: per-tier rows (1. mentés / 2. mentés) instead of per-layer (DB/Konfig/Data)
- UI: BackupContents label shows what each tier protects (DB + Konfig + Adatok)
- UI: rsync backups show browsable indicator (📁)
- Cleanup: removed unused filterSnapshotsByPaths + pathCovers from router.go
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix 1: HDD data backup is now mandatory for all deployed apps.
resolveAppBackupPaths() iterates ListDeployedStacks() directly — no
longer reads GetAppBackupMap() or checks the Enabled flag. DiscoverAppData()
drops backupPrefs parameter; BackupEnabled is set from HasHDDData.
Five dead settings methods removed: IsAppBackupEnabled, SetAppBackup,
GetAppBackupMap, SetAppBackupBulk, GetAppBackupPrefs.
Fix 2: Cross-drive backup now triggers a fresh DB dump (DumpStackDB)
before running. DBDumper interface added to crossdrive.go; Manager
implements it; SetDBDumper wired in main.go. Non-fatal — proceeds with
user data backup even if DB dump fails.
Fix 3: Restore dropdown shows ALL deployed apps (not just HDD+enabled).
restore.go rewritten: always restores config+DB, adds user data if hasHDD.
UI shows restore type banner (full / config+DB / config only) with
color-coded styling. Snapshot API clarified for non-HDD apps.
Fix 4: "Docker kötetek" → "Konfiguráció" — named volumes are not in
the restic backup paths; compose files + app.yaml are what's backed up.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>