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:
@@ -303,6 +303,41 @@ func (r *ResticManager) Stats() (*RepoStats, error) {
|
||||
return stats, nil
|
||||
}
|
||||
|
||||
// GetPassword reads and returns the restic repository password.
|
||||
func (r *ResticManager) GetPassword() (string, error) {
|
||||
data, err := os.ReadFile(r.passwordFile)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("reading restic password: %w", err)
|
||||
}
|
||||
return strings.TrimSpace(string(data)), nil
|
||||
}
|
||||
|
||||
// RestoreAppData restores specific paths from a restic snapshot.
|
||||
func (r *ResticManager) RestoreAppData(snapshotID string, paths []string) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
args := []string{
|
||||
"restore", snapshotID,
|
||||
"--target", "/",
|
||||
}
|
||||
for _, p := range paths {
|
||||
args = append(args, "--include", p)
|
||||
}
|
||||
|
||||
r.logger.Printf("[WARN] RESTORE started: snapshot=%s, paths=%v", snapshotID, paths)
|
||||
|
||||
cmd := r.command(ctx, args...)
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
r.logger.Printf("[ERROR] Restore failed: %v, output: %s", err, truncate(string(output), 500))
|
||||
return fmt.Errorf("restic restore failed: %w", err)
|
||||
}
|
||||
|
||||
r.logger.Printf("[INFO] RESTORE completed: snapshot=%s, paths=%v", snapshotID, paths)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *ResticManager) command(ctx context.Context, args ...string) *exec.Cmd {
|
||||
cmd := exec.CommandContext(ctx, "restic", args...)
|
||||
cmd.Env = append(os.Environ(),
|
||||
|
||||
Reference in New Issue
Block a user