restic/cmd/restic/cmd_mount.go

105 lines
1.9 KiB
Go
Raw Normal View History

// +build !openbsd
2015-04-07 19:10:53 +00:00
package main
import (
"fmt"
"os"
2015-07-26 15:20:26 +00:00
"github.com/restic/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"
)
type CmdMount struct {
global *GlobalOptions
ready chan struct{}
done chan struct{}
2015-04-07 19:10:53 +00:00
}
func init() {
_, err := parser.AddCommand("mount",
"mount a repository",
"The mount command mounts a repository read-only to a given directory",
&CmdMount{
global: &globalOpts,
ready: make(chan struct{}, 1),
done: make(chan struct{}),
})
2015-04-07 19:10:53 +00:00
if err != nil {
panic(err)
}
}
func (cmd CmdMount) Usage() string {
return "MOUNTPOINT"
}
func (cmd CmdMount) Execute(args []string) error {
if len(args) == 0 {
return fmt.Errorf("wrong number of parameters, Usage: %s", cmd.Usage())
}
repo, err := cmd.global.OpenRepository()
if err != nil {
return err
}
err = repo.LoadIndex()
if err != nil {
return err
}
mountpoint := args[0]
2015-07-19 12:08:34 +00:00
if _, err := os.Stat(mountpoint); os.IsNotExist(err) {
cmd.global.Verbosef("Mountpoint %s doesn't exist, creating it\n", mountpoint)
err = os.Mkdir(mountpoint, os.ModeDir|0700)
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
}
root := fs.Tree{}
2015-07-19 12:28:11 +00:00
root.Add("snapshots", fuse.NewSnapshotsDir(repo))
2015-04-07 19:10:53 +00:00
2015-07-19 12:08:34 +00:00
cmd.global.Printf("Now serving %s at %s\n", repo.Backend().Location(), mountpoint)
cmd.global.Printf("Don't forget to umount after quitting!\n")
2015-04-07 19:10:53 +00:00
AddCleanupHandler(func() error {
return systemFuse.Unmount(mountpoint)
})
cmd.ready <- struct{}{}
errServe := make(chan error)
go func() {
err = fs.Serve(c, &root)
if err != nil {
errServe <- err
}
<-c.Ready
errServe <- c.MountError
}()
select {
case err := <-errServe:
2015-04-07 19:10:53 +00:00
return err
case <-cmd.done:
err := c.Close()
if err != nil {
cmd.global.Printf("Error closing fuse connection: %s\n", err)
}
return systemFuse.Unmount(mountpoint)
2015-04-07 19:10:53 +00:00
}
}