fs: Allow on the fly remotes with :backend: syntax - fixes #2449
This change allows remotes to be created on the fly without a config file by using the remote type prefixed with a : as the remote name, Eg :s3: to make an s3 remote. This assumes the user is supplying the backend config via command line flags or environment variables.
This commit is contained in:
parent
174ca22936
commit
8656bd2bb0
5 changed files with 64 additions and 18 deletions
|
@ -133,6 +133,48 @@ It is recommended to use `copy` when copying individual files, not `sync`.
|
||||||
They have pretty much the same effect but `copy` will use a lot less
|
They have pretty much the same effect but `copy` will use a lot less
|
||||||
memory.
|
memory.
|
||||||
|
|
||||||
|
Syntax of remote paths
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
The syntax of the paths passed to the rclone command are as follows.
|
||||||
|
|
||||||
|
### /path/to/dir
|
||||||
|
|
||||||
|
This refers to the local file system.
|
||||||
|
|
||||||
|
On Windows only `\` may be used instead of `/` in local paths
|
||||||
|
**only**, non local paths must use `/`.
|
||||||
|
|
||||||
|
These paths needn't start with a leading `/` - if they don't then they
|
||||||
|
will be relative to the current directory.
|
||||||
|
|
||||||
|
### remote:path/to/dir
|
||||||
|
|
||||||
|
This refers to a directory `path/to/dir` on `remote:` as defined in
|
||||||
|
the config file (configured with `rclone config`).
|
||||||
|
|
||||||
|
### remote:/path/to/dir
|
||||||
|
|
||||||
|
On most backends this is refers to the same directory as
|
||||||
|
`remote:path/to/dir` and that format should be preferred. On a very
|
||||||
|
small number of remotes (FTP, SFTP, Dropbox for business) this will
|
||||||
|
refer to a different directory. On these, paths without a leading `/`
|
||||||
|
will refer to your "home" directory and paths with a leading `/` will
|
||||||
|
refer to the root.
|
||||||
|
|
||||||
|
### :backend:path/to/dir
|
||||||
|
|
||||||
|
This is an advanced form for creating remotes on the fly. `backend`
|
||||||
|
should be the name or prefix of a backend (the `type` in the config
|
||||||
|
file) and all the configuration for the backend should be provided on
|
||||||
|
the command line (or in environment variables).
|
||||||
|
|
||||||
|
Eg
|
||||||
|
|
||||||
|
rclone lsd --http-url https://pub.rclone.org :http:
|
||||||
|
|
||||||
|
Which lists all the directories in `pub.rclone.org`.
|
||||||
|
|
||||||
Quoting and the shell
|
Quoting and the shell
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
|
|
|
@ -121,17 +121,7 @@ No checksums are stored.
|
||||||
|
|
||||||
### Usage without a config file ###
|
### Usage without a config file ###
|
||||||
|
|
||||||
Note that since only two environment variable need to be set, it is
|
Since the http remote only has one config parameter it is easy to use
|
||||||
easy to use without a config file like this.
|
without a config file:
|
||||||
|
|
||||||
```
|
rclone lsd --http-url https://beta.rclone.org :http:
|
||||||
RCLONE_CONFIG_ZZ_TYPE=http RCLONE_CONFIG_ZZ_URL=https://beta.rclone.org rclone lsd zz:
|
|
||||||
```
|
|
||||||
|
|
||||||
Or if you prefer
|
|
||||||
|
|
||||||
```
|
|
||||||
export RCLONE_CONFIG_ZZ_TYPE=http
|
|
||||||
export RCLONE_CONFIG_ZZ_URL=https://beta.rclone.org
|
|
||||||
rclone lsd zz:
|
|
||||||
```
|
|
||||||
|
|
12
fs/fs.go
12
fs/fs.go
|
@ -859,10 +859,14 @@ func ParseRemote(path string) (fsInfo *RegInfo, configName, fsPath string, err e
|
||||||
var fsName string
|
var fsName string
|
||||||
var ok bool
|
var ok bool
|
||||||
if configName != "" {
|
if configName != "" {
|
||||||
m := ConfigMap(nil, configName)
|
if strings.HasPrefix(configName, ":") {
|
||||||
fsName, ok = m.Get("type")
|
fsName = configName[1:]
|
||||||
if !ok {
|
} else {
|
||||||
return nil, "", "", ErrorNotFoundInConfigFile
|
m := ConfigMap(nil, configName)
|
||||||
|
fsName, ok = m.Get("type")
|
||||||
|
if !ok {
|
||||||
|
return nil, "", "", ErrorNotFoundInConfigFile
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fsName = "local"
|
fsName = "local"
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Matcher is a pattern to match an rclone URL
|
// Matcher is a pattern to match an rclone URL
|
||||||
var Matcher = regexp.MustCompile(`^([\w_ -]+):(.*)$`)
|
var Matcher = regexp.MustCompile(`^(:?[\w_ -]+):(.*)$`)
|
||||||
|
|
||||||
// Parse deconstructs a remote path into configName and fsPath
|
// Parse deconstructs a remote path into configName and fsPath
|
||||||
//
|
//
|
||||||
|
|
|
@ -16,6 +16,7 @@ func TestParse(t *testing.T) {
|
||||||
{"path/to/file", "", "path/to/file"},
|
{"path/to/file", "", "path/to/file"},
|
||||||
{"remote:path/to/file", "remote", "path/to/file"},
|
{"remote:path/to/file", "remote", "path/to/file"},
|
||||||
{"remote:/path/to/file", "remote", "/path/to/file"},
|
{"remote:/path/to/file", "remote", "/path/to/file"},
|
||||||
|
{":backend:/path/to/file", ":backend", "/path/to/file"},
|
||||||
} {
|
} {
|
||||||
gotConfigName, gotFsPath := Parse(test.in)
|
gotConfigName, gotFsPath := Parse(test.in)
|
||||||
assert.Equal(t, test.wantConfigName, gotConfigName)
|
assert.Equal(t, test.wantConfigName, gotConfigName)
|
||||||
|
@ -28,12 +29,21 @@ func TestSplit(t *testing.T) {
|
||||||
remote, wantParent, wantLeaf string
|
remote, wantParent, wantLeaf string
|
||||||
}{
|
}{
|
||||||
{"", "", ""},
|
{"", "", ""},
|
||||||
|
|
||||||
{"remote:", "remote:", ""},
|
{"remote:", "remote:", ""},
|
||||||
{"remote:potato", "remote:", "potato"},
|
{"remote:potato", "remote:", "potato"},
|
||||||
{"remote:/", "remote:/", ""},
|
{"remote:/", "remote:/", ""},
|
||||||
{"remote:/potato", "remote:/", "potato"},
|
{"remote:/potato", "remote:/", "potato"},
|
||||||
{"remote:/potato/potato", "remote:/potato/", "potato"},
|
{"remote:/potato/potato", "remote:/potato/", "potato"},
|
||||||
{"remote:potato/sausage", "remote:potato/", "sausage"},
|
{"remote:potato/sausage", "remote:potato/", "sausage"},
|
||||||
|
|
||||||
|
{":remote:", ":remote:", ""},
|
||||||
|
{":remote:potato", ":remote:", "potato"},
|
||||||
|
{":remote:/", ":remote:/", ""},
|
||||||
|
{":remote:/potato", ":remote:/", "potato"},
|
||||||
|
{":remote:/potato/potato", ":remote:/potato/", "potato"},
|
||||||
|
{":remote:potato/sausage", ":remote:potato/", "sausage"},
|
||||||
|
|
||||||
{"/", "/", ""},
|
{"/", "/", ""},
|
||||||
{"/root", "/", "root"},
|
{"/root", "/", "root"},
|
||||||
{"/a/b", "/a/", "b"},
|
{"/a/b", "/a/", "b"},
|
||||||
|
|
Loading…
Reference in a new issue