kubelwagen/fs/local.go

101 lines
2 KiB
Go

package fs
import (
"io"
"os"
"path/filepath"
"github.com/barakmich/kubelwagen"
"github.com/hanwen/go-fuse/fuse"
"github.com/sirupsen/logrus"
)
type LocalFs struct {
base string
open map[int]*os.File
}
func NewLocalFs(path string) *LocalFs {
return &LocalFs{
base: path,
open: make(map[int]*os.File),
}
}
func (fs *LocalFs) Handle(r *kubelwagen.Request) *kubelwagen.Response {
switch r.Method {
case kubelwagen.MethodOpenDir:
return fs.openDir(r)
case kubelwagen.MethodGetAttr:
return fs.getAttr(r)
}
return &kubelwagen.Response{
ID: r.ID,
Code: fuse.ENOSYS,
}
}
func (fs *LocalFs) getPath(r *kubelwagen.Request) string {
return filepath.Join(fs.base, r.Path)
}
func (fs *LocalFs) openDir(r *kubelwagen.Request) *kubelwagen.Response {
out := &kubelwagen.Response{
ID: r.ID,
Code: fuse.OK,
}
// returns dirents and status
f, err := os.Open(fs.getPath(r))
if err != nil {
logrus.Errorf("LocalFS openDir (%s): %s\n", r.Path, err)
return kubelwagen.ErrorResp(r, err)
}
want := 100
output := make([]fuse.DirEntry, 0, want)
for {
infos, err := f.Readdir(want)
for i := range infos {
// workaround for https://code.google.com/p/go/issues/detail?id=5960
if infos[i] == nil {
continue
}
n := infos[i].Name()
d := fuse.DirEntry{
Name: n,
}
if s := fuse.ToStatT(infos[i]); s != nil {
d.Mode = uint32(s.Mode)
d.Ino = s.Ino
} else {
logrus.Printf("ReadDir entry %q for %q has no stat info", n, r.Path)
}
output = append(output, d)
}
if len(infos) < want || err == io.EOF {
break
}
if err != nil {
logrus.Errorln("Readdir() returned err:", err)
break
}
}
f.Close()
out.Dirents = output
return out
}
func (fs *LocalFs) getAttr(r *kubelwagen.Request) *kubelwagen.Response {
out := &kubelwagen.Response{
ID: r.ID,
Code: fuse.OK,
}
fi, err := os.Stat(fs.getPath(r))
if err != nil {
logrus.Errorf("LocalFS getAttr (%s): %s\n", r.Path, err)
return kubelwagen.ErrorResp(r, err)
}
out.Stat = fuse.ToAttr(fi)
return out
}