github.com/mckael/restic@v0.8.3/internal/restic/snapshot_find.go (about) 1 package restic 2 3 import ( 4 "context" 5 "fmt" 6 "os" 7 "time" 8 9 "github.com/restic/restic/internal/errors" 10 ) 11 12 // ErrNoSnapshotFound is returned when no snapshot for the given criteria could be found. 13 var ErrNoSnapshotFound = errors.New("no snapshot found") 14 15 // FindLatestSnapshot finds latest snapshot with optional target/directory, tags and hostname filters. 16 func FindLatestSnapshot(ctx context.Context, repo Repository, targets []string, tagLists []TagList, hostname string) (ID, error) { 17 var ( 18 latest time.Time 19 latestID ID 20 found bool 21 ) 22 23 err := repo.List(ctx, SnapshotFile, func(snapshotID ID, size int64) error { 24 snapshot, err := LoadSnapshot(ctx, repo, snapshotID) 25 if err != nil { 26 return errors.Errorf("Error loading snapshot %v: %v", snapshotID.Str(), err) 27 } 28 if snapshot.Time.Before(latest) || (hostname != "" && hostname != snapshot.Hostname) { 29 return nil 30 } 31 32 if !snapshot.HasTagList(tagLists) { 33 return nil 34 } 35 36 if !snapshot.HasPaths(targets) { 37 return nil 38 } 39 40 latest = snapshot.Time 41 latestID = snapshotID 42 found = true 43 return nil 44 }) 45 46 if err != nil { 47 return ID{}, err 48 } 49 50 if !found { 51 return ID{}, ErrNoSnapshotFound 52 } 53 54 return latestID, nil 55 } 56 57 // FindSnapshot takes a string and tries to find a snapshot whose ID matches 58 // the string as closely as possible. 59 func FindSnapshot(repo Repository, s string) (ID, error) { 60 61 // find snapshot id with prefix 62 name, err := Find(repo.Backend(), SnapshotFile, s) 63 if err != nil { 64 return ID{}, err 65 } 66 67 return ParseID(name) 68 } 69 70 // FindFilteredSnapshots yields Snapshots filtered from the list of all 71 // snapshots. 72 func FindFilteredSnapshots(ctx context.Context, repo Repository, host string, tags []TagList, paths []string) (Snapshots, error) { 73 results := make(Snapshots, 0, 20) 74 75 err := repo.List(ctx, SnapshotFile, func(id ID, size int64) error { 76 sn, err := LoadSnapshot(ctx, repo, id) 77 if err != nil { 78 fmt.Fprintf(os.Stderr, "could not load snapshot %v: %v\n", id.Str(), err) 79 return nil 80 } 81 82 if (host != "" && host != sn.Hostname) || !sn.HasTagList(tags) || !sn.HasPaths(paths) { 83 return nil 84 } 85 86 results = append(results, sn) 87 return nil 88 }) 89 90 if err != nil { 91 return nil, err 92 } 93 94 return results, nil 95 }