From b1c8071163398c744cb02f5736f4d87f69f442b3 Mon Sep 17 00:00:00 2001 From: Pauline Middelink Date: Wed, 8 Mar 2017 19:59:19 +0100 Subject: [PATCH] Add filtering to `mount` command --- src/cmds/restic/cmd_mount.go | 16 ++++++++++++---- src/restic/fuse/snapshot.go | 17 +++++++++++++++-- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/cmds/restic/cmd_mount.go b/src/cmds/restic/cmd_mount.go index a4b8340cd..20ce5dec3 100644 --- a/src/cmds/restic/cmd_mount.go +++ b/src/cmds/restic/cmd_mount.go @@ -35,6 +35,9 @@ type MountOptions struct { OwnerRoot bool AllowRoot bool AllowOther bool + Host string + Tags []string + Paths []string } var mountOptions MountOptions @@ -42,9 +45,14 @@ var mountOptions MountOptions func init() { cmdRoot.AddCommand(cmdMount) - cmdMount.Flags().BoolVar(&mountOptions.OwnerRoot, "owner-root", false, "use 'root' as the owner of files and dirs") - cmdMount.Flags().BoolVar(&mountOptions.AllowRoot, "allow-root", false, "allow root user to access the data in the mounted directory") - cmdMount.Flags().BoolVar(&mountOptions.AllowOther, "allow-other", false, "allow other users to access the data in the mounted directory") + mountFlags := cmdMount.Flags() + mountFlags.BoolVar(&mountOptions.OwnerRoot, "owner-root", false, "use 'root' as the owner of files and dirs") + mountFlags.BoolVar(&mountOptions.AllowRoot, "allow-root", false, "allow root user to access the data in the mounted directory") + mountFlags.BoolVar(&mountOptions.AllowOther, "allow-other", false, "allow other users to access the data in the mounted directory") + + mountFlags.StringVarP(&mountOptions.Host, "host", "H", "", `only consider snapshots for this host`) + mountFlags.StringSliceVar(&mountOptions.Tags, "tag", nil, "only consider snapshots which include this `tag`") + mountFlags.StringSliceVar(&mountOptions.Paths, "path", nil, "only consider snapshots which include this (absolute) `path`") } func mount(opts MountOptions, gopts GlobalOptions, mountpoint string) error { @@ -91,7 +99,7 @@ func mount(opts MountOptions, gopts GlobalOptions, mountpoint string) error { Printf("Don't forget to umount after quitting!\n") root := fs.Tree{} - root.Add("snapshots", fuse.NewSnapshotsDir(repo, opts.OwnerRoot)) + root.Add("snapshots", fuse.NewSnapshotsDir(repo, opts.OwnerRoot, opts.Paths, opts.Tags, opts.Host)) debug.Log("serving mount at %v", mountpoint) err = fs.Serve(c, &root) diff --git a/src/restic/fuse/snapshot.go b/src/restic/fuse/snapshot.go index 1e1092dea..2a654397b 100644 --- a/src/restic/fuse/snapshot.go +++ b/src/restic/fuse/snapshot.go @@ -32,6 +32,9 @@ var _ = fs.NodeStringLookuper(&SnapshotsDir{}) type SnapshotsDir struct { repo restic.Repository ownerIsRoot bool + paths []string + tags []string + host string // knownSnapshots maps snapshot timestamp to the snapshot sync.RWMutex @@ -40,12 +43,15 @@ type SnapshotsDir struct { } // NewSnapshotsDir returns a new dir object for the snapshots. -func NewSnapshotsDir(repo restic.Repository, ownerIsRoot bool) *SnapshotsDir { +func NewSnapshotsDir(repo restic.Repository, ownerIsRoot bool, paths []string, tags []string, host string) *SnapshotsDir { debug.Log("fuse mount initiated") return &SnapshotsDir{ repo: repo, - knownSnapshots: make(map[string]SnapshotWithId), ownerIsRoot: ownerIsRoot, + paths: paths, + tags: tags, + host: host, + knownSnapshots: make(map[string]SnapshotWithId), processed: restic.NewIDSet(), } } @@ -79,6 +85,13 @@ func (sn *SnapshotsDir) updateCache(ctx context.Context) error { return err } + // Filter snapshots we don't care for. + if (sn.host != "" && sn.host != snapshot.Hostname) || + !snapshot.HasTags(sn.tags) || + !snapshot.HasPaths(sn.paths) { + continue + } + timestamp := snapshot.Time.Format(time.RFC3339) for i := 1; ; i++ { if _, ok := sn.knownSnapshots[timestamp]; !ok {