Exemple #1
0
func (fs *MultiZipFs) GetAttr(name string, context *fuse.Context) (*fuse.Attr, fuse.Status) {
	a := &fuse.Attr{}
	a.Owner = *fuse.CurrentOwner()
	if name == "" {
		// Should not write in top dir.
		a.Mode = fuse.S_IFDIR | 0500
		return a, fuse.OK
	}

	if name == "config" {
		a.Mode = fuse.S_IFDIR | 0700
		return a, fuse.OK
	}

	dir, base := filepath.Split(name)
	if dir != "" && dir != CONFIG_PREFIX {
		return nil, fuse.ENOENT
	}
	submode := uint32(fuse.S_IFDIR | 0700)
	if dir == CONFIG_PREFIX {
		submode = fuse.S_IFLNK | 0600
	}

	fs.lock.RLock()
	defer fs.lock.RUnlock()

	a.Mode = submode
	_, hasDir := fs.zips[base]
	if hasDir {
		return a, fuse.OK
	}

	return nil, fuse.ENOENT
}
Exemple #2
0
// NewOptions generates FUSE options that correspond to libfuse's
// defaults.
func NewOptions() *Options {
	return &Options{
		NegativeTimeout: 0,
		AttrTimeout:     time.Second,
		EntryTimeout:    time.Second,
		Owner:           fuse.CurrentOwner(),
	}
}
Exemple #3
0
func main() {
	debug := flag.Bool("debug", false, "debug on")
	hardlinks := flag.Bool("hardlinks", false, "support hardlinks")
	delcache_ttl := flag.Float64("deletion_cache_ttl", 5.0, "Deletion cache TTL in seconds.")
	branchcache_ttl := flag.Float64("branchcache_ttl", 5.0, "Branch cache TTL in seconds.")
	deldirname := flag.String(
		"deletion_dirname", "GOUNIONFS_DELETIONS", "Directory name to use for deletions.")
	hide_readonly_link := flag.Bool("hide_readonly_link", true,
		"Hides READONLY link from the top mountpoints. "+
			"Enabled by default.")
	portableInodes := flag.Bool("portable-inodes", false,
		"Use sequential 32-bit inode numbers.")

	flag.Parse()

	if len(flag.Args()) < 2 {
		fmt.Println("Usage:\n  main MOUNTPOINT BASEDIR")
		os.Exit(2)
	}
	ufsOptions := unionfs.UnionFsOptions{
		DeletionCacheTTL: time.Duration(*delcache_ttl * float64(time.Second)),
		BranchCacheTTL:   time.Duration(*branchcache_ttl * float64(time.Second)),
		DeletionDirName:  *deldirname,
	}
	options := unionfs.AutoUnionFsOptions{
		UnionFsOptions: ufsOptions,
		Options: nodefs.Options{
			EntryTimeout:    time.Second,
			AttrTimeout:     time.Second,
			NegativeTimeout: time.Second,
			Owner:           fuse.CurrentOwner(),
		},
		UpdateOnMount: true,
		PathNodeFsOptions: pathfs.PathNodeFsOptions{
			ClientInodes: *hardlinks,
		},
		HideReadonly: *hide_readonly_link,
	}
	fsOpts := nodefs.Options{
		PortableInodes: *portableInodes,
	}
	gofs := unionfs.NewAutoUnionFs(flag.Arg(1), options)
	pathfs := pathfs.NewPathNodeFs(gofs, nil)
	state, conn, err := nodefs.MountRoot(flag.Arg(0), pathfs.Root(), &fsOpts)
	if err != nil {
		fmt.Printf("Mount fail: %v\n", err)
		os.Exit(1)
	}

	pathfs.SetDebug(*debug)
	conn.SetDebug(*debug)
	state.SetDebug(*debug)

	state.Serve()
	time.Sleep(1 * time.Second)
}
Exemple #4
0
func main() {
	version := flag.Bool("version", false, "print version number")
	debug := flag.Bool("debug", false, "debug on")
	hardlinks := flag.Bool("hardlinks", false, "support hardlinks")
	delcache_ttl := flag.Float64("deletion_cache_ttl", 5.0, "Deletion cache TTL in seconds.")
	branchcache_ttl := flag.Float64("branchcache_ttl", 5.0, "Branch cache TTL in seconds.")
	deldirname := flag.String(
		"deletion_dirname", "GOUNIONFS_DELETIONS", "Directory name to use for deletions.")
	flag.Parse()

	if *version {
		fmt.Println(fuse.Version())
		os.Exit(0)
	}

	if len(flag.Args()) < 2 {
		fmt.Println("Usage:\n  main MOUNTPOINT BASEDIR")
		os.Exit(2)
	}
	ufsOptions := unionfs.UnionFsOptions{
		DeletionCacheTTL: time.Duration(*delcache_ttl * float64(time.Second)),
		BranchCacheTTL:   time.Duration(*branchcache_ttl * float64(time.Second)),
		DeletionDirName:  *deldirname,
	}
	options := unionfs.AutoUnionFsOptions{
		UnionFsOptions: ufsOptions,
		FileSystemOptions: fuse.FileSystemOptions{
			EntryTimeout:    time.Second,
			AttrTimeout:     time.Second,
			NegativeTimeout: time.Second,
			Owner:           fuse.CurrentOwner(),
		},
		UpdateOnMount: true,
		PathNodeFsOptions: fuse.PathNodeFsOptions{
			ClientInodes: *hardlinks,
		},
	}

	fmt.Printf("AutoUnionFs - Go-FUSE Version %v.\n", fuse.Version())
	gofs := unionfs.NewAutoUnionFs(flag.Arg(1), options)
	pathfs := fuse.NewPathNodeFs(gofs, nil)
	state, conn, err := fuse.MountNodeFileSystem(flag.Arg(0), pathfs, nil)
	if err != nil {
		fmt.Printf("Mount fail: %v\n", err)
		os.Exit(1)
	}

	pathfs.Debug = *debug
	conn.Debug = *debug
	state.Debug = *debug

	gofs.SetMountState(state)

	state.Loop()
}
Exemple #5
0
func makeAttr(mode uint32) types.Struct {
	now := time.Now()
	ctime := types.Number(float64(now.Unix()) + float64(now.Nanosecond())/1000000000)
	mtime := ctime

	user := fuse.CurrentOwner()
	gid := types.Number(float64(user.Gid))
	uid := types.Number(float64(user.Uid))

	return types.NewStructWithType(attrType, types.ValueSlice{ctime, gid, types.Number(mode), mtime, uid, types.NewMap()})
}
Exemple #6
0
func TestDefaultNodeGetAttr(t *testing.T) {
	dir := testutil.TempDir()
	defer os.RemoveAll(dir)

	opts := &nodefs.Options{
		// Note: defaultNode.GetAttr() calling file.GetAttr() is only useful if
		// AttrTimeout is zero.
		// See https://github.com/JonathonReinhart/gitlab-fuse/issues/2
		Owner: fuse.CurrentOwner(),
	}

	root := nodefs.NewDefaultNode()
	s, _, err := nodefs.MountRoot(dir, root, opts)
	if err != nil {
		t.Fatalf("MountRoot: %v", err)
	}
	go s.Serve()
	if err := s.WaitMount(); err != nil {
		t.Fatal("WaitMount", err)
	}
	defer s.Unmount()

	// Attach another custom node type
	root.Inode().NewChild("foo", false, &myNode{
		Node:    nodefs.NewDefaultNode(),
		content: []byte("success"),
	})

	filepath := path.Join(dir, "foo")

	// NewDefaultNode() should provide for stat that indicates 0-byte regular file
	fi, err := os.Stat(filepath)
	if err != nil {
		t.Fatalf("Stat: %v", err)
	}
	if mode := (fi.Mode() & os.ModeType); mode != 0 {
		// Mode() & ModeType should be zero for regular files
		t.Fatalf("Unexpected mode: %#o", mode)
	}
	if size := fi.Size(); size != 0 {
		t.Fatalf("Unexpected size: %d", size)
	}

	// But when we open the file, we should get the content
	content, err := ioutil.ReadFile(filepath)
	if err != nil {
		t.Fatalf("ReadFile: %v", err)
	}
	if string(content) != "success" {
		t.Fatalf("Unexpected content: %v", content)
	}
}
Exemple #7
0
func main() {
	version := flag.Bool("version", false, "print version number")
	debug := flag.Bool("debug", false, "debug on")
	threaded := flag.Bool("threaded", true, "threading on")
	delcache_ttl := flag.Float64("deletion_cache_ttl", 5.0, "Deletion cache TTL in seconds.")
	branchcache_ttl := flag.Float64("branchcache_ttl", 5.0, "Branch cache TTL in seconds.")
	deldirname := flag.String(
		"deletion_dirname", "GOUNIONFS_DELETIONS", "Directory name to use for deletions.")
	flag.Parse()

	if *version {
		fmt.Println(fuse.Version())
		os.Exit(0)
	}

	if len(flag.Args()) < 2 {
		fmt.Println("Usage:\n  main MOUNTPOINT BASEDIR")
		os.Exit(2)
	}
	ufsOptions := unionfs.UnionFsOptions{
		DeletionCacheTTLSecs: *delcache_ttl,
		BranchCacheTTLSecs:   *branchcache_ttl,
		DeletionDirName:      *deldirname,
	}
	options := unionfs.AutoUnionFsOptions{
		UnionFsOptions: ufsOptions,
		FileSystemOptions: fuse.FileSystemOptions{
			EntryTimeout:    1.0,
			AttrTimeout:     1.0,
			NegativeTimeout: 1.0,
			Owner:           fuse.CurrentOwner(),
		},
		UpdateOnMount: true,
	}

	gofs := unionfs.NewAutoUnionFs(flag.Arg(1), options)
	pathfs := fuse.NewPathNodeFs(gofs)
	state, conn, err := fuse.MountNodeFileSystem(flag.Arg(0), pathfs, nil)
	if err != nil {
		fmt.Printf("Mount fail: %v\n", err)
		os.Exit(1)
	}

	pathfs.Debug = *debug
	conn.Debug = *debug
	state.Debug = *debug
	state.Loop(*threaded)
}
Exemple #8
0
func (fs *autoUnionFs) GetAttr(path string, context *fuse.Context) (*fuse.Attr, fuse.Status) {
	a := &fuse.Attr{
		Owner: *fuse.CurrentOwner(),
	}
	if path == "" || path == _CONFIG || path == _STATUS {
		a.Mode = fuse.S_IFDIR | 0755
		return a, fuse.OK
	}

	if path == filepath.Join(_STATUS, _VERSION) {
		a.Mode = fuse.S_IFREG | 0644
		a.Size = uint64(len(fs.options.Version))
		return a, fuse.OK
	}

	if path == filepath.Join(_STATUS, _DEBUG) {
		a.Mode = fuse.S_IFREG | 0644
		a.Size = uint64(len(fs.DebugData()))
		return a, fuse.OK
	}

	if path == filepath.Join(_STATUS, _ROOT) {
		a.Mode = syscall.S_IFLNK | 0644
		return a, fuse.OK
	}

	if path == filepath.Join(_CONFIG, _SCAN_CONFIG) {
		a.Mode = fuse.S_IFREG | 0644
		return a, fuse.OK
	}
	comps := strings.Split(path, string(filepath.Separator))

	if len(comps) > 1 && comps[0] == _CONFIG {
		fs := fs.getUnionFs(comps[1])

		if fs == nil {
			return nil, fuse.ENOENT
		}

		a.Mode = syscall.S_IFLNK | 0644
		return a, fuse.OK
	}

	return nil, fuse.ENOENT
}