fuse: Add hosts dir

This commit is contained in:
Alexander Neumann 2017-06-18 20:25:31 +02:00
parent f4e85a53e7
commit 64f434eca4
3 changed files with 113 additions and 14 deletions

View File

@ -0,0 +1,99 @@
// +build !openbsd
// +build !windows
package fuse
import (
"os"
"restic"
"restic/debug"
"golang.org/x/net/context"
"bazil.org/fuse"
"bazil.org/fuse/fs"
)
// HostsDir is a fuse directory which contains hostnames.
type HostsDir struct {
inode uint64
root *Root
snapshots restic.Snapshots
hosts map[string]*SnapshotsDir
}
// NewHostsDir returns a new directory containing hostnames, which in
// turn contains snapshots of a single host each.
func NewHostsDir(root *Root, inode uint64, snapshots restic.Snapshots) *HostsDir {
hosts := make(map[string]restic.Snapshots)
for _, sn := range snapshots {
hosts[sn.Hostname] = append(hosts[sn.Hostname], sn)
}
debug.Log("create hosts dir with %d snapshots, inode %d", len(hosts), inode)
d := &HostsDir{
root: root,
inode: inode,
snapshots: snapshots,
hosts: make(map[string]*SnapshotsDir),
}
for hostname, snapshots := range hosts {
debug.Log(" host %v has %v snapshots", hostname, len(snapshots))
d.hosts[hostname] = NewSnapshotsDir(root, fs.GenerateDynamicInode(inode, hostname), snapshots)
}
return d
}
// Attr returns the attributes for the root node.
func (d *HostsDir) Attr(ctx context.Context, attr *fuse.Attr) error {
attr.Inode = d.inode
attr.Mode = os.ModeDir | 0555
if !d.root.cfg.OwnerIsRoot {
attr.Uid = uint32(os.Getuid())
attr.Gid = uint32(os.Getgid())
}
debug.Log("attr: %v", attr)
return nil
}
// ReadDirAll returns all entries of the root node.
func (d *HostsDir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
debug.Log("ReadDirAll()")
items := []fuse.Dirent{
{
Inode: d.inode,
Name: ".",
Type: fuse.DT_Dir,
},
{
Inode: d.root.inode,
Name: "..",
Type: fuse.DT_Dir,
},
}
for name := range d.hosts {
items = append(items, fuse.Dirent{
Inode: fs.GenerateDynamicInode(d.inode, name),
Name: name,
Type: fuse.DT_Dir,
})
}
return items, nil
}
// Lookup returns a specific entry from the root node.
func (d *HostsDir) Lookup(ctx context.Context, name string) (fs.Node, error) {
debug.Log("Lookup(%s)", name)
if dir, ok := d.hosts[name]; ok {
return dir, nil
}
return nil, fuse.ENOENT
}

View File

@ -28,8 +28,10 @@ type Root struct {
cfg Config
inode uint64
snapshots restic.Snapshots
dirSnapshots *SnapshotsDir
blobSizeCache *BlobSizeCache
dirSnapshots *SnapshotsDir
dirHosts *HostsDir
}
// ensure that *Root implements these interfaces
@ -50,7 +52,8 @@ func NewRoot(ctx context.Context, repo restic.Repository, cfg Config) (*Root, er
snapshots: snapshots,
}
root.dirSnapshots = NewDirSnapshots(root, fs.GenerateDynamicInode(root.inode, "snapshots"), snapshots)
root.dirSnapshots = NewSnapshotsDir(root, fs.GenerateDynamicInode(root.inode, "snapshots"), snapshots)
root.dirHosts = NewHostsDir(root, fs.GenerateDynamicInode(root.inode, "hosts"), snapshots)
root.blobSizeCache = NewBlobSizeCache(ctx, repo.Index())
return root, nil
@ -94,16 +97,11 @@ func (r *Root) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
Name: "snapshots",
Type: fuse.DT_Dir,
},
// {
// Inode: fs.GenerateDynamicInode(0, "tags"),
// Name: "tags",
// Type: fuse.DT_Dir,
// },
// {
// Inode: fs.GenerateDynamicInode(0, "hosts"),
// Name: "hosts",
// Type: fuse.DT_Dir,
// },
{
Inode: fs.GenerateDynamicInode(0, "hosts"),
Name: "hosts",
Type: fuse.DT_Dir,
},
}
return items, nil
@ -115,6 +113,8 @@ func (r *Root) Lookup(ctx context.Context, name string) (fs.Node, error) {
switch name {
case "snapshots":
return r.dirSnapshots, nil
case "hosts":
return r.dirHosts, nil
}
return nil, fuse.ENOENT

View File

@ -28,8 +28,8 @@ type SnapshotsDir struct {
var _ = fs.HandleReadDirAller(&SnapshotsDir{})
var _ = fs.NodeStringLookuper(&SnapshotsDir{})
// NewDirSnapshots returns a new directory containing snapshots.
func NewDirSnapshots(root *Root, inode uint64, snapshots restic.Snapshots) *SnapshotsDir {
// NewSnapshotsDir returns a new directory containing snapshots.
func NewSnapshotsDir(root *Root, inode uint64, snapshots restic.Snapshots) *SnapshotsDir {
debug.Log("create snapshots dir with %d snapshots, inode %d", len(snapshots), inode)
d := &SnapshotsDir{
root: root,