refactor: remove backward compat wrapper and legacy snapshot support
All checks were successful
check / check (pull_request) Successful in 2m26s
All checks were successful
check / check (pull_request) Successful in 2m26s
- Remove PurgeSnapshots wrapper; callers use PurgeSnapshotsWithOptions directly - Update snapshot create --prune to call PurgeSnapshotsWithOptions - Remove TestSnapshotPurgeOptions (tested Go struct assignment, no value) - Remove legacy no-name snapshot tests (TestPurgeKeepLatest_LegacyNoNameSnapshots, TestPurgeKeepLatest_MixedNamedAndLegacy) - Remove legacy format test cases from TestParseSnapshotName - Update parseSnapshotName doc to not mention legacy format
This commit is contained in:
@@ -80,8 +80,9 @@ func parseSnapshotTimestamp(snapshotID string) (time.Time, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// parseSnapshotName extracts the snapshot name from a snapshot ID.
|
// parseSnapshotName extracts the snapshot name from a snapshot ID.
|
||||||
// Format: hostname_snapshotname_timestamp (3 parts) or hostname_timestamp (2 parts, no name).
|
// Format: hostname_snapshotname_timestamp — the middle part(s) between hostname
|
||||||
// Returns the snapshot name, or empty string if no name component is present.
|
// and the RFC3339 timestamp are the snapshot name (may contain underscores).
|
||||||
|
// Returns the snapshot name, or empty string if the ID is malformed.
|
||||||
func parseSnapshotName(snapshotID string) string {
|
func parseSnapshotName(snapshotID string) string {
|
||||||
parts := strings.Split(snapshotID, "_")
|
parts := strings.Split(snapshotID, "_")
|
||||||
if len(parts) < 3 {
|
if len(parts) < 3 {
|
||||||
|
|||||||
@@ -20,26 +20,11 @@ func TestParseSnapshotName(t *testing.T) {
|
|||||||
snapshotID: "server1_system_2026-02-15T09:30:00Z",
|
snapshotID: "server1_system_2026-02-15T09:30:00Z",
|
||||||
want: "system",
|
want: "system",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "no snapshot name (legacy format)",
|
|
||||||
snapshotID: "myhost_2026-01-12T14:41:15Z",
|
|
||||||
want: "",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "name with underscores",
|
name: "name with underscores",
|
||||||
snapshotID: "myhost_my_special_backup_2026-03-01T00:00:00Z",
|
snapshotID: "myhost_my_special_backup_2026-03-01T00:00:00Z",
|
||||||
want: "my_special_backup",
|
want: "my_special_backup",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "single part (edge case)",
|
|
||||||
snapshotID: "nounderscore",
|
|
||||||
want: "",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "empty string",
|
|
||||||
snapshotID: "",
|
|
||||||
want: "",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
@@ -89,31 +74,3 @@ func TestParseSnapshotTimestamp(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSnapshotPurgeOptions(t *testing.T) {
|
|
||||||
opts := &SnapshotPurgeOptions{
|
|
||||||
KeepLatest: true,
|
|
||||||
Name: "home",
|
|
||||||
Force: true,
|
|
||||||
}
|
|
||||||
if !opts.KeepLatest {
|
|
||||||
t.Error("Expected KeepLatest to be true")
|
|
||||||
}
|
|
||||||
if opts.Name != "home" {
|
|
||||||
t.Errorf("Expected Name to be 'home', got %q", opts.Name)
|
|
||||||
}
|
|
||||||
if !opts.Force {
|
|
||||||
t.Error("Expected Force to be true")
|
|
||||||
}
|
|
||||||
|
|
||||||
opts2 := &SnapshotPurgeOptions{
|
|
||||||
OlderThan: "30d",
|
|
||||||
Name: "system",
|
|
||||||
}
|
|
||||||
if opts2.OlderThan != "30d" {
|
|
||||||
t.Errorf("Expected OlderThan to be '30d', got %q", opts2.OlderThan)
|
|
||||||
}
|
|
||||||
if opts2.Name != "system" {
|
|
||||||
t.Errorf("Expected Name to be 'system', got %q", opts2.Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -228,53 +228,6 @@ func TestPurgeOlderThan_WithNameFilter(t *testing.T) {
|
|||||||
assert.Contains(t, remaining, "testhost_home_2026-01-01T00:00:00Z")
|
assert.Contains(t, remaining, "testhost_home_2026-01-01T00:00:00Z")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPurgeKeepLatest_LegacyNoNameSnapshots(t *testing.T) {
|
|
||||||
// Legacy snapshots without a name component (hostname_timestamp).
|
|
||||||
// Should be grouped together under empty-name.
|
|
||||||
snapshotIDs := []string{
|
|
||||||
"testhost_2026-01-01T00:00:00Z",
|
|
||||||
"testhost_2026-01-01T01:00:00Z",
|
|
||||||
"testhost_2026-01-01T02:00:00Z",
|
|
||||||
}
|
|
||||||
|
|
||||||
v := setupPurgeTest(t, snapshotIDs)
|
|
||||||
|
|
||||||
err := v.PurgeSnapshotsWithOptions(&vaultik.SnapshotPurgeOptions{
|
|
||||||
KeepLatest: true,
|
|
||||||
Force: true,
|
|
||||||
})
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
remaining := listRemainingSnapshots(t, v)
|
|
||||||
assert.Len(t, remaining, 1)
|
|
||||||
assert.Contains(t, remaining, "testhost_2026-01-01T02:00:00Z")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPurgeKeepLatest_MixedNamedAndLegacy(t *testing.T) {
|
|
||||||
// Mix of named snapshots and legacy ones (no name).
|
|
||||||
snapshotIDs := []string{
|
|
||||||
"testhost_2026-01-01T00:00:00Z",
|
|
||||||
"testhost_home_2026-01-01T01:00:00Z",
|
|
||||||
"testhost_2026-01-01T02:00:00Z",
|
|
||||||
"testhost_home_2026-01-01T03:00:00Z",
|
|
||||||
}
|
|
||||||
|
|
||||||
v := setupPurgeTest(t, snapshotIDs)
|
|
||||||
|
|
||||||
err := v.PurgeSnapshotsWithOptions(&vaultik.SnapshotPurgeOptions{
|
|
||||||
KeepLatest: true,
|
|
||||||
Force: true,
|
|
||||||
})
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
remaining := listRemainingSnapshots(t, v)
|
|
||||||
|
|
||||||
// Should keep latest of each group: latest legacy + latest home
|
|
||||||
assert.Len(t, remaining, 2)
|
|
||||||
assert.Contains(t, remaining, "testhost_2026-01-01T02:00:00Z")
|
|
||||||
assert.Contains(t, remaining, "testhost_home_2026-01-01T03:00:00Z")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPurgeKeepLatest_ThreeNames(t *testing.T) {
|
func TestPurgeKeepLatest_ThreeNames(t *testing.T) {
|
||||||
// Three different snapshot names with multiple snapshots each.
|
// Three different snapshot names with multiple snapshots each.
|
||||||
snapshotIDs := []string{
|
snapshotIDs := []string{
|
||||||
|
|||||||
@@ -95,7 +95,10 @@ func (v *Vaultik) CreateSnapshot(opts *SnapshotCreateOptions) error {
|
|||||||
log.Info("Pruning enabled - deleting old snapshots and unreferenced blobs")
|
log.Info("Pruning enabled - deleting old snapshots and unreferenced blobs")
|
||||||
v.printlnStdout("\nPruning old snapshots (keeping latest)...")
|
v.printlnStdout("\nPruning old snapshots (keeping latest)...")
|
||||||
|
|
||||||
if err := v.PurgeSnapshots(true, "", true); err != nil {
|
if err := v.PurgeSnapshotsWithOptions(&SnapshotPurgeOptions{
|
||||||
|
KeepLatest: true,
|
||||||
|
Force: true,
|
||||||
|
}); err != nil {
|
||||||
return fmt.Errorf("prune: purging old snapshots: %w", err)
|
return fmt.Errorf("prune: purging old snapshots: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -528,18 +531,7 @@ type SnapshotPurgeOptions struct {
|
|||||||
Name string // Filter purge to a specific snapshot name
|
Name string // Filter purge to a specific snapshot name
|
||||||
}
|
}
|
||||||
|
|
||||||
// PurgeSnapshots removes old snapshots based on criteria.
|
// PurgeSnapshotsWithOptions removes old snapshots based on criteria.
|
||||||
// When keepLatest is true, retention is applied per snapshot name — the latest
|
|
||||||
// snapshot for each distinct name is kept.
|
|
||||||
func (v *Vaultik) PurgeSnapshots(keepLatest bool, olderThan string, force bool) error {
|
|
||||||
return v.PurgeSnapshotsWithOptions(&SnapshotPurgeOptions{
|
|
||||||
KeepLatest: keepLatest,
|
|
||||||
OlderThan: olderThan,
|
|
||||||
Force: force,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// PurgeSnapshotsWithOptions removes old snapshots based on criteria with full options.
|
|
||||||
// When KeepLatest is true, retention is applied per snapshot name — the latest
|
// When KeepLatest is true, retention is applied per snapshot name — the latest
|
||||||
// snapshot for each distinct name is kept. If Name is non-empty, only snapshots
|
// snapshot for each distinct name is kept. If Name is non-empty, only snapshots
|
||||||
// matching that name are considered for purge.
|
// matching that name are considered for purge.
|
||||||
|
|||||||
Reference in New Issue
Block a user