mirror of
https://github.com/rclone/rclone.git
synced 2024-11-22 09:32:29 +08:00
mount: change interface of mount commands to take VFS
This is in preparation of being able to pass options to the rc command "mount/mount"
This commit is contained in:
parent
744828a4de
commit
2871268505
5
backend/cache/cache_mount_unix_test.go
vendored
5
backend/cache/cache_mount_unix_test.go
vendored
|
@ -13,6 +13,8 @@ import (
|
|||
"github.com/rclone/rclone/cmd/mount"
|
||||
"github.com/rclone/rclone/cmd/mountlib"
|
||||
"github.com/rclone/rclone/fs"
|
||||
"github.com/rclone/rclone/vfs"
|
||||
"github.com/rclone/rclone/vfs/vfsflags"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
@ -30,7 +32,8 @@ func (r *run) mountFs(t *testing.T, f fs.Fs) {
|
|||
require.NoError(t, err)
|
||||
c, err := fuse.Mount(r.mntDir, options...)
|
||||
require.NoError(t, err)
|
||||
filesys := mount.NewFS(f)
|
||||
VFS := vfs.New(f, &vfsflags.Opt)
|
||||
filesys := mount.NewFS(VFS)
|
||||
server := fusefs.New(c, nil)
|
||||
|
||||
// Serve the mount point in the background returning error to errChan
|
||||
|
|
5
backend/cache/cache_mount_windows_test.go
vendored
5
backend/cache/cache_mount_windows_test.go
vendored
|
@ -14,6 +14,8 @@ import (
|
|||
"github.com/rclone/rclone/cmd/cmount"
|
||||
"github.com/rclone/rclone/cmd/mountlib"
|
||||
"github.com/rclone/rclone/fs"
|
||||
"github.com/rclone/rclone/vfs"
|
||||
"github.com/rclone/rclone/vfs/vfsflags"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
@ -51,7 +53,8 @@ func (r *run) mountFs(t *testing.T, f fs.Fs) {
|
|||
"--FileSystemName=rclone",
|
||||
}
|
||||
|
||||
fsys := cmount.NewFS(f)
|
||||
VFS := vfs.New(f, &vfsflags.Opt)
|
||||
fsys := cmount.NewFS(VFS)
|
||||
host := fuse.NewFileSystemHost(fsys)
|
||||
|
||||
// Serve the mount point in the background returning error to errChan
|
||||
|
|
|
@ -17,7 +17,6 @@ import (
|
|||
"github.com/rclone/rclone/fs"
|
||||
"github.com/rclone/rclone/fs/log"
|
||||
"github.com/rclone/rclone/vfs"
|
||||
"github.com/rclone/rclone/vfs/vfsflags"
|
||||
)
|
||||
|
||||
const fhUnset = ^uint64(0)
|
||||
|
@ -32,10 +31,10 @@ type FS struct {
|
|||
}
|
||||
|
||||
// NewFS makes a new FS
|
||||
func NewFS(f fs.Fs) *FS {
|
||||
func NewFS(VFS *vfs.VFS) *FS {
|
||||
fsys := &FS{
|
||||
VFS: vfs.New(f, &vfsflags.Opt),
|
||||
f: f,
|
||||
VFS: VFS,
|
||||
f: VFS.Fs(),
|
||||
ready: make(chan (struct{})),
|
||||
}
|
||||
return fsys
|
||||
|
|
|
@ -23,7 +23,6 @@ import (
|
|||
"github.com/rclone/rclone/fs"
|
||||
"github.com/rclone/rclone/lib/atexit"
|
||||
"github.com/rclone/rclone/vfs"
|
||||
"github.com/rclone/rclone/vfs/vfsflags"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -45,7 +44,7 @@ func init() {
|
|||
}
|
||||
|
||||
// mountOptions configures the options from the command line flags
|
||||
func mountOptions(device string, mountpoint string) (options []string) {
|
||||
func mountOptions(VFS *vfs.VFS, device string, mountpoint string) (options []string) {
|
||||
// Options
|
||||
options = []string{
|
||||
"-o", "fsname=" + device,
|
||||
|
@ -97,7 +96,7 @@ func mountOptions(device string, mountpoint string) (options []string) {
|
|||
if mountlib.DefaultPermissions {
|
||||
options = append(options, "-o", "default_permissions")
|
||||
}
|
||||
if vfsflags.Opt.ReadOnly {
|
||||
if VFS.Opt.ReadOnly {
|
||||
options = append(options, "-o", "ro")
|
||||
}
|
||||
if mountlib.WritebackCache {
|
||||
|
@ -135,22 +134,23 @@ func waitFor(fn func() bool) (ok bool) {
|
|||
//
|
||||
// returns an error, and an error channel for the serve process to
|
||||
// report an error when fusermount is called.
|
||||
func mount(f fs.Fs, mountpoint string) (*vfs.VFS, <-chan error, func() error, error) {
|
||||
func mount(VFS *vfs.VFS, mountpoint string) (<-chan error, func() error, error) {
|
||||
f := VFS.Fs()
|
||||
fs.Debugf(f, "Mounting on %q", mountpoint)
|
||||
|
||||
// Check the mountpoint - in Windows the mountpoint mustn't exist before the mount
|
||||
if runtime.GOOS != "windows" {
|
||||
fi, err := os.Stat(mountpoint)
|
||||
if err != nil {
|
||||
return nil, nil, nil, errors.Wrap(err, "mountpoint")
|
||||
return nil, nil, errors.Wrap(err, "mountpoint")
|
||||
}
|
||||
if !fi.IsDir() {
|
||||
return nil, nil, nil, errors.New("mountpoint is not a directory")
|
||||
return nil, nil, errors.New("mountpoint is not a directory")
|
||||
}
|
||||
}
|
||||
|
||||
// Create underlying FS
|
||||
fsys := NewFS(f)
|
||||
fsys := NewFS(VFS)
|
||||
host := fuse.NewFileSystemHost(fsys)
|
||||
if usingReaddirPlus {
|
||||
host.SetCapReaddirPlus(true)
|
||||
|
@ -158,7 +158,7 @@ func mount(f fs.Fs, mountpoint string) (*vfs.VFS, <-chan error, func() error, er
|
|||
host.SetCapCaseInsensitive(f.Features().CaseInsensitive)
|
||||
|
||||
// Create options
|
||||
options := mountOptions(f.Name()+":"+f.Root(), mountpoint)
|
||||
options := mountOptions(VFS, f.Name()+":"+f.Root(), mountpoint)
|
||||
fs.Debugf(f, "Mounting with options: %q", options)
|
||||
|
||||
// Serve the mount point in the background returning error to errChan
|
||||
|
@ -199,7 +199,7 @@ func mount(f fs.Fs, mountpoint string) (*vfs.VFS, <-chan error, func() error, er
|
|||
select {
|
||||
case err := <-errChan:
|
||||
err = errors.Wrap(err, "mount stopped before calling Init")
|
||||
return nil, nil, nil, err
|
||||
return nil, nil, err
|
||||
case <-fsys.ready:
|
||||
}
|
||||
|
||||
|
@ -214,15 +214,15 @@ func mount(f fs.Fs, mountpoint string) (*vfs.VFS, <-chan error, func() error, er
|
|||
}
|
||||
}
|
||||
|
||||
return fsys.VFS, errChan, unmount, nil
|
||||
return errChan, unmount, nil
|
||||
}
|
||||
|
||||
// Mount mounts the remote at mountpoint.
|
||||
//
|
||||
// If noModTime is set then it
|
||||
func Mount(f fs.Fs, mountpoint string) error {
|
||||
func Mount(VFS *vfs.VFS, mountpoint string) error {
|
||||
// Mount it
|
||||
FS, errChan, unmount, err := mount(f, mountpoint)
|
||||
errChan, unmount, err := mount(VFS, mountpoint)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to mount FUSE fs")
|
||||
}
|
||||
|
@ -248,9 +248,9 @@ waitloop:
|
|||
break waitloop
|
||||
// user sent SIGHUP to clear the cache
|
||||
case <-sigHup:
|
||||
root, err := FS.Root()
|
||||
root, err := VFS.Root()
|
||||
if err != nil {
|
||||
fs.Errorf(f, "Error reading root: %v", err)
|
||||
fs.Errorf(VFS.Fs(), "Error reading root: %v", err)
|
||||
} else {
|
||||
root.ForgetAll()
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ import (
|
|||
"github.com/rclone/rclone/fs"
|
||||
"github.com/rclone/rclone/fs/log"
|
||||
"github.com/rclone/rclone/vfs"
|
||||
"github.com/rclone/rclone/vfs/vfsflags"
|
||||
)
|
||||
|
||||
// FS represents the top level filing system
|
||||
|
@ -28,10 +27,10 @@ type FS struct {
|
|||
var _ fusefs.FS = (*FS)(nil)
|
||||
|
||||
// NewFS makes a new FS
|
||||
func NewFS(f fs.Fs) *FS {
|
||||
func NewFS(VFS *vfs.VFS) *FS {
|
||||
fsys := &FS{
|
||||
VFS: vfs.New(f, &vfsflags.Opt),
|
||||
f: f,
|
||||
VFS: VFS,
|
||||
f: VFS.Fs(),
|
||||
}
|
||||
return fsys
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ import (
|
|||
"github.com/rclone/rclone/fs"
|
||||
"github.com/rclone/rclone/lib/atexit"
|
||||
"github.com/rclone/rclone/vfs"
|
||||
"github.com/rclone/rclone/vfs/vfsflags"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -28,7 +27,7 @@ func init() {
|
|||
}
|
||||
|
||||
// mountOptions configures the options from the command line flags
|
||||
func mountOptions(device string) (options []fuse.MountOption) {
|
||||
func mountOptions(VFS *vfs.VFS, device string) (options []fuse.MountOption) {
|
||||
options = []fuse.MountOption{
|
||||
fuse.MaxReadahead(uint32(mountlib.MaxReadAhead)),
|
||||
fuse.Subtype("rclone"),
|
||||
|
@ -61,7 +60,7 @@ func mountOptions(device string) (options []fuse.MountOption) {
|
|||
if mountlib.DefaultPermissions {
|
||||
options = append(options, fuse.DefaultPermissions())
|
||||
}
|
||||
if vfsflags.Opt.ReadOnly {
|
||||
if VFS.Opt.ReadOnly {
|
||||
options = append(options, fuse.ReadOnly())
|
||||
}
|
||||
if mountlib.WritebackCache {
|
||||
|
@ -85,14 +84,15 @@ func mountOptions(device string) (options []fuse.MountOption) {
|
|||
//
|
||||
// returns an error, and an error channel for the serve process to
|
||||
// report an error when fusermount is called.
|
||||
func mount(f fs.Fs, mountpoint string) (*vfs.VFS, <-chan error, func() error, error) {
|
||||
func mount(VFS *vfs.VFS, mountpoint string) (<-chan error, func() error, error) {
|
||||
f := VFS.Fs()
|
||||
fs.Debugf(f, "Mounting on %q", mountpoint)
|
||||
c, err := fuse.Mount(mountpoint, mountOptions(f.Name()+":"+f.Root())...)
|
||||
c, err := fuse.Mount(mountpoint, mountOptions(VFS, f.Name()+":"+f.Root())...)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
filesys := NewFS(f)
|
||||
filesys := NewFS(VFS)
|
||||
server := fusefs.New(c, nil)
|
||||
|
||||
// Serve the mount point in the background returning error to errChan
|
||||
|
@ -109,7 +109,7 @@ func mount(f fs.Fs, mountpoint string) (*vfs.VFS, <-chan error, func() error, er
|
|||
// check if the mount process has an error to report
|
||||
<-c.Ready
|
||||
if err := c.MountError; err != nil {
|
||||
return nil, nil, nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
unmount := func() error {
|
||||
|
@ -118,13 +118,13 @@ func mount(f fs.Fs, mountpoint string) (*vfs.VFS, <-chan error, func() error, er
|
|||
return fuse.Unmount(mountpoint)
|
||||
}
|
||||
|
||||
return filesys.VFS, errChan, unmount, nil
|
||||
return errChan, unmount, nil
|
||||
}
|
||||
|
||||
// Mount mounts the remote at mountpoint.
|
||||
//
|
||||
// If noModTime is set then it
|
||||
func Mount(f fs.Fs, mountpoint string) error {
|
||||
func Mount(VFS *vfs.VFS, mountpoint string) error {
|
||||
if mountlib.DebugFUSE {
|
||||
fuse.Debug = func(msg interface{}) {
|
||||
fs.Debugf("fuse", "%v", msg)
|
||||
|
@ -132,7 +132,7 @@ func Mount(f fs.Fs, mountpoint string) error {
|
|||
}
|
||||
|
||||
// Mount it
|
||||
FS, errChan, unmount, err := mount(f, mountpoint)
|
||||
errChan, unmount, err := mount(VFS, mountpoint)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to mount FUSE fs")
|
||||
}
|
||||
|
@ -162,9 +162,9 @@ waitloop:
|
|||
break waitloop
|
||||
// user sent SIGHUP to clear the cache
|
||||
case <-sigHup:
|
||||
root, err := FS.Root()
|
||||
root, err := VFS.Root()
|
||||
if err != nil {
|
||||
fs.Errorf(f, "Error reading root: %v", err)
|
||||
fs.Errorf(VFS.Fs(), "Error reading root: %v", err)
|
||||
} else {
|
||||
root.ForgetAll()
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ import (
|
|||
"github.com/rclone/rclone/fs"
|
||||
"github.com/rclone/rclone/fs/log"
|
||||
"github.com/rclone/rclone/vfs"
|
||||
"github.com/rclone/rclone/vfs/vfsflags"
|
||||
)
|
||||
|
||||
// FS represents the top level filing system
|
||||
|
@ -24,10 +23,10 @@ type FS struct {
|
|||
}
|
||||
|
||||
// NewFS creates a pathfs.FileSystem from the fs.Fs passed in
|
||||
func NewFS(f fs.Fs) *FS {
|
||||
func NewFS(VFS *vfs.VFS) *FS {
|
||||
fsys := &FS{
|
||||
VFS: vfs.New(f, &vfsflags.Opt),
|
||||
f: f,
|
||||
VFS: VFS,
|
||||
f: VFS.Fs(),
|
||||
}
|
||||
return fsys
|
||||
}
|
||||
|
|
|
@ -156,10 +156,11 @@ func mountOptions(fsys *FS, f fs.Fs) (mountOpts *fuse.MountOptions) {
|
|||
//
|
||||
// returns an error, and an error channel for the serve process to
|
||||
// report an error when fusermount is called.
|
||||
func mount(f fs.Fs, mountpoint string) (*vfs.VFS, <-chan error, func() error, error) {
|
||||
func mount(VFS *vfs.VFS, mountpoint string) (<-chan error, func() error, error) {
|
||||
f := VFS.Fs()
|
||||
fs.Debugf(f, "Mounting on %q", mountpoint)
|
||||
|
||||
fsys := NewFS(f)
|
||||
fsys := NewFS(VFS)
|
||||
// nodeFsOpts := &fusefs.PathNodeFsOptions{
|
||||
// ClientInodes: false,
|
||||
// Debug: mountlib.DebugFUSE,
|
||||
|
@ -187,20 +188,20 @@ func mount(f fs.Fs, mountpoint string) (*vfs.VFS, <-chan error, func() error, er
|
|||
|
||||
root, err := fsys.Root()
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
rawFS := fusefs.NewNodeFS(root, &opts)
|
||||
server, err := fuse.NewServer(rawFS, mountpoint, &opts.MountOptions)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
//mountOpts := &fuse.MountOptions{}
|
||||
//server, err := fusefs.Mount(mountpoint, fsys, &opts)
|
||||
// server, err := fusefs.Mount(mountpoint, root, &opts)
|
||||
// if err != nil {
|
||||
// return nil, nil, nil, err
|
||||
// return nil, nil, err
|
||||
// }
|
||||
|
||||
umount := func() error {
|
||||
|
@ -222,19 +223,19 @@ func mount(f fs.Fs, mountpoint string) (*vfs.VFS, <-chan error, func() error, er
|
|||
fs.Debugf(f, "Waiting for the mount to start...")
|
||||
err = server.WaitMount()
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
fs.Debugf(f, "Mount started")
|
||||
return fsys.VFS, errs, umount, nil
|
||||
return errs, umount, nil
|
||||
}
|
||||
|
||||
// Mount mounts the remote at mountpoint.
|
||||
//
|
||||
// If noModTime is set then it
|
||||
func Mount(f fs.Fs, mountpoint string) error {
|
||||
func Mount(VFS *vfs.VFS, mountpoint string) error {
|
||||
// Mount it
|
||||
vfs, errChan, unmount, err := mount(f, mountpoint)
|
||||
errChan, unmount, err := mount(VFS, mountpoint)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to mount FUSE fs")
|
||||
}
|
||||
|
@ -263,9 +264,9 @@ waitloop:
|
|||
break waitloop
|
||||
// user sent SIGHUP to clear the cache
|
||||
case <-sigHup:
|
||||
root, err := vfs.Root()
|
||||
root, err := VFS.Root()
|
||||
if err != nil {
|
||||
fs.Errorf(f, "Error reading root: %v", err)
|
||||
fs.Errorf(VFS.Fs(), "Error reading root: %v", err)
|
||||
} else {
|
||||
root.ForgetAll()
|
||||
}
|
||||
|
|
|
@ -43,7 +43,9 @@ type (
|
|||
// UnmountFn is called to unmount the file system
|
||||
UnmountFn func() error
|
||||
// MountFn is called to mount the file system
|
||||
MountFn func(f fs.Fs, mountpoint string) (*vfs.VFS, <-chan error, func() error, error)
|
||||
MountFn func(VFS *vfs.VFS, mountpoint string) (<-chan error, func() error, error)
|
||||
// MountBlockingFn is called to mount the file system and block
|
||||
MountBlockingFn func(VFS *vfs.VFS, mountpoint string) error
|
||||
)
|
||||
|
||||
// Global constants
|
||||
|
@ -106,7 +108,7 @@ func checkMountpointOverlap(root, mountpoint string) error {
|
|||
}
|
||||
|
||||
// NewMountCommand makes a mount command with the given name and Mount function
|
||||
func NewMountCommand(commandName string, hidden bool, Mount func(f fs.Fs, mountpoint string) error) *cobra.Command {
|
||||
func NewMountCommand(commandName string, hidden bool, Mount MountBlockingFn) *cobra.Command {
|
||||
var commandDefinition = &cobra.Command{
|
||||
Use: commandName + " remote:path /path/to/mountpoint",
|
||||
Hidden: hidden,
|
||||
|
@ -346,7 +348,8 @@ be copied to the vfs cache before opening with --vfs-cache-mode full.
|
|||
}
|
||||
}
|
||||
|
||||
err := Mount(fdst, mountpoint)
|
||||
VFS := vfs.New(fdst, &vfsflags.Opt)
|
||||
err := Mount(VFS, mountpoint)
|
||||
if err != nil {
|
||||
log.Fatalf("Fatal error: %v", err)
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
"github.com/rclone/rclone/fs"
|
||||
"github.com/rclone/rclone/fs/rc"
|
||||
"github.com/rclone/rclone/vfs"
|
||||
"github.com/rclone/rclone/vfs/vfsflags"
|
||||
)
|
||||
|
||||
// MountInfo defines the configuration for a mount
|
||||
|
@ -91,7 +93,8 @@ func mountRc(_ context.Context, in rc.Params) (out rc.Params, err error) {
|
|||
}
|
||||
|
||||
if mountFns[mountType] != nil {
|
||||
_, _, unmountFn, err := mountFns[mountType](fdst, mountPoint)
|
||||
VFS := vfs.New(fdst, &vfsflags.Opt)
|
||||
_, unmountFn, err := mountFns[mountType](VFS, mountPoint)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("mount FAILED: %v", err)
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"github.com/rclone/rclone/fstest"
|
||||
"github.com/rclone/rclone/vfs"
|
||||
"github.com/rclone/rclone/vfs/vfscommon"
|
||||
"github.com/rclone/rclone/vfs/vfsflags"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
@ -33,7 +34,7 @@ type (
|
|||
// UnmountFn is called to unmount the file system
|
||||
UnmountFn func() error
|
||||
// MountFn is called to mount the file system
|
||||
MountFn func(f fs.Fs, mountpoint string) (vfs *vfs.VFS, unmountResult <-chan error, unmount func() error, err error)
|
||||
MountFn func(VFS *vfs.VFS, mountpoint string) (unmountResult <-chan error, unmount func() error, err error)
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -176,7 +177,8 @@ found:
|
|||
func (r *Run) mount() {
|
||||
log.Printf("mount %q %q", r.fremote, r.mountPath)
|
||||
var err error
|
||||
r.vfs, r.umountResult, r.umountFn, err = mountFn(r.fremote, r.mountPath)
|
||||
r.vfs = vfs.New(r.fremote, &vfsflags.Opt)
|
||||
r.umountResult, r.umountFn, err = mountFn(r.vfs, r.mountPath)
|
||||
if err != nil {
|
||||
log.Printf("mount FAILED: %v", err)
|
||||
r.skip = true
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
"testing"
|
||||
|
||||
_ "github.com/rclone/rclone/backend/all" // import all the backends
|
||||
"github.com/rclone/rclone/fs"
|
||||
"github.com/rclone/rclone/fstest"
|
||||
"github.com/rclone/rclone/vfs"
|
||||
"github.com/rclone/rclone/vfs/vfstest"
|
||||
|
@ -18,13 +17,12 @@ func TestFunctional(t *testing.T) {
|
|||
if *fstest.RemoteName != "" {
|
||||
t.Skip("Skip on non local")
|
||||
}
|
||||
vfstest.RunTests(t, true, func(f fs.Fs, mountpoint string) (VFS *vfs.VFS, unmountResult <-chan error, unmount func() error, err error) {
|
||||
vfstest.RunTests(t, true, func(VFS *vfs.VFS, mountpoint string) (unmountResult <-chan error, unmount func() error, err error) {
|
||||
unmountResultChan := make(chan (error), 1)
|
||||
unmount = func() error {
|
||||
unmountResultChan <- nil
|
||||
return nil
|
||||
}
|
||||
VFS = vfs.New(f, nil)
|
||||
return VFS, unmountResultChan, unmount, nil
|
||||
return unmountResultChan, unmount, nil
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user