Major refactoring: Updated manifest format and renamed backup to snapshot

- Created manifest.go with proper Manifest structure including blob sizes
- Updated manifest generation to include compressed size for each blob
- Added TotalCompressedSize field to manifest for quick access
- Renamed backup package to snapshot for clarity
- Updated snapshot list to show all remote snapshots
- Remote snapshots not in local DB fetch manifest to get size
- Local snapshots not in remote are automatically deleted
- Removed backwards compatibility code (pre-1.0, no users)
- Fixed prune command to use new manifest format
- Updated all imports and references from backup to snapshot
This commit is contained in:
2025-07-26 03:27:47 +02:00
parent c07d8eec0a
commit a544fa80f2
11 changed files with 254 additions and 168 deletions

View File

@@ -2,18 +2,16 @@ package cli
import (
"context"
"encoding/json"
"fmt"
"strings"
"git.eeqj.de/sneak/vaultik/internal/backup"
"git.eeqj.de/sneak/vaultik/internal/config"
"git.eeqj.de/sneak/vaultik/internal/database"
"git.eeqj.de/sneak/vaultik/internal/globals"
"git.eeqj.de/sneak/vaultik/internal/log"
"git.eeqj.de/sneak/vaultik/internal/s3"
"git.eeqj.de/sneak/vaultik/internal/snapshot"
"github.com/dustin/go-humanize"
"github.com/klauspost/compress/zstd"
"github.com/spf13/cobra"
"go.uber.org/fx"
)
@@ -66,7 +64,7 @@ specifying a path using --config or by setting VAULTIK_CONFIG to a path.`,
Debug: rootFlags.Debug,
},
Modules: []fx.Option{
backup.Module,
snapshot.Module,
s3.Module,
fx.Provide(fx.Annotate(
func(g *globals.Globals, cfg *config.Config, repos *database.Repositories,
@@ -195,8 +193,8 @@ func (app *PruneApp) runPrune(ctx context.Context, opts *PruneOptions) error {
// Step 5: Build set of referenced blobs
referencedBlobs := make(map[string]bool)
for _, blobHash := range manifest.Blobs {
referencedBlobs[blobHash] = true
for _, blob := range manifest.Blobs {
referencedBlobs[blob.Hash] = true
}
// Step 6: List all blobs in S3
@@ -277,16 +275,8 @@ func (app *PruneApp) runPrune(ctx context.Context, opts *PruneOptions) error {
return nil
}
// BlobManifest represents the structure of a snapshot's blob manifest
type BlobManifest struct {
SnapshotID string `json:"snapshot_id"`
Timestamp string `json:"timestamp"`
BlobCount int `json:"blob_count"`
Blobs []string `json:"blobs"`
}
// downloadManifest downloads and decompresses a snapshot manifest
func (app *PruneApp) downloadManifest(ctx context.Context, snapshotID string) (*BlobManifest, error) {
func (app *PruneApp) downloadManifest(ctx context.Context, snapshotID string) (*snapshot.Manifest, error) {
manifestPath := fmt.Sprintf("metadata/%s/manifest.json.zst", snapshotID)
// Download the compressed manifest
@@ -296,18 +286,11 @@ func (app *PruneApp) downloadManifest(ctx context.Context, snapshotID string) (*
}
defer func() { _ = reader.Close() }()
// Decompress using zstd
zr, err := zstd.NewReader(reader)
// Decode manifest
manifest, err := snapshot.DecodeManifest(reader)
if err != nil {
return nil, fmt.Errorf("creating zstd reader: %w", err)
}
defer zr.Close()
// Decode JSON manifest
var manifest BlobManifest
if err := json.NewDecoder(zr).Decode(&manifest); err != nil {
return nil, fmt.Errorf("decoding manifest: %w", err)
}
return &manifest, nil
return manifest, nil
}