package ipns import ( "fmt" "os" "os/exec" "os/signal" "runtime" "syscall" "time" "github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse" "github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs" "github.com/jbenet/go-ipfs/core" ) // Mount mounts an IpfsNode instance at a particular path. It // serves until the process receives exit signals (to Unmount). func Mount(ipfs *core.IpfsNode, fpath string, ipfspath string) error { sigc := make(chan os.Signal, 1) signal.Notify(sigc, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) go func() { defer ipfs.Network.Close() <-sigc for { err := Unmount(fpath) if err == nil { return } time.Sleep(time.Millisecond * 100) } }() c, err := fuse.Mount(fpath) if err != nil { return err } defer c.Close() fsys, err := NewIpns(ipfs, ipfspath) if err != nil { return err } err = fs.Serve(c, fsys) if err != nil { return err } // check if the mount process has an error to report <-c.Ready if err := c.MountError; err != nil { return err } return nil } // Unmount attempts to unmount the provided FUSE mount point, forcibly // if necessary. func Unmount(point string) error { fmt.Printf("Unmounting %s...\n", point) var cmd *exec.Cmd switch runtime.GOOS { case "darwin": cmd = exec.Command("diskutil", "umount", "force", point) case "linux": cmd = exec.Command("fusermount", "-u", point) default: return fmt.Errorf("unmount: unimplemented") } errc := make(chan error, 1) go func() { if err := exec.Command("umount", point).Run(); err == nil { errc <- err } // retry to unmount with the fallback cmd errc <- cmd.Run() }() select { case <-time.After(1 * time.Second): return fmt.Errorf("umount timeout") case err := <-errc: return err } }