package backup import "fmt" // RestoreApp restores an app's HDD data from a restic snapshot. func (m *Manager) RestoreApp(stackName, snapshotID string) error { // Validate app has backup enabled if !m.settings.IsAppBackupEnabled(stackName) { return fmt.Errorf("backup not enabled for %s", stackName) } // Resolve HDD paths for this app if m.stackProvider == nil { return fmt.Errorf("stack provider not configured") } hddMounts := m.stackProvider.GetStackHDDMounts(stackName) if len(hddMounts) == 0 { return fmt.Errorf("no HDD data paths found for %s", stackName) } // Validate snapshot exists snapshots, err := m.restic.ListSnapshots(100) if err != nil { return fmt.Errorf("listing snapshots: %w", err) } found := false for _, s := range snapshots { if s.ID == snapshotID { found = true break } } if !found { return fmt.Errorf("snapshot %s not found", snapshotID) } // Use the running flag to prevent concurrent backup/restore m.mu.Lock() if m.running { m.mu.Unlock() return fmt.Errorf("backup or restore already in progress") } m.running = true m.mu.Unlock() defer func() { m.mu.Lock() m.running = false m.mu.Unlock() }() m.logger.Printf("[WARN] RESTORE starting: stack=%s, snapshot=%s, paths=%v", stackName, snapshotID, hddMounts) // Execute restore if err := m.restic.RestoreAppData(snapshotID, hddMounts); err != nil { m.logger.Printf("[ERROR] RESTORE failed for %s: %v", stackName, err) return err } m.logger.Printf("[INFO] RESTORE completed: stack=%s, snapshot=%s", stackName, snapshotID) return nil }