Update snapshot list to sync with remote
- Added syncWithRemote method that lists remote snapshots from S3 - Removes local snapshots that don't exist in remote storage - Ensures local database stays in sync with actual remote state - This prevents showing snapshots that have been deleted from S3
This commit is contained in:
parent
fb220685a2
commit
0cbb5aa0a6
@ -487,6 +487,12 @@ func newSnapshotVerifyCommand() *cobra.Command {
|
|||||||
|
|
||||||
// List lists all snapshots
|
// List lists all snapshots
|
||||||
func (app *SnapshotApp) List(ctx context.Context, jsonOutput bool) error {
|
func (app *SnapshotApp) List(ctx context.Context, jsonOutput bool) error {
|
||||||
|
// First, sync with remote snapshots
|
||||||
|
if err := app.syncWithRemote(ctx); err != nil {
|
||||||
|
return fmt.Errorf("syncing with remote: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now get snapshots from S3
|
||||||
snapshots, err := app.getSnapshots(ctx)
|
snapshots, err := app.getSnapshots(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -774,6 +780,54 @@ func (app *SnapshotApp) deleteSnapshot(ctx context.Context, snapshotID string) e
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// syncWithRemote syncs local database with remote snapshots
|
||||||
|
func (app *SnapshotApp) syncWithRemote(ctx context.Context) error {
|
||||||
|
log.Info("Syncing with remote snapshots")
|
||||||
|
|
||||||
|
// Get all remote snapshot IDs
|
||||||
|
remoteSnapshots := make(map[string]bool)
|
||||||
|
objectCh := app.S3Client.ListObjectsStream(ctx, "metadata/", false)
|
||||||
|
|
||||||
|
for object := range objectCh {
|
||||||
|
if object.Err != nil {
|
||||||
|
return fmt.Errorf("listing remote snapshots: %w", object.Err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract snapshot ID from paths like metadata/hostname-20240115-143052Z/
|
||||||
|
parts := strings.Split(object.Key, "/")
|
||||||
|
if len(parts) >= 2 && parts[0] == "metadata" && parts[1] != "" {
|
||||||
|
remoteSnapshots[parts[1]] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug("Found remote snapshots", "count", len(remoteSnapshots))
|
||||||
|
|
||||||
|
// Get all local snapshots (use a high limit to get all)
|
||||||
|
localSnapshots, err := app.Repositories.Snapshots.ListRecent(ctx, 10000)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("listing local snapshots: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove local snapshots that don't exist remotely
|
||||||
|
removedCount := 0
|
||||||
|
for _, snapshot := range localSnapshots {
|
||||||
|
if !remoteSnapshots[snapshot.ID] {
|
||||||
|
log.Info("Removing local snapshot not found in remote", "snapshot_id", snapshot.ID)
|
||||||
|
if err := app.Repositories.Snapshots.Delete(ctx, snapshot.ID); err != nil {
|
||||||
|
log.Error("Failed to delete local snapshot", "snapshot_id", snapshot.ID, "error", err)
|
||||||
|
} else {
|
||||||
|
removedCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if removedCount > 0 {
|
||||||
|
log.Info("Removed local snapshots not found in remote", "count", removedCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// parseSnapshotTimestamp extracts timestamp from snapshot ID
|
// parseSnapshotTimestamp extracts timestamp from snapshot ID
|
||||||
// Format: hostname-20240115-143052Z
|
// Format: hostname-20240115-143052Z
|
||||||
func parseSnapshotTimestamp(snapshotID string) (time.Time, error) {
|
func parseSnapshotTimestamp(snapshotID string) (time.Time, error) {
|
||||||
|
Loading…
Reference in New Issue
Block a user