mirror of
https://github.com/restic/restic.git
synced 2025-12-04 03:38:25 +00:00
Avoid choosing parent snapshot newer than time of current snapshot
Currently, `restic backup` (if a `--parent` is not provided) will choose the most recent matching snapshot as the parent snapshot. This makes sense in the usual case, where we tag the snapshot-being-created with the current time. However, this doesn't make sense if the user has passed `--time` and is currently creating a snapshot older than the latest snapshot. Instead, choose the most recent snapshot which is not newer than the snapshot-being-created's timestamp, to avoid any time travel. Impetus for this change: I'm using restic for the first time! I have a number of existing BTRFS snapshots I am backing up via restic to serve as my initial set of backups. I initially `restic backup`'d the most recent snapshot to test, then started backing up each of the other snapshots. I noticed in `restic cat snapshot <id>` output that all the remaining snapshots have the most recent as the parent.
This commit is contained in:
@@ -13,8 +13,8 @@ import (
|
||||
// ErrNoSnapshotFound is returned when no snapshot for the given criteria could be found.
|
||||
var ErrNoSnapshotFound = errors.New("no snapshot found")
|
||||
|
||||
// FindLatestSnapshot finds latest snapshot with optional target/directory, tags and hostname filters.
|
||||
func FindLatestSnapshot(ctx context.Context, repo Repository, targets []string, tagLists []TagList, hostnames []string) (ID, error) {
|
||||
// FindLatestSnapshot finds latest snapshot with optional target/directory, tags, hostname, and timestamp filters.
|
||||
func FindLatestSnapshot(ctx context.Context, repo Repository, targets []string, tagLists []TagList, hostnames []string, timeStamp *time.Time) (ID, error) {
|
||||
var err error
|
||||
absTargets := make([]string, 0, len(targets))
|
||||
for _, target := range targets {
|
||||
@@ -38,6 +38,10 @@ func FindLatestSnapshot(ctx context.Context, repo Repository, targets []string,
|
||||
return errors.Errorf("Error loading snapshot %v: %v", id.Str(), err)
|
||||
}
|
||||
|
||||
if timeStamp != nil && snapshot.Time.After(*timeStamp) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if snapshot.Time.Before(latest) {
|
||||
return nil
|
||||
}
|
||||
|
||||
47
internal/restic/snapshot_find_test.go
Normal file
47
internal/restic/snapshot_find_test.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package restic_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/restic/restic/internal/repository"
|
||||
"github.com/restic/restic/internal/restic"
|
||||
)
|
||||
|
||||
func TestFindLatestSnapshot(t *testing.T) {
|
||||
repo, cleanup := repository.TestRepository(t)
|
||||
defer cleanup()
|
||||
|
||||
restic.TestCreateSnapshot(t, repo, parseTimeUTC("2015-05-05 05:05:05"), 1, 0)
|
||||
restic.TestCreateSnapshot(t, repo, parseTimeUTC("2017-07-07 07:07:07"), 1, 0)
|
||||
latestSnapshot := restic.TestCreateSnapshot(t, repo, parseTimeUTC("2019-09-09 09:09:09"), 1, 0)
|
||||
|
||||
id, err := restic.FindLatestSnapshot(context.TODO(), repo, []string{}, []restic.TagList{}, []string{"foo"}, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("FindLatestSnapshot returned error: %v", err)
|
||||
}
|
||||
|
||||
if id != *latestSnapshot.ID() {
|
||||
t.Errorf("FindLatestSnapshot returned wrong snapshot ID: %v", id)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindLatestSnapshotWithMaxTimestamp(t *testing.T) {
|
||||
repo, cleanup := repository.TestRepository(t)
|
||||
defer cleanup()
|
||||
|
||||
restic.TestCreateSnapshot(t, repo, parseTimeUTC("2015-05-05 05:05:05"), 1, 0)
|
||||
desiredSnapshot := restic.TestCreateSnapshot(t, repo, parseTimeUTC("2017-07-07 07:07:07"), 1, 0)
|
||||
restic.TestCreateSnapshot(t, repo, parseTimeUTC("2019-09-09 09:09:09"), 1, 0)
|
||||
|
||||
maxTimestamp := parseTimeUTC("2018-08-08 08:08:08")
|
||||
|
||||
id, err := restic.FindLatestSnapshot(context.TODO(), repo, []string{}, []restic.TagList{}, []string{"foo"}, &maxTimestamp)
|
||||
if err != nil {
|
||||
t.Fatalf("FindLatestSnapshot returned error: %v", err)
|
||||
}
|
||||
|
||||
if id != *desiredSnapshot.ID() {
|
||||
t.Errorf("FindLatestSnapshot returned wrong snapshot ID: %v", id)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user