func TestRootErr(t *testing.T) { fuse.Debug = debug(t) dir, err := ioutil.TempDir("", "fusetest") if err != nil { t.Fatal(err) } os.MkdirAll(dir, 0777) c, err := fuse.Mount(dir) if err != nil { t.Fatal(err) } defer umount(dir) ch := make(chan error, 1) go func() { ch <- Serve(c, badRootFS{}) }() select { case err := <-ch: // TODO this is not be a textual comparison, Serve hides // details if err.Error() != "cannot obtain root node: file name too long" { t.Errorf("Unexpected error: %v", err) } case <-time.After(1 * time.Second): t.Fatal("Serve did not return an error as expected, aborting") } }
func main() { flag.Usage = Usage flag.Parse() if flag.NArg() != 1 { Usage() os.Exit(2) } mountpoint := flag.Arg(0) c, err := fuse.Mount( mountpoint, fuse.FSName("helloworld"), fuse.Subtype("hellofs"), fuse.LocalVolume(), fuse.VolumeName("Hello world!"), ) if err != nil { log.Fatal(err) } defer c.Close() err = fs.Serve(c, FS{}) if err != nil { log.Fatal(err) } // check if the mount process has an error to report <-c.Ready if err := c.MountError; err != nil { log.Fatal(err) } }
func TestStatfs(t *testing.T) { fuse.Debug = debug(t) dir, err := ioutil.TempDir("", "fusetest") if err != nil { t.Fatal(err) } os.MkdirAll(dir, 0777) c, err := fuse.Mount(dir) if err != nil { t.Fatal(err) } defer umount(dir) go func() { err := Serve(c, testStatFS{}) if err != nil { fmt.Printf("SERVE ERROR: %v\n", err) } }() waitForMount_inode1(t, dir) { var st syscall.Statfs_t err = syscall.Statfs(dir, &st) if err != nil { t.Errorf("Statfs failed: %v", err) } t.Logf("Statfs got: %#v", st) if g, e := st.Blocks, uint64(42); g != e { t.Errorf("got Blocks = %q; want %q", g, e) } if g, e := st.Files, uint64(13); g != e { t.Errorf("got Files = %d; want %d", g, e) } } { var st syscall.Statfs_t f, err := os.Open(dir) if err != nil { t.Errorf("Open for fstatfs failed: %v", err) } defer f.Close() err = syscall.Fstatfs(int(f.Fd()), &st) if err != nil { t.Errorf("Fstatfs failed: %v", err) } t.Logf("Fstatfs got: %#v", st) if g, e := st.Blocks, uint64(42); g != e { t.Errorf("got Blocks = %q; want %q", g, e) } if g, e := st.Files, uint64(13); g != e { t.Errorf("got Files = %d; want %d", g, e) } } }
func main() { flag.Usage = Usage flag.Parse() if flag.NArg() != 1 { Usage() os.Exit(2) } mountpoint := flag.Arg(0) c, err := fuse.Mount(mountpoint) if err != nil { log.Fatal(err) } fs.Serve(c, FS{}) }
func TestFuse(t *testing.T) { fuse.Debug = debug(t) dir, err := ioutil.TempDir("", "fusetest") if err != nil { t.Fatal(err) } os.MkdirAll(dir, 0777) for _, tt := range fuseTests { if *fuseRun == "" || *fuseRun == tt.name { if st, ok := tt.node.(interface { setup(*testing.T) }); ok { t.Logf("setting up %T", tt.node) st.setup(t) } } } c, err := fuse.Mount(dir) if err != nil { t.Fatal(err) } defer umount(dir) go func() { err := Serve(c, testFS{}) if err != nil { fmt.Printf("SERVE ERROR: %v\n", err) } }() waitForMount(t, dir) for _, tt := range fuseTests { if *fuseRun == "" || *fuseRun == tt.name { t.Logf("running %T", tt.node) tt.node.test(dir+"/"+tt.name, t) } } }
// Mounted mounts the fuse.Server at a temporary directory. // // It also waits until the filesystem is known to be visible (OS X // workaround). // // After successful return, caller must clean up by calling Close. func Mounted(srv *fs.Server, options ...fuse.MountOption) (*Mount, error) { dir, err := ioutil.TempDir("", "fusetest") if err != nil { return nil, err } c, err := fuse.Mount(dir, options...) if err != nil { return nil, err } done := make(chan struct{}) serveErr := make(chan error, 1) mnt := &Mount{ Dir: dir, Conn: c, Error: serveErr, done: done, } go func() { defer close(done) serveErr <- srv.Serve(c) }() select { case <-mnt.Conn.Ready: if mnt.Conn.MountError != nil { return nil, err } return mnt, err case err = <-mnt.Error: // Serve quit early if err != nil { return nil, err } return nil, errors.New("Serve exited early") } }
func main() { var conn *fuse.Conn // Scans the arg list and sets up flags client.AddFlags() flag.Usage = usage flag.Parse() narg := flag.NArg() if narg > 2 { usage() } var mountPoint string var err error if narg > 0 { mountPoint = flag.Arg(0) } else { mountPoint, err = ioutil.TempDir("", "cammount") if err != nil { log.Fatal(err) } log.Printf("No mount point given. Using: %s", mountPoint) defer os.Remove(mountPoint) } errorf := func(msg string, args ...interface{}) { fmt.Fprintf(os.Stderr, msg, args...) fmt.Fprint(os.Stderr, "\n") usage() } var ( cl *client.Client root blob.Ref // nil if only one arg camfs *fs.CamliFileSystem ) if narg == 2 { rootArg := flag.Arg(1) // not trying very hard since NewFromShareRoot will do it better with a regex if strings.HasPrefix(rootArg, "http://") || strings.HasPrefix(rootArg, "https://") { if client.ExplicitServer() != "" { errorf("Can't use an explicit blobserver with a share URL; the blobserver is implicit from the share URL.") } var err error cl, root, err = client.NewFromShareRoot(rootArg) if err != nil { log.Fatal(err) } } else { cl = client.NewOrFail() // automatic from flags cl.SetHTTPClient(&http.Client{Transport: cl.TransportForConfig(nil)}) var ok bool root, ok = blob.Parse(rootArg) if !ok { // not a blobref, check for root name instead req := &search.WithAttrRequest{N: 1, Attr: "camliRoot", Value: rootArg} wres, err := cl.GetPermanodesWithAttr(req) if err != nil { log.Fatal("could not query search") } if wres.WithAttr != nil { root = wres.WithAttr[0].Permanode } else { log.Fatalf("root specified is not a blobref or name of a root: %q\n", rootArg) } } } } else { cl = client.NewOrFail() // automatic from flags cl.SetHTTPClient(&http.Client{Transport: cl.TransportForConfig(nil)}) } diskCacheFetcher, err := cacher.NewDiskCache(cl) if err != nil { log.Fatalf("Error setting up local disk cache: %v", err) } defer diskCacheFetcher.Clean() if root.Valid() { var err error camfs, err = fs.NewRootedCamliFileSystem(cl, diskCacheFetcher, root) if err != nil { log.Fatalf("Error creating root with %v: %v", root, err) } } else { camfs = fs.NewDefaultCamliFileSystem(cl, diskCacheFetcher) } if *debug { fuse.Debug = func(msg interface{}) { log.Print(msg) } // TODO: set fs's logger } // This doesn't appear to work on OS X: sigc := make(chan os.Signal, 1) conn, err = fuse.Mount(mountPoint) if err != nil { if err.Error() == "cannot find load_fusefs" && runtime.GOOS == "darwin" { log.Fatal("FUSE not available; install from http://osxfuse.github.io/") } log.Fatalf("Mount: %v", err) } xtermDone := make(chan bool, 1) if *xterm { cmd := exec.Command("xterm") cmd.Dir = mountPoint if err := cmd.Start(); err != nil { log.Printf("Error starting xterm: %v", err) } else { go func() { cmd.Wait() xtermDone <- true }() defer cmd.Process.Kill() } } if *open { if runtime.GOOS == "darwin" { go exec.Command("open", mountPoint).Run() } } if *term { if runtime.GOOS == "darwin" { if osutil.DirExists("/Applications/iTerm.app/") { go exec.Command("open", "-a", "iTerm", mountPoint).Run() } else { log.Printf("TODO: iTerm not installed. Figure out how to open with Terminal.app instead.") } } } signal.Notify(sigc, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT) doneServe := make(chan error, 1) go func() { doneServe <- fusefs.Serve(conn, camfs) }() quitKey := make(chan bool, 1) go awaitQuitKey(quitKey) select { case err := <-doneServe: log.Printf("conn.Serve returned %v", err) case sig := <-sigc: log.Printf("Signal %s received, shutting down.", sig) case <-quitKey: log.Printf("Quit key pressed. Shutting down.") case <-xtermDone: log.Printf("xterm done") } time.AfterFunc(2*time.Second, func() { os.Exit(1) }) log.Printf("Unmounting...") err = fs.Unmount(mountPoint) log.Printf("Unmount = %v", err) log.Printf("cammount FUSE process ending.") }