v0.11.8 — Per-App Cross-Drive Backup (3-2-1 rule)
New feature: backup app data to a secondary storage drive to satisfy
the "different media" requirement of the 3-2-1 backup rule.
- settings.go: CrossDriveBackup struct, AppBackupPrefs.CrossDrive field,
getter/setter methods, GetOrCreateCrossDrivePassword, preserves
cross-drive config when toggling nightly backup
- crossdrive.go (new): CrossDriveRunner with rsync and restic backends.
Validates destination (mount point, writable), prevents source/dest
overlap, per-app concurrency lock, persists last_run/status/size.
- main.go: wire CrossDriveRunner, register cross-drive-daily (03:30)
and cross-drive-weekly (04:30 Sundays) scheduler jobs
- router.go: 4 new API endpoints — save config, trigger run, get status,
run-all. Router now accepts Settings and CrossDriveRunner.
- server.go: Server struct accepts CrossDriveRunner, new web route
POST /settings/cross-backup/{name}
- handlers.go: deployHandler populates CrossDriveConfig, BackupDestPaths,
BackupDestWarning, AppBackupEnabled. settingsCrossBackupHandler saves
config. backupsHandler builds CrossDriveSummary, UnconfiguredApps,
CrossDriveWarnings for backup page.
- deploy.html: "Biztonsági mentés" card with destination/method/schedule
dropdowns, last-run status, manual trigger button, flash messages.
- backups.html: "Másolatok másik meghajtóra" section with per-app
status rows, unconfigured app warnings, "Összes futtatása most" button.
- style.css: margin-bottom fix for .deploy-stale-data, new cross-drive
card and list styles.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -53,6 +53,21 @@ type SnapshotRecord struct {
|
||||
HasStats bool `json:"has_stats"` // false for historical entries loaded from restic
|
||||
}
|
||||
|
||||
// CrossDriveSummaryItem holds display data for one app's cross-drive backup.
|
||||
type CrossDriveSummaryItem struct {
|
||||
StackName string
|
||||
DisplayName string
|
||||
Method string // "rsync" or "restic"
|
||||
MethodLabel string // "Egyszerű másolat" or "Restic"
|
||||
DestPath string
|
||||
DestLabel string // storage path label
|
||||
Schedule string
|
||||
ScheduleLabel string // "Naponta" or "Hetente" or "Kézi"
|
||||
LastStatus string // "ok", "error", "running", ""
|
||||
LastRunShort string // formatted short time e.g. "03:15"
|
||||
SizeHuman string
|
||||
}
|
||||
|
||||
// FullBackupStatus contains everything the backup page needs.
|
||||
type FullBackupStatus struct {
|
||||
Enabled bool
|
||||
@@ -88,6 +103,11 @@ type FullBackupStatus struct {
|
||||
// App data backup
|
||||
AppDataInfo []AppBackupInfo
|
||||
|
||||
// Cross-drive backup summary
|
||||
CrossDriveSummary []CrossDriveSummaryItem
|
||||
UnconfiguredApps []CrossDriveSummaryItem // apps with HDD data but no cross-drive config
|
||||
CrossDriveWarnings []string // destination health warnings
|
||||
|
||||
// Flash messages (set by handlers, passed through redirect)
|
||||
FlashSuccess string
|
||||
FlashError string
|
||||
|
||||
Reference in New Issue
Block a user