Bind the local index to its backup destination
The local index tracks which chunks and blobs already exist at the backup destination. Nothing was recording *which* destination, so changing storage_url and running a backup left the scanner treating every already-seen chunk as still-present at the new (empty) location. Uploads were skipped silently and the resulting snapshots pointed at blobs that don't exist at the new destination. Fix: record storage_url in a new local_meta key-value table on first mutating command, and refuse to proceed when the configured URL later differs from the stored one. The error explains the two recovery paths (revert the config, or run 'vaultik database purge' to discard the index and rebuild from a fresh full backup). Wired into snapshot create / prune / snapshot remove / snapshot purge / snapshot cleanup. Read-only inspection commands (snapshot list, remote info, store info) are exempt.
This commit is contained in:
52
internal/database/local_meta_test.go
Normal file
52
internal/database/local_meta_test.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package database_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"sneak.berlin/go/vaultik/internal/database"
|
||||
)
|
||||
|
||||
func TestLocalMetaEmptyOnFresh(t *testing.T) {
|
||||
db, err := database.NewTestDB()
|
||||
require.NoError(t, err)
|
||||
defer func() { _ = db.Close() }()
|
||||
|
||||
repos := database.NewRepositories(db)
|
||||
|
||||
got, err := repos.LocalMeta.Get(context.Background(), database.LocalMetaKeyStorageURL)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "", got, "fresh DB must return empty for unset keys, not error")
|
||||
}
|
||||
|
||||
func TestLocalMetaSetGetRoundTrip(t *testing.T) {
|
||||
db, err := database.NewTestDB()
|
||||
require.NoError(t, err)
|
||||
defer func() { _ = db.Close() }()
|
||||
|
||||
repos := database.NewRepositories(db)
|
||||
ctx := context.Background()
|
||||
|
||||
require.NoError(t, repos.LocalMeta.Set(ctx, database.LocalMetaKeyStorageURL, "file:///mnt/backups"))
|
||||
|
||||
got, err := repos.LocalMeta.Get(ctx, database.LocalMetaKeyStorageURL)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "file:///mnt/backups", got)
|
||||
}
|
||||
|
||||
func TestLocalMetaSetOverwrites(t *testing.T) {
|
||||
db, err := database.NewTestDB()
|
||||
require.NoError(t, err)
|
||||
defer func() { _ = db.Close() }()
|
||||
|
||||
repos := database.NewRepositories(db)
|
||||
ctx := context.Background()
|
||||
|
||||
require.NoError(t, repos.LocalMeta.Set(ctx, database.LocalMetaKeyStorageURL, "s3://old"))
|
||||
require.NoError(t, repos.LocalMeta.Set(ctx, database.LocalMetaKeyStorageURL, "s3://new"))
|
||||
|
||||
got, err := repos.LocalMeta.Get(ctx, database.LocalMetaKeyStorageURL)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "s3://new", got)
|
||||
}
|
||||
Reference in New Issue
Block a user