Files
2022-12-08 12:16:04 +11:00

197 lines
4.1 KiB
Go

package plg_backend_nfs
import (
"context"
. "github.com/mickael-kerjean/filestash/server/common"
"github.com/vmware/go-nfs-client/nfs"
"github.com/vmware/go-nfs-client/nfs/rpc"
"github.com/vmware/go-nfs-client/nfs/util"
"io"
"os"
"os/user"
"strconv"
"strings"
)
type NfsShare struct {
mount *nfs.Mount
v *nfs.Target
ctx context.Context
}
func init() {
Backend.Register("nfs", NfsShare{})
util.DefaultLogger.SetDebug(false)
}
func (this NfsShare) Init(params map[string]string, app *App) (IBackend, error) {
if params["hostname"] == "" {
params["hostname"] = "localhost"
}
var (
uid uint32 = 1000
gid uint32 = 1000
)
if user, err := user.Current(); err == nil {
params["target"] = user.HomeDir
if _uid, err := strconv.Atoi(user.Uid); err == nil {
uid = uint32(_uid)
}
if _gid, err := strconv.Atoi(user.Gid); err == nil {
gid = uint32(_gid)
}
}
if mn, err := os.Hostname(); err == nil && params["machine_name"] == "" {
params["machine_name"] = mn
}
if params["uid"] != "" {
if _uid, err := strconv.Atoi(params["uid"]); err == nil {
uid = uint32(_uid)
}
}
if params["gid"] != "" {
if _gid, err := strconv.Atoi(params["gid"]); err == nil {
gid = uint32(_gid)
}
}
auth := rpc.NewAuthUnix(params["machine_name"], uid, gid)
mount, err := nfs.DialMount(params["hostname"])
if err != nil {
return nil, err
}
v, err := mount.Mount(params["target"], auth.Auth())
if err != nil {
return nil, err
}
return NfsShare{mount, v, app.Context}, nil
}
func (this NfsShare) LoginForm() Form {
return Form{
Elmnts: []FormElement{
FormElement{
Name: "type",
Type: "hidden",
Value: "nfs",
},
FormElement{
Name: "hostname",
Type: "text",
Placeholder: "Hostname",
},
FormElement{
Name: "target",
Type: "text",
Placeholder: "Mount Path",
},
FormElement{
Name: "advanced",
Type: "enable",
Placeholder: "Advanced",
Target: []string{"nfs_uid", "nfs_gid", "nfs_machinename"},
},
FormElement{
Id: "nfs_uid",
Name: "uid",
Type: "number",
Placeholder: "uid",
},
FormElement{
Id: "nfs_gid",
Name: "gid",
Type: "number",
Placeholder: "gid",
},
FormElement{
Id: "nfs_machinename",
Name: "machine_name",
Type: "text",
Placeholder: "machine name",
},
},
}
}
func (this NfsShare) Ls(path string) ([]os.FileInfo, error) {
defer this.Close()
files := make([]os.FileInfo, 0)
dirs, err := this.v.ReadDirPlus(path)
if err != nil {
return files, err
}
for _, dir := range dirs {
if dir.FileName == "." || dir.FileName == ".." {
continue
} else if dir.Attr.Attr.Type != 1 && dir.Attr.Attr.Type != 2 {
// don't show anything else than file and folder
continue
}
files = append(files, File{
FName: dir.FileName,
FType: func() string {
if dir.Attr.Attr.Type == 1 {
return "file"
}
return "directory"
}(),
FSize: int64(dir.Attr.Attr.Filesize),
FTime: int64(dir.Attr.Attr.Ctime.Seconds),
})
}
return files, nil
}
func (this NfsShare) Cat(path string) (io.ReadCloser, error) {
go func() {
<-this.ctx.Done()
this.Close()
}()
rc, err := this.v.OpenFile(path, 0777)
if err != nil {
return nil, err
}
return rc, nil
}
func (this NfsShare) Mkdir(path string) error {
defer this.Close()
_, err := this.v.Mkdir(path, 0775)
return err
}
func (this NfsShare) Rm(path string) error {
defer this.Close()
if strings.HasSuffix(path, "/") {
return this.v.RemoveAll(path)
}
return this.v.Remove(path)
}
func (this NfsShare) Mv(from string, to string) error {
defer this.Close()
return ErrNotImplemented
}
func (this NfsShare) Touch(path string) error {
defer this.Close()
return this.Save(path, strings.NewReader(""))
}
func (this NfsShare) Save(path string, file io.Reader) error {
defer this.Close()
w, err := this.v.OpenFile(path, 0644)
if err != nil {
return err
}
_, err = io.Copy(w, file)
w.Close()
return err
}
func (this NfsShare) Close() {
this.v.Close()
this.mount.Close()
}