From 11d237c2528d6996cdbefdb81383748923cec79d Mon Sep 17 00:00:00 2001 From: Pauline Middelink Date: Wed, 8 Mar 2017 20:19:12 +0100 Subject: [PATCH] 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. --- src/cmds/restic/find.go | 78 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 src/cmds/restic/find.go diff --git a/src/cmds/restic/find.go b/src/cmds/restic/find.go new file mode 100644 index 000000000..fa9d71694 --- /dev/null +++ b/src/cmds/restic/find.go @@ -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 +}