Phase 3 complete: per-app backup toggles, restore, storage overview

- Storage overview on backup page (SSD/HDD bars, repo stats)
- Restic password visibility + hub sync for disaster recovery
- App data discovery (HDD bind mounts, Docker volumes)
- Per-app backup toggle checkboxes with settings persistence
- Dynamic backup paths: enabled app HDD data included in restic snapshots
- Limited app restore from snapshots (self-service recovery)
- Snapshots API endpoint for restore dropdown
- Version bump to 0.8.0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-16 21:29:56 +01:00
parent a3af7c6a2d
commit 7d801d1094
15 changed files with 1088 additions and 29 deletions
+4 -4
View File
@@ -81,7 +81,7 @@ func (m *Manager) DeleteStack(name string, removeHDDData bool) (*DeleteResponse,
}
// Step 1: Parse compose file for HDD bind mounts
hddMounts := parseComposeHDDMounts(stack.ComposePath, hddPath)
hddMounts := ParseComposeHDDMounts(stack.ComposePath, hddPath)
// Step 2: Run docker compose down --rmi local --volumes
env := m.stackEnv(stackDir)
@@ -164,7 +164,7 @@ func (m *Manager) GetStackHDDData(name string) (*HDDDataResponse, error) {
return resp, nil
}
mounts := parseComposeHDDMounts(stack.ComposePath, hddPath)
mounts := ParseComposeHDDMounts(stack.ComposePath, hddPath)
protected := protectedHDDPaths(hddPath)
for _, mount := range mounts {
@@ -197,9 +197,9 @@ func (m *Manager) GetStackHDDData(name string) (*HDDDataResponse, error) {
return resp, nil
}
// parseComposeHDDMounts reads a docker-compose.yml and extracts host paths
// ParseComposeHDDMounts reads a docker-compose.yml and extracts host paths
// that reference the HDD path from volume bind mounts.
func parseComposeHDDMounts(composePath, hddPath string) []string {
func ParseComposeHDDMounts(composePath, hddPath string) []string {
if hddPath == "" {
return nil
}