From 1903535dc5f462823c87e5a863b3d49a720239c3 Mon Sep 17 00:00:00 2001 From: Marek Goc Date: Mon, 16 Feb 2026 02:04:57 +0100 Subject: [PATCH] better snapshots management --- internal/server/admin_handlers.go | 2 ++ internal/server/server.go | 37 +++++++++++++++++-------------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/internal/server/admin_handlers.go b/internal/server/admin_handlers.go index 7dce9ba..b9a0b5f 100644 --- a/internal/server/admin_handlers.go +++ b/internal/server/admin_handlers.go @@ -480,6 +480,8 @@ func (s *Server) handleAdminDeleteSnapshot(w http.ResponseWriter, r *http.Reques if snap != nil { if snap.StorageType == "s3" && s.s3Backend != nil { s.s3Backend.Delete(context.Background(), snap.StorageKey) + } else if snap.StorageType == "local" && s.localBackend != nil { + s.localBackend.Delete(context.Background(), snap.StorageKey) } } diff --git a/internal/server/server.go b/internal/server/server.go index aa7e8a8..a85c7dd 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -126,21 +126,21 @@ func (s *Server) rotateSnapshots(clientID string) (int, int64) { return 0, 0 } - // Select appropriate backend - var backend StorageBackend - if s.s3Backend != nil { - backend = s.s3Backend - } else if s.localBackend != nil { - backend = s.localBackend - } else { - log.Printf("No storage backend available for rotation") - return 0, 0 - } - - // Delete snapshots + // Delete snapshots - use correct backend based on each snapshot's storage type ctx := context.Background() for _, snap := range toDelete { - if err := backend.Delete(ctx, snap.StorageKey); err != nil { + // Determine which backend to use for this specific snapshot + var snapBackend StorageBackend + if snap.StorageType == "s3" && s.s3Backend != nil { + snapBackend = s.s3Backend + } else if snap.StorageType == "local" && s.localBackend != nil { + snapBackend = s.localBackend + } else { + log.Printf("No storage backend available for snapshot %s (type: %s)", snap.SnapshotID, snap.StorageType) + continue + } + + if err := snapBackend.Delete(ctx, snap.StorageKey); err != nil { log.Printf("Error deleting snapshot %s: %v", snap.StorageKey, err) continue } @@ -326,6 +326,7 @@ func (s *Server) HandleUploadStream(w http.ResponseWriter, r *http.Request) { } // Save metadata to database + // Use actual storage type where snapshot was stored (not always s3) metadata := &SnapshotMetadata{ ClientID: clientID, SnapshotID: storageKey, @@ -333,7 +334,7 @@ func (s *Server) HandleUploadStream(w http.ResponseWriter, r *http.Request) { SizeBytes: actualSize, DatasetName: datasetName, StorageKey: storageKey, - StorageType: "s3", + StorageType: client.StorageType, // Use actual storage type from client config Compressed: compressedStr == "true", Incremental: incrementalStr == "true", BaseSnapshot: baseSnapshot, @@ -450,15 +451,17 @@ func (s *Server) HandleDownload(w http.ResponseWriter, r *http.Request) { return } + // Use snapshot's own storage_type to determine which backend to use + // This enables mixed storage scenarios (e.g., full on local, incrementals on S3) ctx := context.Background() var backend StorageBackend - if client.StorageType == "s3" && s.s3Backend != nil { + if targetSnapshot.StorageType == "s3" && s.s3Backend != nil { backend = s.s3Backend - } else if s.localBackend != nil { + } else if targetSnapshot.StorageType == "local" && s.localBackend != nil { backend = s.localBackend } else { - http.Error(w, "No storage backend available", http.StatusInternalServerError) + http.Error(w, "No storage backend available for this snapshot's storage type", http.StatusInternalServerError) return }