From 5f168b3b96c68790b7554d36c5a669c4ecaca506 Mon Sep 17 00:00:00 2001 From: Chaitanya Date: Sat, 25 Apr 2020 10:33:07 +0530 Subject: [PATCH] rc: add mount/mount command --- cmd/cmount/mount.go | 3 + cmd/mount/mount.go | 2 + cmd/mount2/mount.go | 4 ++ cmd/mountlib/mount.go | 7 +++ cmd/mountlib/rc.go | 132 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 148 insertions(+) create mode 100644 cmd/mountlib/rc.go diff --git a/cmd/cmount/mount.go b/cmd/cmount/mount.go index 78099f012..1e39f773b 100644 --- a/cmd/cmount/mount.go +++ b/cmd/cmount/mount.go @@ -39,6 +39,9 @@ func init() { name = "mount" } mountlib.NewMountCommand(name, false, Mount) + // Add mount to rc + mountlib.AddRc("cmount", mount) + } // mountOptions configures the options from the command line flags diff --git a/cmd/mount/mount.go b/cmd/mount/mount.go index 15e59b47b..50d66060f 100644 --- a/cmd/mount/mount.go +++ b/cmd/mount/mount.go @@ -23,6 +23,8 @@ import ( func init() { mountlib.NewMountCommand("mount", false, Mount) + // Add mount to rc + mountlib.AddRc("mount", mount) } // mountOptions configures the options from the command line flags diff --git a/cmd/mount2/mount.go b/cmd/mount2/mount.go index 3e6da0152..b20b5a214 100644 --- a/cmd/mount2/mount.go +++ b/cmd/mount2/mount.go @@ -24,6 +24,10 @@ import ( func init() { mountlib.NewMountCommand("mount2", true, Mount) + + // Add mount to rc + mountlib.AddRc("mount2", mount) + } // mountOptions configures the options from the command line flags diff --git a/cmd/mountlib/mount.go b/cmd/mountlib/mount.go index 6b4d34874..f5ea13c02 100644 --- a/cmd/mountlib/mount.go +++ b/cmd/mountlib/mount.go @@ -39,6 +39,13 @@ var ( AsyncRead = true // do async reads by default ) +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) +) + // Global constants const ( MaxLeafSize = 4095 // don't pass file names longer than this diff --git a/cmd/mountlib/rc.go b/cmd/mountlib/rc.go new file mode 100644 index 000000000..1515273b8 --- /dev/null +++ b/cmd/mountlib/rc.go @@ -0,0 +1,132 @@ +package mountlib + +import ( + "context" + "log" + + "github.com/pkg/errors" + "github.com/rclone/rclone/fs" + "github.com/rclone/rclone/fs/rc" +) + +var ( + // Mount functions available + mountFns map[string]MountFn + // Map of mounted path => unmount function + unmountFns map[string]UnmountFn +) + +func init() { + rc.Add(rc.Call{ + Path: "mount/mount", + AuthRequired: true, + Fn: mountRc, + Title: "Create a new mount point", + Help: `rclone allows Linux, FreeBSD, macOS and Windows to mount any of +Rclone's cloud storage systems as a file system with FUSE. + +If no mountOption is provided, the priority is given as follows: 1. mount 2.cmount 3.mount2 + +This takes the following parameters + +- fs - a remote path to be mounted (required) +- mountPoint: valid path on the local machine (required) +- mountOption: One of the values (mount, cmount, mount2) specifies the mount implementation to use + +Eg + + rclone rc mount/mount fs=mydrive: mountPoint=/home//mountPoint + rclone rc mount/mount fs=mydrive: mountPoint=/home//mountPoint mountOption=mount +`, + }) + + rc.Add(rc.Call{ + Path: "mount/unmount", + AuthRequired: true, + Fn: unMountRc, + Title: "Unmount all active mounts", + Help: ` +rclone allows Linux, FreeBSD, macOS and Windows to +mount any of Rclone's cloud storage systems as a file system with +FUSE. + +This takes the following parameters + +- mountPoint: valid path on the local machine where the mount was created (required) + +Eg + + rclone rc mount/unmount mountPoint=/home//mountPoint +`, + }) + +} + +// AddRc adds mount and unmount functionality to rc +func AddRc(mountUtilName string, mountFunction MountFn) { + if mountFns == nil { + mountFns = make(map[string]MountFn) + } + if unmountFns == nil { + unmountFns = make(map[string]UnmountFn) + } + // rcMount allows the mount command to be run from rc + mountFns[mountUtilName] = mountFunction +} + +// rcMount allows the umount command to be run from rc +func unMountRc(_ context.Context, in rc.Params) (out rc.Params, err error) { + mountPoint, err := in.GetString("mountPoint") + if err != nil { + return nil, err + } + + if unmountFns != nil && unmountFns[mountPoint] != nil { + err := unmountFns[mountPoint]() + if err != nil { + return nil, err + } + unmountFns[mountPoint] = nil + } else { + return nil, errors.New("mount not found") + } + + return nil, nil +} + +// rcMount allows the mount command to be run from rc +func mountRc(_ context.Context, in rc.Params) (out rc.Params, err error) { + mountPoint, err := in.GetString("mountPoint") + if err != nil { + return nil, err + } + + mountOption, err := in.GetString("mountOption") + + if err != nil || mountOption == "" { + if mountFns["mount"] != nil { + mountOption = "mount" + } else if mountFns["cmount"] != nil { + mountOption = "cmount" + } else if mountFns["mount2"] != nil { + mountOption = "mount2" + } + } + + // Get Fs.fs to be mounted from fs parameter in the params + fdst, err := rc.GetFs(in) + if err != nil { + return nil, err + } + + if mountFns[mountOption] != nil { + _, _, unmountFns[mountPoint], err = mountFns[mountOption](fdst, mountPoint) + if err != nil { + log.Printf("mount FAILED: %v", err) + return nil, err + } + fs.Debugf(nil, "Mount for %s created at %s using %s", fdst.String(), mountPoint, mountOption) + return nil, nil + } + return nil, errors.New("Mount Option specified is not registered, or is invalid") +}