-
Notifications
You must be signed in to change notification settings - Fork 2
/
mounts.go
216 lines (177 loc) · 8.61 KB
/
mounts.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
package rclone
import (
"context"
"strings"
"time"
"github.com/darkhz/rclone-tui/rclone"
)
// Mounts stores the list of mountpoints.
type Mounts struct {
MountPoints []MountPoint `json:"mountPoints"`
}
// MountPoint stores information about a mountpoint.
type MountPoint struct {
Fs string `json:"Fs"`
MountPoint string `json:"MountPoint"`
MountedOn time.Time `json:"MountedOn"`
}
// MountHelp stores information about a mount option.
type MountHelp struct {
Name, Help, OptionType, ValueType string
Windows, OSX, Other bool
Options []string
}
var mountOptionHelp = []MountHelp{
{"FS", "A remote path to be mounted", "main:required", "string", true, true, true, nil},
{"MountPoint", "Valid path on the local machine", "main:required", "string", true, true, true, nil},
{"MountType", "One of the values (mount, cmount, mount2) specifies the mount implementation to use", "main:optional", "string", true, true, true, nil},
{"AllowNonEmpty", "Allow mounting over a non-empty directory", "mountOpt", "bool", false, true, true, nil},
{"AllowOther", "Allow access to other users", "mountOpt", "bool", false, true, true, nil},
{"AllowRoot", "Allow access to root user", "mountOpt", "bool", false, true, true, nil},
{"AsyncRead", "Use asynchronous reads", "mountOpt", "bool", false, true, true, nil},
{"AttrTimeout", "Time for which file/directory attributes are cached", "mountOpt", "Duration", true, true, true, nil},
{"CacheMaxAge", "Max age of objects in the cache", "vfsOpt", "Duration", true, true, true, nil},
{"CacheMaxSize", "Max total size of objects in the cache", "vfsOpt", "int", true, true, true, nil},
{"CacheMode", "Cache mode off|minimal|writes|full", "vfsOpt", "int", true, true, true, nil},
{"CachePollInterval", "Interval to poll the cache for stale objects", "vfsOpt", "Duration", true, true, true, nil},
{"CaseInsensitive", "If a file name not found, find a case insensitive match", "vfsOpt", "bool", true, true, true, nil},
{"ChunkSize", "Read the source objects in chunks", "vfsOpt", "int", true, true, true, nil},
{"ChunkSizeLimit", "If greater than --vfs-read-chunk-size, double the chunk size after each chunk read, until the limit is reached ('off' is unlimited)", "vfsOpt", "int", true, true, true, nil},
{"Daemon", "Run mount in background and exit parent process (as background output is suppressed, use --log-file with --log-format=pid,... to monitor)", "mountOpt", "bool", false, true, true, nil},
{"DaemonTimeout", "Time limit for rclone to respond to kernel", "mountOpt", "Duration", false, true, true, nil},
{"DaemonWait", "Time to wait for ready mount from daemon (maximum time on Linux, constant sleep time on OSX/BSD)", "mountOpt", "Duration", false, true, true, nil},
{"DebugFUSE", "Debug the FUSE internals", "mountOpt", "bool", true, true, true, nil},
{"DefaultPermissions", "Makes kernel enforce access control based on the file mode", "mountOpt", "bool", false, true, true, nil},
{"DeviceName", "Set the device name - default is remote:path", "mountOpt", "string", true, true, true, nil},
{"DirCacheTime", "Time to cache directory entries for", "vfsOpt", "Duration", true, true, true, nil},
{"DirPerms", "Directory permissions", "vfsOpt", "int", true, true, true, nil},
{"DiskSpaceTotalSize", "Specify the total space of disk", "vfsOpt", "int", true, true, true, nil},
{"ExtraFlags", "Flags or arguments to be passed direct to libfuse/WinFsp (repeat if required). Each mount option must be separated by a space.", "mountOpt", "StringArray", true, true, true, nil},
{"ExtraOptions", "Option for libfuse/WinFsp (repeat if required). Each mount option must be separated by a space.", "mountOpt", "StringArray", true, true, true, nil},
{"FastFingerprint", "Use fast (less accurate) fingerprints for change detection", "vfsOpt", "bool", true, true, true, nil},
{"FilePerms", "File permissions", "vfsOpt", "int", true, true, true, nil},
{"MaxReadAhead", "The number of bytes that can be prefetched for sequential reads", "mountOpt", "int", false, true, true, nil},
{"NetworkMode", "Mount as remote network drive, instead of fixed disk drive", "mountOpt", "bool", true, false, false, nil},
{"NoAppleDouble", "Ignore Apple Double (._) and .DS_Store files", "mountOpt", "bool", false, true, false, nil},
{"NoAppleXattr", "Ignore all \"com.apple.*\" extended attributes", "mountOpt", "bool", false, true, false, nil},
{"NoChecksum", "Don't compare checksums on up/download", "vfsOpt", "bool", true, true, true, nil},
{"NoModTime", "Don't read/write the modification time (can speed things up)", "vfsOpt", "bool", true, true, true, nil},
{"NoSeek", "Don't allow seeking in files", "vfsOpt", "bool", true, true, true, nil},
{"PollInterval", "Time to wait between polling for changes, must be smaller than dir-cache-time and only on supported remotes (set 0 to disable)", "vfsOpt", "Duration", true, true, true, nil},
{"ReadAhead", "Extra read ahead over --buffer-size when using cache-mode full", "vfsOpt", "int", true, true, true, nil},
{"ReadOnly", "Only allow read-only access", "vfsOpt", "bool", true, true, true, nil},
{"ReadWait", "Time to wait for in-sequence read before seeking", "vfsOpt", "Duration", true, true, true, nil},
{"UsedIsSize", "Use the `rclone size` algorithm for Used size", "vfsOpt", "bool", true, true, true, nil},
{"VolumeName", "Set the volume name", "mountOpt", "string", true, true, false, nil},
{"WriteBack", "Time to writeback files after last use when using cache", "vfsOpt", "Duration", true, true, true, nil},
{"WriteWait", "Time to wait for in-sequence write before giving error", "vfsOpt", "Duration", true, true, true, nil},
{"WritebackCache", "Makes kernel buffer writes before sending them to rclone (without this, writethrough caching is used)", "mountOpt", "bool", false, true, true, nil},
}
// CreateMount creates a mountpoint.
func CreateMount(mountData map[string]interface{}) error {
parseMountExtras(mountData)
job, err := rclone.SendCommandAsync("UI:Mounts", "Mounting remote", mountData, "/mount/mount")
if err != nil {
return err
}
_, err = rclone.GetJobReply(job)
return err
}
// Unmount unmounts the provided mountpoint.
func Unmount(mountpoint string) error {
command := map[string]interface{}{
"mountPoint": mountpoint,
}
job, err := rclone.SendCommandAsync("UI:Mounts", "Unmounting mountpoint", command, "/mount/unmount")
if err != nil {
return err
}
_, err = rclone.GetJobReply(job)
return err
}
// UnmountAll unmounts all mountpoints.
func UnmountAll() error {
job, err := rclone.SendCommandAsync(
"UI:Mounts", "Unmounting all mountpoints",
map[string]interface{}{}, "/mount/unmountall",
)
if err != nil {
return err
}
_, err = rclone.GetJobReply(job)
return err
}
// ListMountTypes lists the mount types.
func ListMountTypes(ctx context.Context) ([]string, error) {
return GetDataSlice(ctx, "/mount/types", "mountTypes")
}
// GetMountPoints returns a list of mountpoints.
func GetMountPoints() ([]MountPoint, error) {
var mounts Mounts
response, err := rclone.SendCommand(map[string]interface{}{}, "/mount/listmounts")
if err != nil {
return nil, err
}
err = response.Decode(&mounts)
return mounts.MountPoints, err
}
// GetMountHelp returns the information for a mount option.
func GetMountHelp(name string) MountHelp {
var mountHelp MountHelp
for _, mh := range mountOptionHelp {
if mh.Name == name {
mountHelp = mh
break
}
}
return mountHelp
}
// GetMountOptions returns a list of all mount options.
func GetMountOptions() ([]MountHelp, error) {
var opts []MountHelp
remotes, err := ListRemotes(rclone.GetClientContext())
if err != nil {
return nil, err
}
mountTypes, err := ListMountTypes(rclone.GetClientContext())
if err != nil {
return nil, err
}
version, _ := rclone.GetVersion(false)
for _, opt := range mountOptionHelp {
switch opt.Name {
case "FS":
opt.Options = remotes
case "MountType":
opt.Options = mountTypes
}
windowsOnly := version.Os == "windows" && opt.Windows
osxOnly := (version.Os == "darwin" || version.Os == "ios") && opt.OSX
if windowsOnly || osxOnly || (!windowsOnly && !osxOnly) && opt.Other {
opts = append(opts, opt)
}
}
mountOptionHelp = opts
return mountOptionHelp, nil
}
// parseMountExtras parses the 'ExtraFlags' and 'ExtraOptions' mount options.
func parseMountExtras(mountData map[string]interface{}) {
mountMap, ok := mountData["mountOpt"]
if !ok {
return
}
mountOpts, ok := mountMap.(map[string]interface{})
if !ok {
return
}
for _, mountFlag := range []string{
"ExtraFlags",
"ExtraOptions",
} {
if value, ok := mountOpts[mountFlag]; ok && value != nil {
if opts, ok := value.(string); ok {
mountOpts[mountFlag] = strings.Split(opts, " ")
}
}
}
}