Add diskfs proxying

This commit is contained in:
Ingo Oppermann 2022-08-05 12:30:25 +02:00
parent c31fd657be
commit 5af85c6a8b
No known key found for this signature in database
GPG Key ID: 2AB32426E9DD229E
5 changed files with 52 additions and 13 deletions

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"fmt" "fmt"
"path/filepath" "path/filepath"
"regexp"
"sync" "sync"
"time" "time"
@ -16,7 +17,7 @@ type Cluster interface {
ListNodes() []NodeReader ListNodes() []NodeReader
GetNode(id string) (NodeReader, error) GetNode(id string) (NodeReader, error)
Stop() Stop()
GetFile(path string) (string, error) GetURL(path string) (string, error)
} }
type ClusterConfig struct { type ClusterConfig struct {
@ -35,6 +36,8 @@ type cluster struct {
cancel context.CancelFunc cancel context.CancelFunc
once sync.Once once sync.Once
prefix *regexp.Regexp
logger log.Logger logger log.Logger
} }
@ -45,6 +48,7 @@ func New(config ClusterConfig) (Cluster, error) {
idupdate: map[string]time.Time{}, idupdate: map[string]time.Time{},
fileid: map[string]string{}, fileid: map[string]string{},
updates: make(chan NodeState, 64), updates: make(chan NodeState, 64),
prefix: regexp.MustCompile(`^[a-z]+:`),
logger: config.Logger, logger: config.Logger,
} }
@ -170,7 +174,7 @@ func (c *cluster) GetNode(id string) (NodeReader, error) {
return node, nil return node, nil
} }
func (c *cluster) GetFile(path string) (string, error) { func (c *cluster) GetURL(path string) (string, error) {
c.lock.RLock() c.lock.RLock()
defer c.lock.RUnlock() defer c.lock.RUnlock()
@ -199,7 +203,20 @@ func (c *cluster) GetFile(path string) (string, error) {
return "", fmt.Errorf("file not found") return "", fmt.Errorf("file not found")
} }
url := node.Address() + "/" + filepath.Join("memfs", path) // Remove prefix from path
prefix := c.prefix.FindString(path)
path = c.prefix.ReplaceAllString(path, "")
url := ""
if prefix == "memfs:" {
url = node.Address() + "/" + filepath.Join("memfs", path)
} else if prefix == "diskfs:" {
url = node.Address() + path
} else {
c.logger.Debug().WithField("path", path).WithField("prefix", prefix).Log("unknown prefix")
return "", fmt.Errorf("file not found")
}
c.logger.Debug().WithField("url", url).Log("file cluster url") c.logger.Debug().WithField("url", url).Log("file cluster url")

View File

@ -131,11 +131,12 @@ func (n *node) stop() {
} }
func (n *node) files() { func (n *node) files() {
files, err := n.peer.MemFSList("name", "asc") memfsfiles, errMemfs := n.peer.MemFSList("name", "asc")
diskfsfiles, errDiskfs := n.peer.DiskFSList("name", "asc")
n.lastUpdate = time.Now() n.lastUpdate = time.Now()
if err != nil { if errMemfs != nil || errDiskfs != nil {
n.fileList = nil n.fileList = nil
n.state = stateDisconnected n.state = stateDisconnected
return return
@ -143,10 +144,18 @@ func (n *node) files() {
n.state = stateConnected n.state = stateConnected
n.fileList = make([]string, len(files)) n.fileList = make([]string, len(memfsfiles)+len(diskfsfiles))
for i, file := range files { nfiles := 0
n.fileList[i] = file.Name
for _, file := range memfsfiles {
n.fileList[nfiles] = "memfs:" + file.Name
nfiles++
}
for _, file := range diskfsfiles {
n.fileList[nfiles] = "diskfs:" + file.Name
nfiles++
} }
return return

View File

@ -16,12 +16,14 @@ type Filesystem interface {
type filesystem struct { type filesystem struct {
fs.Filesystem fs.Filesystem
what string
cluster cluster.Cluster cluster cluster.Cluster
} }
func NewClusterFS(what string, fs fs.Filesystem, cluster cluster.Cluster) Filesystem { func NewClusterFS(what string, fs fs.Filesystem, cluster cluster.Cluster) Filesystem {
f := &filesystem{ f := &filesystem{
Filesystem: fs, Filesystem: fs,
what: what,
cluster: cluster, cluster: cluster,
} }
@ -35,7 +37,7 @@ func (fs *filesystem) Open(path string) fs.File {
} }
// Check if the file is available in the cluster // Check if the file is available in the cluster
url, err := fs.cluster.GetFile(path) url, err := fs.cluster.GetURL(fs.what + ":" + path)
if err != nil { if err != nil {
return nil return nil
} }

View File

@ -49,7 +49,10 @@ func (h *DiskFSHandler) GetFile(c echo.Context) error {
return api.Err(http.StatusNotFound, "File not found", path) return api.Err(http.StatusNotFound, "File not found", path)
} }
stat, _ := file.Stat() stat, err := file.Stat()
if err != nil {
return api.Err(http.StatusNotFound, "File not found", path)
}
if stat.IsDir() { if stat.IsDir() {
path = filepath.Join(path, "index.html") path = filepath.Join(path, "index.html")
@ -61,7 +64,10 @@ func (h *DiskFSHandler) GetFile(c echo.Context) error {
return api.Err(http.StatusNotFound, "File not found", path) return api.Err(http.StatusNotFound, "File not found", path)
} }
stat, _ = file.Stat() stat, err = file.Stat()
if err != nil {
return api.Err(http.StatusNotFound, "File not found", path)
}
} }
defer file.Close() defer file.Close()

View File

@ -184,8 +184,13 @@ func NewServer(config Config) (Server, error) {
config.Cache, config.Cache,
) )
filesystem := config.DiskFS
if config.Cluster != nil {
filesystem = clusterfs.NewClusterFS("diskfs", filesystem, config.Cluster)
}
s.handler.diskfs = handler.NewDiskFS( s.handler.diskfs = handler.NewDiskFS(
config.DiskFS, filesystem,
config.Cache, config.Cache,
) )
@ -230,7 +235,7 @@ func NewServer(config Config) (Server, error) {
filesystem := config.MemFS.Filesystem filesystem := config.MemFS.Filesystem
if config.Cluster != nil { if config.Cluster != nil {
filesystem = clusterfs.NewClusterFS("TODO", filesystem, config.Cluster) filesystem = clusterfs.NewClusterFS("memfs", filesystem, config.Cluster)
} }
s.handler.memfs = handler.NewMemFS( s.handler.memfs = handler.NewMemFS(