restic/src/cmds/restic/cmd_mount.go

114 lines
2.3 KiB
Go
Raw Normal View History

// +build !openbsd
// +build !windows
2015-04-07 19:10:53 +00:00
package main
import (
"os"
2016-09-17 10:36:05 +00:00
"github.com/spf13/cobra"
2016-09-15 19:17:20 +00:00
"restic/debug"
2016-09-01 20:17:37 +00:00
"restic/errors"
resticfs "restic/fs"
"restic/fuse"
2015-04-07 19:10:53 +00:00
2015-07-19 12:28:11 +00:00
systemFuse "bazil.org/fuse"
2015-04-07 19:10:53 +00:00
"bazil.org/fuse/fs"
)
2016-09-17 10:36:05 +00:00
var cmdMount = &cobra.Command{
Use: "mount [flags] mountpoint",
Short: "mount the repository",
Long: `
The "mount" command mounts the repository via fuse to a directory. This is a
read-only mount.
`,
RunE: func(cmd *cobra.Command, args []string) error {
return runMount(mountOptions, globalOptions, args)
},
}
2016-09-17 10:36:05 +00:00
// MountOptions collects all options for the mount command.
type MountOptions struct {
OwnerRoot bool
2015-04-07 19:10:53 +00:00
}
2016-09-17 10:36:05 +00:00
var mountOptions MountOptions
2015-04-07 19:10:53 +00:00
func init() {
2016-09-17 10:36:05 +00:00
cmdRoot.AddCommand(cmdMount)
2015-04-07 19:10:53 +00:00
2016-09-17 10:36:05 +00:00
cmdMount.Flags().BoolVar(&mountOptions.OwnerRoot, "owner-root", false, "use 'root' as the owner of files and dirs")
2015-04-07 19:10:53 +00:00
}
2016-09-17 10:36:05 +00:00
func mount(opts MountOptions, gopts GlobalOptions, mountpoint string) error {
2016-09-15 19:17:20 +00:00
debug.Log("mount", "start mount")
defer debug.Log("mount", "finish mount")
2015-04-07 19:10:53 +00:00
2016-09-17 10:36:05 +00:00
repo, err := OpenRepository(gopts)
2015-04-07 19:10:53 +00:00
if err != nil {
return err
}
err = repo.LoadIndex()
if err != nil {
return err
}
if _, err := resticfs.Stat(mountpoint); os.IsNotExist(errors.Cause(err)) {
2016-09-17 10:36:05 +00:00
Verbosef("Mountpoint %s doesn't exist, creating it\n", mountpoint)
err = resticfs.Mkdir(mountpoint, os.ModeDir|0700)
2015-07-19 12:08:34 +00:00
if err != nil {
return err
2015-04-07 19:10:53 +00:00
}
}
2015-07-19 12:28:11 +00:00
c, err := systemFuse.Mount(
2015-04-07 19:10:53 +00:00
mountpoint,
2015-07-19 12:28:11 +00:00
systemFuse.ReadOnly(),
systemFuse.FSName("restic"),
2015-04-07 19:10:53 +00:00
)
if err != nil {
return err
}
2016-09-17 10:36:05 +00:00
Printf("Now serving the repository at %s\n", mountpoint)
Printf("Don't forget to umount after quitting!\n")
2015-04-07 19:10:53 +00:00
root := fs.Tree{}
2016-09-17 10:36:05 +00:00
root.Add("snapshots", fuse.NewSnapshotsDir(repo, opts.OwnerRoot))
2015-04-07 19:10:53 +00:00
2016-09-15 19:17:20 +00:00
debug.Log("mount", "serving mount at %v", mountpoint)
err = fs.Serve(c, &root)
if err != nil {
return err
}
<-c.Ready
return c.MountError
}
2016-09-17 10:36:05 +00:00
func umount(mountpoint string) error {
2016-09-15 19:17:20 +00:00
return systemFuse.Unmount(mountpoint)
}
2016-09-17 10:36:05 +00:00
func runMount(opts MountOptions, gopts GlobalOptions, args []string) error {
2016-09-15 19:17:20 +00:00
if len(args) == 0 {
2016-09-17 10:36:05 +00:00
return errors.Fatalf("wrong number of parameters")
2016-09-15 19:17:20 +00:00
}
mountpoint := args[0]
2015-04-07 19:10:53 +00:00
AddCleanupHandler(func() error {
2016-09-15 19:17:20 +00:00
debug.Log("mount", "running umount cleanup handler for mount at %v", mountpoint)
2016-09-17 10:36:05 +00:00
err := umount(mountpoint)
if err != nil {
2016-09-17 10:36:05 +00:00
Warnf("unable to umount (maybe already umounted?): %v\n", err)
}
2016-09-15 17:59:07 +00:00
return nil
})
2016-09-17 10:36:05 +00:00
return mount(opts, gopts, mountpoint)
2015-04-07 19:10:53 +00:00
}