mirror of
https://github.com/octoleo/restic.git
synced 2024-12-01 17:23:57 +00:00
fuse: Add hosts dir
This commit is contained in:
parent
f4e85a53e7
commit
64f434eca4
99
src/restic/fuse/hosts_dir.go
Normal file
99
src/restic/fuse/hosts_dir.go
Normal 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
|
||||||
|
}
|
@ -28,8 +28,10 @@ type Root struct {
|
|||||||
cfg Config
|
cfg Config
|
||||||
inode uint64
|
inode uint64
|
||||||
snapshots restic.Snapshots
|
snapshots restic.Snapshots
|
||||||
dirSnapshots *SnapshotsDir
|
|
||||||
blobSizeCache *BlobSizeCache
|
blobSizeCache *BlobSizeCache
|
||||||
|
|
||||||
|
dirSnapshots *SnapshotsDir
|
||||||
|
dirHosts *HostsDir
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensure that *Root implements these interfaces
|
// ensure that *Root implements these interfaces
|
||||||
@ -50,7 +52,8 @@ func NewRoot(ctx context.Context, repo restic.Repository, cfg Config) (*Root, er
|
|||||||
snapshots: snapshots,
|
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())
|
root.blobSizeCache = NewBlobSizeCache(ctx, repo.Index())
|
||||||
|
|
||||||
return root, nil
|
return root, nil
|
||||||
@ -94,16 +97,11 @@ func (r *Root) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
|
|||||||
Name: "snapshots",
|
Name: "snapshots",
|
||||||
Type: fuse.DT_Dir,
|
Type: fuse.DT_Dir,
|
||||||
},
|
},
|
||||||
// {
|
{
|
||||||
// Inode: fs.GenerateDynamicInode(0, "tags"),
|
Inode: fs.GenerateDynamicInode(0, "hosts"),
|
||||||
// Name: "tags",
|
Name: "hosts",
|
||||||
// Type: fuse.DT_Dir,
|
Type: fuse.DT_Dir,
|
||||||
// },
|
},
|
||||||
// {
|
|
||||||
// Inode: fs.GenerateDynamicInode(0, "hosts"),
|
|
||||||
// Name: "hosts",
|
|
||||||
// Type: fuse.DT_Dir,
|
|
||||||
// },
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return items, nil
|
return items, nil
|
||||||
@ -115,6 +113,8 @@ func (r *Root) Lookup(ctx context.Context, name string) (fs.Node, error) {
|
|||||||
switch name {
|
switch name {
|
||||||
case "snapshots":
|
case "snapshots":
|
||||||
return r.dirSnapshots, nil
|
return r.dirSnapshots, nil
|
||||||
|
case "hosts":
|
||||||
|
return r.dirHosts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, fuse.ENOENT
|
return nil, fuse.ENOENT
|
||||||
|
@ -28,8 +28,8 @@ type SnapshotsDir struct {
|
|||||||
var _ = fs.HandleReadDirAller(&SnapshotsDir{})
|
var _ = fs.HandleReadDirAller(&SnapshotsDir{})
|
||||||
var _ = fs.NodeStringLookuper(&SnapshotsDir{})
|
var _ = fs.NodeStringLookuper(&SnapshotsDir{})
|
||||||
|
|
||||||
// NewDirSnapshots returns a new directory containing snapshots.
|
// NewSnapshotsDir returns a new directory containing snapshots.
|
||||||
func NewDirSnapshots(root *Root, inode uint64, snapshots restic.Snapshots) *SnapshotsDir {
|
func NewSnapshotsDir(root *Root, inode uint64, snapshots restic.Snapshots) *SnapshotsDir {
|
||||||
debug.Log("create snapshots dir with %d snapshots, inode %d", len(snapshots), inode)
|
debug.Log("create snapshots dir with %d snapshots, inode %d", len(snapshots), inode)
|
||||||
d := &SnapshotsDir{
|
d := &SnapshotsDir{
|
||||||
root: root,
|
root: root,
|
||||||
|
Loading…
Reference in New Issue
Block a user