rc: Add mount list option for listing current mounts

This commit is contained in:
Chaitanya 2020-06-04 22:43:10 +05:30 committed by Nick Craig-Wood
parent 7e48ee8758
commit 830ab37371

View File

@ -4,29 +4,40 @@ import (
"context" "context"
"log" "log"
"sort" "sort"
"sync"
"time"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs"
"github.com/rclone/rclone/fs/rc" "github.com/rclone/rclone/fs/rc"
) )
// MountInfo defines the configuration for a mount
type MountInfo struct {
unmountFn UnmountFn
MountPoint string `json:"MountPoint"`
MountedOn time.Time `json:"MountedOn"`
Fs string `json:"Fs"`
}
var ( var (
// Mount functions available // Mount functions available
mountFns map[string]MountFn mountFns = map[string]MountFn{}
// Map of mounted path => unmount function // mutex for mountFns
unmountFns map[string]UnmountFn mountFnsMutex = &sync.Mutex{}
// Map of mounted path => MountInfo
liveMounts = map[string]MountInfo{}
// mutex for live mounts
liveMountsMutex = sync.Mutex{}
) )
// AddRc adds mount and unmount functionality to rc // AddRc adds mount and unmount functionality to rc
func AddRc(mountUtilName string, mountFunction MountFn) { func AddRc(mountUtilName string, mountFunction MountFn) {
if mountFns == nil { mountFnsMutex.Lock()
mountFns = make(map[string]MountFn)
}
if unmountFns == nil {
unmountFns = make(map[string]UnmountFn)
}
// rcMount allows the mount command to be run from rc // rcMount allows the mount command to be run from rc
mountFns[mountUtilName] = mountFunction mountFns[mountUtilName] = mountFunction
mountFnsMutex.Unlock()
} }
func init() { func init() {
@ -54,7 +65,7 @@ Eg
}) })
} }
// rcMount allows the mount command to be run from rc // mountRc allows the mount command to be run from rc
func mountRc(_ context.Context, in rc.Params) (out rc.Params, err error) { func mountRc(_ context.Context, in rc.Params) (out rc.Params, err error) {
mountPoint, err := in.GetString("mountPoint") mountPoint, err := in.GetString("mountPoint")
if err != nil { if err != nil {
@ -80,7 +91,16 @@ func mountRc(_ context.Context, in rc.Params) (out rc.Params, err error) {
} }
if mountFns[mountType] != nil { if mountFns[mountType] != nil {
_, _, unmountFns[mountPoint], err = mountFns[mountType](fdst, mountPoint) _, _, unmountFn, err := mountFns[mountType](fdst, mountPoint)
liveMountsMutex.Lock()
liveMounts[mountPoint] = MountInfo{
unmountFn: unmountFn,
MountedOn: time.Now(),
Fs: fdst.Name(),
MountPoint: mountPoint,
}
liveMountsMutex.Unlock()
if err != nil { if err != nil {
log.Printf("mount FAILED: %v", err) log.Printf("mount FAILED: %v", err)
return nil, err return nil, err
@ -96,7 +116,7 @@ func init() {
Path: "mount/unmount", Path: "mount/unmount",
AuthRequired: true, AuthRequired: true,
Fn: unMountRc, Fn: unMountRc,
Title: "Unmount all active mounts", Title: "Unmount selected active mount",
Help: ` Help: `
rclone allows Linux, FreeBSD, macOS and Windows to rclone allows Linux, FreeBSD, macOS and Windows to
mount any of Rclone's cloud storage systems as a file system with mount any of Rclone's cloud storage systems as a file system with
@ -113,26 +133,37 @@ Eg
}) })
} }
// rcMount allows the umount command to be run from rc // unMountRc allows the umount command to be run from rc
func unMountRc(_ context.Context, in rc.Params) (out rc.Params, err error) { func unMountRc(_ context.Context, in rc.Params) (out rc.Params, err error) {
mountPoint, err := in.GetString("mountPoint") mountPoint, err := in.GetString("mountPoint")
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = performUnMount(mountPoint)
if unmountFns != nil && unmountFns[mountPoint] != nil { if err != nil {
err := unmountFns[mountPoint]() return nil, err
if err != nil {
return nil, err
}
unmountFns[mountPoint] = nil
} else {
return nil, errors.New("mount not found")
} }
return nil, nil return nil, nil
} }
// performUnMount unmounts the specified mountPoint
func performUnMount(mountPoint string) (err error) {
liveMountsMutex.Lock()
defer liveMountsMutex.Unlock()
mountInfo, ok := liveMounts[mountPoint]
if ok {
err := mountInfo.unmountFn()
if err != nil {
return err
}
delete(liveMounts, mountPoint)
} else {
return errors.New("mount not found")
}
return nil
}
func init() { func init() {
rc.Add(rc.Call{ rc.Add(rc.Call{
Path: "mount/types", Path: "mount/types",
@ -158,11 +189,45 @@ Eg
// mountTypesRc returns a list of available mount types. // mountTypesRc returns a list of available mount types.
func mountTypesRc(_ context.Context, in rc.Params) (out rc.Params, err error) { func mountTypesRc(_ context.Context, in rc.Params) (out rc.Params, err error) {
var mountTypes = []string{} var mountTypes = []string{}
mountFnsMutex.Lock()
for mountType := range mountFns { for mountType := range mountFns {
mountTypes = append(mountTypes, mountType) mountTypes = append(mountTypes, mountType)
} }
mountFnsMutex.Unlock()
sort.Strings(mountTypes) sort.Strings(mountTypes)
return rc.Params{ return rc.Params{
"mountTypes": mountTypes, "mountTypes": mountTypes,
}, nil }, nil
} }
func init() {
rc.Add(rc.Call{
Path: "mount/listmounts",
AuthRequired: true,
Fn: listMountsRc,
Title: "Show current mount points",
Help: `This shows currently mounted points, which can be used for performing an unmount
This takes no parameters and returns
- mountPoints: list of current mount points
Eg
rclone rc mount/listmounts
`,
})
}
// listMountsRc returns a list of current mounts
func listMountsRc(_ context.Context, in rc.Params) (out rc.Params, err error) {
var mountTypes = []MountInfo{}
liveMountsMutex.Lock()
for _, a := range liveMounts {
mountTypes = append(mountTypes, a)
}
liveMountsMutex.Unlock()
return rc.Params{
"mountPoints": mountTypes,
}, nil
}