fs: make --links flag global and add new --local-links and --vfs-links flag

Before this change the --links flag when using the VFS override the
--links flag for the local backend which meant the local backend
needed explicit config to use links.

This fixes the problem by making the --links flag global and adding a
new --local-links flag and --vfs-links flags to control the features
individually if required.
This commit is contained in:
Nick Craig-Wood 2024-11-22 11:42:31 +00:00
parent 9ac7334e9b
commit 67d905e40a
6 changed files with 62 additions and 20 deletions

View File

@ -100,10 +100,8 @@ Metadata is supported on files and directories.
},
{
Name: "links",
Help: "Translate symlinks to/from regular files with a '" + fs.LinkSuffix + "' extension.",
Help: "Translate symlinks to/from regular files with a '" + fs.LinkSuffix + "' extension for the local backend.",
Default: false,
NoPrefix: true,
ShortOpt: "l",
Advanced: true,
},
{
@ -383,12 +381,17 @@ var (
// NewFs constructs an Fs from the path
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
ci := fs.GetConfig(ctx)
// Parse config into Options struct
opt := new(Options)
err := configstruct.Set(m, opt)
if err != nil {
return nil, err
}
// Override --local-links with --links if set
if ci.Links {
opt.TranslateSymlinks = true
}
if opt.TranslateSymlinks && opt.FollowSymlinks {
return nil, errLinksAndCopyLinks
}

View File

@ -1426,6 +1426,22 @@ The options mean
During rmdirs it will not remove root directory, even if it's empty.
### --links / -l
Normally rclone will ignore symlinks or junction points (which behave
like symlinks under Windows).
If you supply this flag then rclone will copy symbolic links from any
supported backend backend, and store them as text files, with a
`.rclonelink` suffix in the destination.
The text file will contain the target of the symbolic link.
The `--links` / `-l` flag enables this feature for all supported
backends and the VFS. There are individual flags for just enabling it
for the VFS `--vfs-links` and the local backend `--local-links` if
required.
### --log-file=FILE ###
Log all of rclone's output to FILE. This is not active by default.

View File

@ -209,13 +209,13 @@ $ rclone -L ls /tmp/a
6 b/one
```
#### --links, -l
#### --local-links, --links, -l
Normally rclone will ignore symlinks or junction points (which behave
like symlinks under Windows).
If you supply this flag then rclone will copy symbolic links from the local storage,
and store them as text files, with a '.rclonelink' suffix in the remote storage.
and store them as text files, with a `.rclonelink` suffix in the remote storage.
The text file will contain the target of the symbolic link (see example).
@ -236,7 +236,7 @@ Copying the entire directory with '-l'
$ rclone copy -l /tmp/a/ remote:/tmp/a/
```
The remote files are created with a '.rclonelink' suffix
The remote files are created with a `.rclonelink` suffix
```
$ rclone ls remote:/tmp/a
@ -274,7 +274,7 @@ $ tree /tmp/b
/tmp/b
├── file1.rclonelink
└── file2.rclonelink
````
```
If you want to copy a single file with `-l` then you must use the `.rclonelink` suffix.
@ -286,6 +286,10 @@ $ tree /tmp/c
└── file1 -> ./file4
```
Note that `--local-links` just enables this feature for the local
backend. `--links` and `-l` enable the feature for all supported
backends and the VFS.
Note that this flag is incompatible with `-copy-links` / `-L`.
### Restricting filesystems with --one-file-system
@ -361,9 +365,9 @@ Properties:
- Type: bool
- Default: false
#### --links / -l
#### --local-links
Translate symlinks to/from regular files with a '.rclonelink' extension.
Translate symlinks to/from regular files with a '.rclonelink' extension for the local backend.
Properties:

View File

@ -105,6 +105,12 @@ var ConfigOptionsInfo = Options{{
Default: false,
Help: "Enable interactive mode",
Groups: "Config,Important",
}, {
Name: "links",
Help: "Translate symlinks to/from regular files with a '" + LinkSuffix + "' extension.",
Default: false,
ShortOpt: "l",
Groups: "Copy",
}, {
Name: "contimeout",
Default: 60 * time.Second,
@ -537,6 +543,7 @@ type ConfigInfo struct {
UseJSONLog bool `config:"use_json_log"`
DryRun bool `config:"dry_run"`
Interactive bool `config:"interactive"`
Links bool `config:"links"`
CheckSum bool `config:"checksum"`
SizeOnly bool `config:"size_only"`
IgnoreTimes bool `config:"ignore_times"`

View File

@ -305,10 +305,11 @@ modified files from the cache (the related global flag `--checkers` has no effec
### Symlinks
Be default the VFS does not support symlinks. However this may be
enabled with the following flag:
By default the VFS does not support symlinks. However this may be
enabled with either of the following flags:
--links Translate symlinks to/from regular files with a '.rclonelink' extension.
--links Translate symlinks to/from regular files with a '.rclonelink' extension.
--vfs-links Translate symlinks to/from regular files with a '.rclonelink' extension for the VFS
As most cloud storage systems do not support symlinks directly, rclone
stores the symlink as a normal file with a special extension. So a
@ -316,9 +317,13 @@ file which appears as a symlink `link-to-file.txt` would be stored on
cloud storage as `link-to-file.txt.rclonelink` and the contents would
be the path to the symlink destination.
This scheme is compatible with that used by the [local backend with the --links flag](/local/#symlinks-junction-points).
Note that `--links` enables symlink translation globally in rclone -
this includes any backend which supports the concept (for example the
local backend). `--vfs-links` just enables it for the VFS layer.
The `--links` flag has been designed for `rclone mount`, `rclone
This scheme is compatible with that used by the [local backend with the --local-links flag](/local/#symlinks-junction-points).
The `--vfs-links` flag has been designed for `rclone mount`, `rclone
nfsmount` and `rclone serve nfs`.
It hasn't been tested with the other `rclone serve` commands yet.

View File

@ -1,6 +1,7 @@
package vfscommon
import (
"context"
"os"
"runtime"
"time"
@ -45,11 +46,10 @@ var OptionsInfo = fs.Options{{
Help: "Only allow read-only access",
Groups: "VFS",
}, {
Name: "links",
Default: false,
Help: "Translate symlinks to/from regular files with a '" + fs.LinkSuffix + "' extension",
Groups: "VFS",
ShortOpt: "l",
Name: "vfs_links",
Default: false,
Help: "Translate symlinks to/from regular files with a '" + fs.LinkSuffix + "' extension for the VFS",
Groups: "VFS",
}, {
Name: "vfs_cache_mode",
Default: CacheModeOff,
@ -176,7 +176,7 @@ type Options struct {
NoSeek bool `config:"no_seek"` // don't allow seeking if set
NoChecksum bool `config:"no_checksum"` // don't check checksums if set
ReadOnly bool `config:"read_only"` // if set VFS is read only
Links bool `config:"links"` // if set interpret link files
Links bool `config:"vfs_links"` // if set interpret link files
NoModTime bool `config:"no_modtime"` // don't read mod times for files
DirCacheTime fs.Duration `config:"dir_cache_time"` // how long to consider directory listing cache valid
Refresh bool `config:"vfs_refresh"` // refreshes the directory listing recursively on start
@ -211,6 +211,13 @@ var Opt Options
// Init the options, making sure everything is within range
func (opt *Options) Init() {
ci := fs.GetConfig(context.Background())
// Override --vfs-links with --links if set
if ci.Links {
opt.Links = true
}
// Mask the permissions with the umask
opt.DirPerms &= ^opt.Umask
opt.FilePerms &= ^opt.Umask