2020-09-27 19:23:47 +00:00
|
|
|
package fuse
|
2020-04-27 16:46:23 +00:00
|
|
|
|
|
|
|
import (
|
2020-05-18 17:42:23 +00:00
|
|
|
"fmt"
|
2020-11-08 17:19:25 +00:00
|
|
|
"os"
|
|
|
|
"path"
|
|
|
|
"runtime"
|
2020-04-27 16:46:23 +00:00
|
|
|
|
|
|
|
"github.com/ajnavarro/distribyted/config"
|
2020-09-27 19:23:47 +00:00
|
|
|
"github.com/ajnavarro/distribyted/fs"
|
2020-05-02 12:06:18 +00:00
|
|
|
"github.com/ajnavarro/distribyted/stats"
|
2020-04-27 16:46:23 +00:00
|
|
|
"github.com/anacrolix/torrent"
|
2020-09-27 19:23:47 +00:00
|
|
|
"github.com/billziss-gh/cgofuse/fuse"
|
2020-07-14 11:55:08 +00:00
|
|
|
log "github.com/sirupsen/logrus"
|
2020-04-27 16:46:23 +00:00
|
|
|
)
|
|
|
|
|
2020-05-18 17:42:23 +00:00
|
|
|
type Handler struct {
|
2020-09-27 19:23:47 +00:00
|
|
|
c *torrent.Client
|
|
|
|
s *stats.Torrent
|
2020-04-27 16:46:23 +00:00
|
|
|
|
2020-09-27 19:23:47 +00:00
|
|
|
hosts map[string]*fuse.FileSystemHost
|
2020-04-27 16:46:23 +00:00
|
|
|
}
|
|
|
|
|
2020-06-03 09:15:01 +00:00
|
|
|
func NewHandler(c *torrent.Client, s *stats.Torrent) *Handler {
|
2020-05-18 17:42:23 +00:00
|
|
|
return &Handler{
|
2020-09-27 19:23:47 +00:00
|
|
|
c: c,
|
|
|
|
s: s,
|
|
|
|
hosts: make(map[string]*fuse.FileSystemHost),
|
2020-04-27 16:46:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-09 10:33:19 +00:00
|
|
|
func (s *Handler) Mount(mpc *config.MountPoint, ef config.EventFunc) error {
|
2020-09-27 19:23:47 +00:00
|
|
|
var torrents []fs.Filesystem
|
2020-05-18 17:42:23 +00:00
|
|
|
for _, mpcTorrent := range mpc.Torrents {
|
|
|
|
var t *torrent.Torrent
|
|
|
|
var err error
|
|
|
|
|
|
|
|
switch {
|
|
|
|
case mpcTorrent.MagnetURI != "":
|
|
|
|
t, err = s.c.AddMagnet(mpcTorrent.MagnetURI)
|
|
|
|
break
|
|
|
|
case mpcTorrent.TorrentPath != "":
|
|
|
|
t, err = s.c.AddTorrentFromFile(mpcTorrent.TorrentPath)
|
|
|
|
break
|
|
|
|
default:
|
|
|
|
err = fmt.Errorf("no magnet URI or torrent path provided")
|
|
|
|
}
|
2020-04-27 16:46:23 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-05-18 17:42:23 +00:00
|
|
|
|
2020-06-07 10:52:00 +00:00
|
|
|
// only get info if name is not available
|
|
|
|
if t.Name() == "" {
|
2020-11-09 10:33:19 +00:00
|
|
|
ef(fmt.Sprintf("getting torrent info...: %v", t.InfoHash()))
|
2020-07-14 11:55:08 +00:00
|
|
|
log.WithField("hash", t.InfoHash()).Info("getting torrent info")
|
2020-06-07 10:52:00 +00:00
|
|
|
<-t.GotInfo()
|
|
|
|
}
|
2020-05-02 12:06:18 +00:00
|
|
|
|
2020-05-18 17:42:23 +00:00
|
|
|
s.s.Add(mpc.Path, t)
|
2020-09-27 19:23:47 +00:00
|
|
|
torrents = append(torrents, fs.NewTorrent(t))
|
2020-05-02 12:06:18 +00:00
|
|
|
|
2020-11-09 10:33:19 +00:00
|
|
|
ef(fmt.Sprintf("torrent %v added to mountpoint", t.Name()))
|
2020-09-27 19:23:47 +00:00
|
|
|
log.WithField("name", t.Name()).WithField("path", mpc.Path).Info("torrent added to mountpoint")
|
2020-04-27 16:46:23 +00:00
|
|
|
}
|
|
|
|
|
2020-11-08 17:19:25 +00:00
|
|
|
folder := mpc.Path
|
|
|
|
// On windows, the folder must don't exist
|
|
|
|
if runtime.GOOS == "windows" {
|
|
|
|
folder = path.Dir(folder)
|
|
|
|
}
|
|
|
|
if err := os.MkdirAll(folder, 0744); err != nil && !os.IsExist(err) {
|
|
|
|
return err
|
|
|
|
}
|
2020-04-27 16:46:23 +00:00
|
|
|
|
2020-09-27 19:23:47 +00:00
|
|
|
host := fuse.NewFileSystemHost(&FS{FSS: torrents})
|
2020-04-27 16:46:23 +00:00
|
|
|
|
2020-11-08 17:19:25 +00:00
|
|
|
// TODO improve error handling here
|
2020-09-27 19:23:47 +00:00
|
|
|
go func() {
|
|
|
|
ok := host.Mount(mpc.Path, nil)
|
|
|
|
if !ok {
|
|
|
|
log.WithField("path", mpc.Path).Error("error trying to mount filesystem")
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
s.hosts[mpc.Path] = host
|
2020-04-27 16:46:23 +00:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-11-08 17:19:25 +00:00
|
|
|
func (s *Handler) UnmountAll() {
|
2020-09-27 19:23:47 +00:00
|
|
|
for path, server := range s.hosts {
|
2020-07-14 11:55:08 +00:00
|
|
|
log.WithField("path", path).Info("unmounting")
|
2020-09-27 19:23:47 +00:00
|
|
|
ok := server.Unmount()
|
|
|
|
if !ok {
|
2020-07-14 11:55:08 +00:00
|
|
|
//TODO try to force unmount if possible
|
2020-09-27 19:23:47 +00:00
|
|
|
log.WithField("path", path).Error("unmount failed")
|
2020-04-27 16:46:23 +00:00
|
|
|
}
|
|
|
|
}
|
2020-11-08 17:19:25 +00:00
|
|
|
s.hosts = make(map[string]*fuse.FileSystemHost)
|
|
|
|
s.s.RemoveAll()
|
2020-04-27 16:46:23 +00:00
|
|
|
}
|