New helper function FindFilteredSnapshots to iterate over snapshots

This helper function takes a set of filters and/or a list of snapshots
from the commandline. It returns a channel of *Snapshot.

When snapshot ids are given, they are checked for validity and their
corresponding Snapshots returned. The snapshot id "latest" is handled
special to return either the last snapshot (no filters) or the last
snapshot matching the filters.

When no arguments are given, the filters are applied over all available
snapshots and these are returned.
This commit is contained in:
Pauline Middelink 2017-03-08 20:19:12 +01:00
parent 0f7b6ec5ac
commit 11d237c252

78
src/cmds/restic/find.go Normal file
View file

@ -0,0 +1,78 @@
package main
import (
"context"
"restic"
"restic/repository"
)
// FindFilteredSnapshots yields Snapshots, either given explicitly by `snapshotIDs` or filtered from the list of all snapshots.
func FindFilteredSnapshots(ctx context.Context, repo *repository.Repository, host string, tags []string, paths []string, snapshotIDs []string) <-chan *restic.Snapshot {
out := make(chan *restic.Snapshot)
go func() {
defer close(out)
if len(snapshotIDs) != 0 {
var (
id restic.ID
usedFilter bool
err error
)
ids := make(restic.IDs, 0, len(snapshotIDs))
// Process all snapshot IDs given as arguments.
for _, s := range snapshotIDs {
if s == "latest" {
id, err = restic.FindLatestSnapshot(repo, paths, tags, host)
if err != nil {
Warnf("Ignoring %q, no snapshot matched given filter (Paths:%v Tags:%v Host:%v)\n", s, paths, tags, host)
usedFilter = true
continue
}
} else {
id, err = restic.FindSnapshot(repo, s)
if err != nil {
Warnf("Ignoring %q, it is not a snapshot id\n", s)
continue
}
}
ids = append(ids, id)
}
// Give the user some indication their filters are not used.
if !usedFilter && (host != "" || len(tags) != 0 || len(paths) != 0) {
Warnf("Ignoring filters as there are explicit snapshot ids given\n")
}
for _, id := range ids.Uniq() {
sn, err := restic.LoadSnapshot(repo, id)
if err != nil {
Warnf("Ignoring %q, could not load snapshot: %v\n", id, err)
continue
}
select {
case <-ctx.Done():
return
case out <- sn:
}
}
return
}
for id := range repo.List(restic.SnapshotFile, ctx.Done()) {
sn, err := restic.LoadSnapshot(repo, id)
if err != nil {
Warnf("Ignoring %q, could not load snapshot: %v\n", id, err)
continue
}
if (host != "" && host != sn.Hostname) || !sn.HasTags(tags) || !sn.HasPaths(paths) {
continue
}
select {
case <-ctx.Done():
return
case out <- sn:
}
}
}()
return out
}