1
0
mirror of https://github.com/rclone/rclone.git synced 2025-12-06 00:03:32 +00:00

Compare commits

...

60 Commits

Author SHA1 Message Date
Nick Craig-Wood
89f2d43f17 Version v1.53.2 2020-10-26 13:26:58 +00:00
Nick Craig-Wood
cfc5d76fca build: stop using set-env and set-path in the GitHub actions
A security problem was discovered when using set-env and
set-path. This has been deprecated by GitHub and a new mechanism
introduced.

This patch switches to using the new mechanism which will stop GitHub
warning about the use of the old mechanism.

See: https://github.com/actions/toolkit/security/advisories/GHSA-mfwh-5m23-j46w
2020-10-26 12:51:07 +00:00
Nick Craig-Wood
0af493f693 build: work around GitHub actions brew problem
Brew was failing with

    fatal: 'origin' does not appear to be a git repository
    fatal: Could not read from remote repository.

See: https://github.com/actions/virtual-environments/issues/1811
See: https://github.com/actions/virtual-environments/issues/1869
2020-10-26 10:37:42 +00:00
Nick Craig-Wood
51b3ee9a97 test: add ListRetries config parameter to integration tests
Occasionally the b2 tests fail because the integration tests don't
retry hard enough with their new setting of -list-retries 3. Override
this setting to 5 for the b2 tests only.
2020-10-25 16:15:41 +00:00
Nick Craig-Wood
6a4b49479d union: create root directories if none exist
This fixes the TestUnion: integration test if the /tmp/union[123] dirs
don't exist.
2020-10-25 16:02:52 +00:00
Nick Craig-Wood
4b03ee0f99 test: remove TestS3Ceph: and TestSwiftCeph: from integration tests
Unfortunately we don't have access to this server any more
2020-10-25 08:48:23 +00:00
albertony
2f6231f7ac jottacloud: avoid double url escaping of device/mountpoint - fixes #4697 2020-10-22 16:52:41 +01:00
Nick Craig-Wood
c0e6f54f01 local: fix sizes and syncing with --links option on Windows - fixes #4581
Before this change rclone returned the size from the Stat call of the
link. On Windows this reads as 0 always, however on unix it reads as
the length of the text in the link. This caused errors like this when
syncing:

    Failed to copy: corrupted on transfer: sizes differ 0 vs 13

This change causes Windows platforms to read the link and use that as
the size of the link instead of 0 which fixes the problem.
2020-10-17 10:42:02 +01:00
Nick Craig-Wood
def7b77d0f vfs: Fix --no-modtime to not attempt to set modtimes (as documented)
See: https://forum.rclone.org/t/rclone-mount-with-azure-blob-archive-tier/19414
2020-10-09 17:02:13 +01:00
Nick Craig-Wood
51b18a4a26 onedrive: fix disk usage for sharepoint
Some onedrive sharepoints appear to return all 0s for quota

    "quota":{"deleted":0,"remaining":0,"total":0,"used":0}

This commit detects this and returns unknown for all quota parts.

See: https://forum.rclone.org/t/zero-size-volume-when-mounting-onedrive-sharepoint/19597
2020-10-09 14:12:29 +01:00
buengese
7cb76f9054 jottacloud: remove clientSecret from config when upgrading to token based authentication - #4645 2020-10-08 11:53:27 +02:00
Anagh Kumar Baranwal
00ccc93482 s3: Add missing regions for AWS
Signed-off-by: Anagh Kumar Baranwal <6824881+darthShadow@users.noreply.github.com>
2020-10-06 16:55:34 +01:00
Dov Murik
f9fe494d93 docs: Box: explain about the backslash-like unicode character
Add the full name of the backslash-lookalike unicode character.
2020-10-06 16:55:31 +01:00
edwardxml
4a0c266787 crypt: update docs
Mostly tense, clarity and point of view proposed changes.

There is still some duplication and benefits that would accrue from further examples.
2020-10-06 16:43:06 +01:00
gyutw
f48d0a518c fichier: increase maximum file size from 100GB to 300GB - fixes #4634 2020-10-06 16:43:06 +01:00
Russell Cattelan
99ff594773 cmd/mount2: fix the swapped UID / GID values 2020-10-06 16:43:06 +01:00
Christopher Stewart
6c140705e3 s3: fix spelling mistake
Fix spelling mistake "patific" => "pacific"
2020-10-06 16:43:06 +01:00
Leo Luan
e76963a971 vfs: Add a missed update of used cache space
The missed update can cause incorrect before-cleaning cache stats
and a pre-mature condition broadcast in purgeOld before the cache
space use is reduced below the quota.
2020-10-06 16:43:06 +01:00
Leo Luan
43ad7b10a2 vfs: Add exponential backoff during ENOSPC retries
Add an exponentially increasing delay during retries up ENOSPC error
to avoid exhausting the 10 retries too soon when the cache space
recovery from item resets is not available from the file system yet
or consumed by other large cache writes.
2020-10-06 16:43:06 +01:00
Leo Luan
f6970c65dd vfs: Fix missed concurrency control between some item operations and reset
Item reset is invoked by cache cleaner for synchronous recovery
from ENOSPC errors. The reset operation removes the cache file and
closes/reopens the downloaders.  Although most parts of reset and
other item operations are done with the item mutex held, the mutex
is released during fd.WriteAt and downloaders calls. We used preAccess
and postAccess calls to serialize Reset, ReadAt, and Open, but missed
some other item operations. The patch adds preAccess/postAccess
calls in Sync, Truncate, Close, WriteAt, and rename.
2020-10-06 16:43:06 +01:00
Leo Luan
6012179c67 vfs: Fix a race condition in retryFailedResets
A failed item reset is saved in the errItems for retryFailedResets
to process.  If the item gets closed before the retry, the item may
have been removed from the c.item array. Previous code did not
account for this condition. This patch adds the check for the
exitence of the retry items in retryFailedResets.
2020-10-06 16:43:06 +01:00
Leo Luan
3ecdd4516f vfs: Fix a deadlock vulnerability in downloaders.Close
The downloaders.Close() call acquires the downloaders' mutex before
calling the wait group wait and the main downloaders thread has a
periodical (5 seconds interval) call to kick its waiters and the
waiter dispatch function tries to get the mutex. So a deadlock can
occur if the Close() call starts, gets the mutex, while the main
downloader thread already got the timer's tick and proceeded to
call kickWaiters. The deadlock happens when the Close call gets
the mutex between the timer's kick and the main downloader thread
gets the mutex first. So it's a pretty short period of time and
it probably explains why the problem has not surfaced, maybe
something like tens of nanoseconds out of 5 seconds (~10^^-8).
It took 5 days of continued stressing the Close calls for the
deadlock to appear.
2020-10-06 16:43:06 +01:00
buengese
3b18ba1358 jottacloud: remove DirMove workaround as it's not required anymore - also fixes #4655 2020-10-05 21:32:04 +02:00
Nick Craig-Wood
5fbbab58ed operations: fix spurious "--checksum is in use but the source and destination have no hashes in common"
Before this change rclone would emit the message

    --checksum is in use but the source and destination have no hashes in common; falling back to --size-only

When the source or destination hash was missing as well as when the
source and destination had no hashes in common.

This first case is very confusing for users when the source and
destination do have a hash in common.

This change fixes that and makes sure the error message is not emitted
on missing hashes even when there is a hash in common.

See: https://forum.rclone.org/t/source-and-destination-have-no-hashes-in-common-for-unencrypted-drive-to-local-sync/19531
2020-10-05 16:08:15 +01:00
Nick Craig-Wood
80b93beedf operations: fix use of --suffix without --backup-dir
As part of the original work adding this feature it was overlooked
that this didn't actually work for full rclone copy/sync.

This commit fixes the problem and adds a test to make sure it stays
working.

See: https://forum.rclone.org/t/suffix-not-working-on-folder-upload-via-ssh-sftp/19526
2020-10-05 16:08:15 +01:00
Nick Craig-Wood
eb5c47fcfa mount: docs: remove incorrect statement about --vfs-cache-mode full
See: https://forum.rclone.org/t/is-this-documentation-correct/19376
2020-10-05 16:08:15 +01:00
Ivan Andreev
c7335e780b chunker: disable ListR to fix missing files on GDrive (workaround #3972) 2020-09-26 15:20:05 +03:00
Ivan Andreev
878ebf3658 mailru: fix invalid timestamp on corrupted files (fixes #4229) 2020-09-26 15:14:08 +03:00
Nick Craig-Wood
1c860ef252 accounting: stabilize display order of transfers on Windows
Before this change we sorted transfers in the stats list solely on
time started. However if --check-first was in use then lots of
transfers could be started in the same millisecond. Because Windows
time resolution is only 1mS this caused the entries to sort equal and
bounce around in the list.

This change fixes the sort so that if the time is equal it uses the
name which should stabilize the order.

Fixes #4599
2020-09-24 19:11:29 +01:00
buengese
a0494479f9 sftp: always convert the checksum to lower case - fixes #4518 2020-09-22 18:37:48 +02:00
Ivan Andreev
9a9a134188 Merge pull request #4608 from ivandeex/pr-chunker-crypt
chunker: fix upload over crypt (fixes #4570)
2020-09-18 18:30:30 +03:00
Ivan Andreev
41ccf01f29 mailru: re-enable fixed chunker tests
This reverts commit 9d3d397f50.
2020-09-18 18:30:24 +03:00
Ivan Andreev
06f3daa64b mailru: fix range requests after june changes on server 2020-09-18 18:30:17 +03:00
Ivan Andreev
d5fe63c0a0 mailru: fix uploads after recent changes on server
similar fix: 5efa9958f1
2020-09-18 18:30:11 +03:00
Muffin King
b7f0e776f6 seafile: fix accessing libraries > 2GB on 32 bit systems - fixes #4588 2020-09-18 10:36:52 +01:00
Nick Craig-Wood
b89f8c05cf vfs: detect and recover from a file being removed externally from the cache
Before this change if a file was removed from the cache while rclone
is running then rclone would not notice and proceed to re-create it
full of zeros.

This change notices files that we expect to have data in going missing
and if they do logs an ERROR recovers.

It isn't recommended deleting files from the cache manually with
rclone running!

See: https://forum.rclone.org/t/corrupted-data-streaming-after-vfs-meta-files-removed/18997
Fixes #4602
2020-09-18 10:36:35 +01:00
Nick Craig-Wood
b81dc16484 acounting: fix incorrect speed and transferTime in core/stats
Before this change the code which summed up the existing transfers
over all the stats groups forgot to add the old transfer time and old
transfers in.

This meant that the speed and elapsedTime got increasingly inaccurate
over time due to the transfers being culled from the list but their
time not being accounted for.

This change adds the old transfers into the sum which fixes the
problem.

This was only a problem over the rc.

Fixes #4569
2020-09-15 12:02:21 +01:00
Nick Craig-Wood
0e121eeddb Start v1.53.2-DEV development 2020-09-13 10:23:47 +01:00
Nick Craig-Wood
0430163180 Version v1.53.1 2020-09-13 09:40:14 +01:00
Evan Harris
09a0dc1600 opendrive: Do not retry 400 errors
This type of error is unlikely to be an error that can be resolved by a retry,
and is triggered in #2296 by files with a timestamp before the unix epoch.
2020-09-12 12:49:57 +01:00
Evan Harris
dd11778ac6 docs: Updated mount command to reflect that it requires Go 1.13 or newer 2020-09-12 12:49:57 +01:00
wjielai
f36cbe5194 docs: add Tencent COS to s3 provider list - fixes #4468
* add Tencent COS to s3 provider list.

Co-authored-by: wjielai <wjielai@tencent.com>
2020-09-12 12:49:57 +01:00
edwardxml
82a383588b docs: Add full stops for consistency in rclone --help
closes #4560 closes #4561 closes #4562 closes #4563 closes #4564
2020-09-12 12:49:56 +01:00
albertony
8ae4d2cffe docs/jottacloud: mention that uploads from local disk will not need to cache files to disk for md5 calculation 2020-09-12 12:48:57 +01:00
Nick Craig-Wood
0f895c0697 vfs,local: Log an ERROR if we fail to set the file to be sparse
See: https://forum.rclone.org/t/rclone-1-53-release/18880/73
2020-09-11 15:37:26 +01:00
Nick Craig-Wood
937dd7fa1f docs: note --log-file does append 2020-09-08 16:13:49 +01:00
Nick Craig-Wood
33869387d1 build: fix architecture name in ARMv7 build - fixes #4571
After introducing the arm-v7 build we are accidentally making debs
and rpms with the architecture arm-v7.

This fixes the problem by stripping the version off.
2020-09-08 16:09:52 +01:00
Nick Craig-Wood
3ec8e304b3 accounting: remove new line from end of --stats-one-line display 2020-09-08 16:09:50 +01:00
Tim Gallant
e62362094e drive: adds special oauth help test - fixes #4555 2020-09-07 12:49:30 +01:00
Nick Craig-Wood
6a0398211d build: don't explicitly set ARM version to fix ARMv5 build #4553
This partially reverts commit f71f6c57d7.
2020-09-07 12:39:39 +01:00
Nick Craig-Wood
e5a53d4c65 check: fix docs
See: https://forum.rclone.org/t/possible-issue-with-documention/18926
2020-09-07 12:12:10 +01:00
Nick Craig-Wood
59d5767a07 check: add back missing --download flag - fixes #4565
This was accidentally removed when refactoring check and cryptcheck in

8b6f2bbb4b check,cryptcheck: add reporting of filenames for same/missing/changed #3264
2020-09-05 09:31:55 +01:00
Nick Craig-Wood
087b5788e2 build: fix "Illegal instruction" error for ARMv6 builds - fixes #4553
Before this change we used `go build -i` to build the releases in parallel.

However this causes the ARMv6 and ARMv7 build to get mixed up somehow,
causing an illegal instruction when running rclone binaries on ARMv6.

See go bug: https://github.com/golang/go/issues/41223

This removes the -i which should have no effect on build times on the
CI and appears to fix the problem.
2020-09-04 16:33:22 +01:00
Nick Craig-Wood
d944bfd936 build: explicitly set ARM version to fix build #4553 2020-09-04 16:33:22 +01:00
Nick Craig-Wood
d780fcf317 docs: fix formatting of rc docs page
See: https://forum.rclone.org/t/rclone-1-53-release/18880/24
2020-09-03 11:53:53 +01:00
Nick Craig-Wood
0a9b8eac80 build: update build for stable branch 2020-09-03 11:29:33 +01:00
Nick Craig-Wood
1272a8f9a5 Start v1.53.1-DEV development 2020-09-03 11:28:43 +01:00
Nick Craig-Wood
0b40eaedaf build: include vendor tar ball in release and fix startdev 2020-09-03 10:59:17 +01:00
Nick Craig-Wood
8340ff4fb9 vfs: fix spurious error "vfs cache: failed to _ensure cache EOF"
Before this change the error message was produced for every file which
was confusing users.

After this change we check for EOF and return from ReadAt at that
point.

See: https://forum.rclone.org/t/rclone-1-53-release/18880/10
2020-09-03 10:43:41 +01:00
Nick Craig-Wood
f5abc168ed docs: fix download links 2020-09-02 17:58:07 +01:00
75 changed files with 35072 additions and 25720 deletions

View File

@@ -107,10 +107,10 @@ jobs:
- name: Set environment variables - name: Set environment variables
shell: bash shell: bash
run: | run: |
echo '::set-env name=GOTAGS::${{ matrix.gotags }}' echo 'GOTAGS=${{ matrix.gotags }}' >> $GITHUB_ENV
echo '::set-env name=BUILD_FLAGS::${{ matrix.build_flags }}' echo 'BUILD_FLAGS=${{ matrix.build_flags }}' >> $GITHUB_ENV
if [[ "${{ matrix.goarch }}" != "" ]]; then echo '::set-env name=GOARCH::${{ matrix.goarch }}' ; fi if [[ "${{ matrix.goarch }}" != "" ]]; then echo 'GOARCH=${{ matrix.goarch }}' >> $GITHUB_ENV ; fi
if [[ "${{ matrix.cgo }}" != "" ]]; then echo '::set-env name=CGO_ENABLED::${{ matrix.cgo }}' ; fi if [[ "${{ matrix.cgo }}" != "" ]]; then echo 'CGO_ENABLED=${{ matrix.cgo }}' >> $GITHUB_ENV ; fi
- name: Install Libraries on Linux - name: Install Libraries on Linux
shell: bash shell: bash
@@ -124,6 +124,8 @@ jobs:
- name: Install Libraries on macOS - name: Install Libraries on macOS
shell: bash shell: bash
run: | run: |
brew untap local/homebrew-openssl # workaround for https://github.com/actions/virtual-environments/issues/1811
brew untap local/homebrew-python2 # workaround for https://github.com/actions/virtual-environments/issues/1811
brew update brew update
brew cask install osxfuse brew cask install osxfuse
if: matrix.os == 'macOS-latest' if: matrix.os == 'macOS-latest'
@@ -133,10 +135,10 @@ jobs:
run: | run: |
$ProgressPreference = 'SilentlyContinue' $ProgressPreference = 'SilentlyContinue'
choco install -y winfsp zip choco install -y winfsp zip
Write-Host "::set-env name=CPATH::C:\Program Files\WinFsp\inc\fuse;C:\Program Files (x86)\WinFsp\inc\fuse" echo "CPATH=C:\Program Files\WinFsp\inc\fuse;C:\Program Files (x86)\WinFsp\inc\fuse" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
if ($env:GOARCH -eq "386") { if ($env:GOARCH -eq "386") {
choco install -y mingw --forcex86 --force choco install -y mingw --forcex86 --force
Write-Host "::add-path::C:\\ProgramData\\chocolatey\\lib\\mingw\\tools\\install\\mingw32\\bin" echo "C:\\ProgramData\\chocolatey\\lib\\mingw\\tools\\install\\mingw32\\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
} }
# Copy mingw32-make.exe to make.exe so the same command line # Copy mingw32-make.exe to make.exe so the same command line
# can be used on Windows as on macOS and Linux # can be used on Windows as on macOS and Linux
@@ -223,8 +225,8 @@ jobs:
- name: Set environment variables - name: Set environment variables
shell: bash shell: bash
run: | run: |
echo '::set-env name=GOPATH::${{ runner.workspace }}' echo 'GOPATH=${{ runner.workspace }}' >> $GITHUB_ENV
echo '::add-path::${{ runner.workspace }}/bin' echo '${{ runner.workspace }}/bin' >> $GITHUB_PATH
- name: Cross-compile rclone - name: Cross-compile rclone
run: | run: |

17178
MANUAL.html generated

File diff suppressed because one or more lines are too long

565
MANUAL.md generated
View File

@@ -1,6 +1,6 @@
% rclone(1) User Manual % rclone(1) User Manual
% Nick Craig-Wood % Nick Craig-Wood
% Sep 02, 2020 % Oct 26, 2020
# Rclone syncs your files to cloud storage # Rclone syncs your files to cloud storage
@@ -146,6 +146,7 @@ WebDAV or S3, that work out of the box.)
- StackPath - StackPath
- SugarSync - SugarSync
- Tardigrade - Tardigrade
- Tencent Cloud Object Storage (COS)
- Wasabi - Wasabi
- WebDAV - WebDAV
- Yandex Disk - Yandex Disk
@@ -503,7 +504,7 @@ See the [global flags page](https://rclone.org/flags/) for global options not li
# rclone copy # rclone copy
Copy files from source to dest, skipping already copied Copy files from source to dest, skipping already copied.
## Synopsis ## Synopsis
@@ -833,7 +834,7 @@ the source match the files in the destination, not the other way
around. This means that extra files in the destination that are not in around. This means that extra files in the destination that are not in
the source will not be detected. the source will not be detected.
The `--differ`, `--missing-on-dst`, `--missing-on-src`, `--src-only` The `--differ`, `--missing-on-dst`, `--missing-on-src`, `--match`
and `--error` flags write paths, one per line, to the file name (or and `--error` flags write paths, one per line, to the file name (or
stdout if it is `-`) supplied. What they write is described in the stdout if it is `-`) supplied. What they write is described in the
help below. For example `--differ` will write all paths which are help below. For example `--differ` will write all paths which are
@@ -859,6 +860,7 @@ rclone check source:path dest:path [flags]
``` ```
--combined string Make a combined report of changes to this file --combined string Make a combined report of changes to this file
--differ string Report all non-matching files to this file --differ string Report all non-matching files to this file
--download Check by downloading rather than with hash.
--error string Report all files with errors (hashing or reading) to this file --error string Report all files with errors (hashing or reading) to this file
-h, --help help for check -h, --help help for check
--match string Report all matching files to this file --match string Report all matching files to this file
@@ -1191,7 +1193,7 @@ See the [global flags page](https://rclone.org/flags/) for global options not li
# rclone cleanup # rclone cleanup
Clean up the remote if possible Clean up the remote if possible.
## Synopsis ## Synopsis
@@ -1915,7 +1917,7 @@ See the [global flags page](https://rclone.org/flags/) for global options not li
# rclone copyto # rclone copyto
Copy files from source to dest, skipping already copied Copy files from source to dest, skipping already copied.
## Synopsis ## Synopsis
@@ -2040,7 +2042,7 @@ the source match the files in the destination, not the other way
around. This means that extra files in the destination that are not in around. This means that extra files in the destination that are not in
the source will not be detected. the source will not be detected.
The `--differ`, `--missing-on-dst`, `--missing-on-src`, `--src-only` The `--differ`, `--missing-on-dst`, `--missing-on-src`, `--match`
and `--error` flags write paths, one per line, to the file name (or and `--error` flags write paths, one per line, to the file name (or
stdout if it is `-`) supplied. What they write is described in the stdout if it is `-`) supplied. What they write is described in the
help below. For example `--differ` will write all paths which are help below. For example `--differ` will write all paths which are
@@ -2434,7 +2436,7 @@ See the [global flags page](https://rclone.org/flags/) for global options not li
# rclone lsf # rclone lsf
List directories and objects in remote:path formatted for parsing List directories and objects in remote:path formatted for parsing.
## Synopsis ## Synopsis
@@ -2744,6 +2746,9 @@ Stopping the mount manually:
# OS X # OS X
umount /path/to/local/mount umount /path/to/local/mount
**Note**: As of `rclone` 1.52.2, `rclone mount` now requires Go version 1.13
or newer on some platforms depending on the underlying FUSE library in use.
## Installing on Windows ## Installing on Windows
To run rclone mount on Windows, you will need to To run rclone mount on Windows, you will need to
@@ -2886,9 +2891,6 @@ parts will be downloaded: 0-100M, 100M-200M, 200M-300M, 300M-400M and so on.
When --vfs-read-chunk-size-limit 500M is specified, the result would be When --vfs-read-chunk-size-limit 500M is specified, the result would be
0-100M, 100M-300M, 300M-700M, 700M-1200M, 1200M-1700M and so on. 0-100M, 100M-300M, 300M-700M, 700M-1200M, 1200M-1700M and so on.
Chunked reading will only work with --vfs-cache-mode < full, as the file will always
be copied to the vfs cache before opening with --vfs-cache-mode full.
## VFS - Virtual File System ## VFS - Virtual File System
This command uses the VFS layer. This adapts the cloud storage objects This command uses the VFS layer. This adapts the cloud storage objects
@@ -3052,6 +3054,11 @@ whereas the --vfs-read-ahead is buffered on disk.
When using this mode it is recommended that --buffer-size is not set When using this mode it is recommended that --buffer-size is not set
too big and --vfs-read-ahead is set large if required. too big and --vfs-read-ahead is set large if required.
**IMPORTANT** not all file systems support sparse files. In particular
FAT/exFAT do not. Rclone will perform very badly if the cache
directory is on a filesystem which doesn't support sparse files and it
will log an ERROR message if one is detected.
## VFS Performance ## VFS Performance
These flags may be used to enable/disable features of the VFS for These flags may be used to enable/disable features of the VFS for
@@ -3289,7 +3296,7 @@ See the [global flags page](https://rclone.org/flags/) for global options not li
# rclone obscure # rclone obscure
Obscure password for use in the rclone config file Obscure password for use in the rclone config file.
## Synopsis ## Synopsis
@@ -3754,6 +3761,11 @@ whereas the --vfs-read-ahead is buffered on disk.
When using this mode it is recommended that --buffer-size is not set When using this mode it is recommended that --buffer-size is not set
too big and --vfs-read-ahead is set large if required. too big and --vfs-read-ahead is set large if required.
**IMPORTANT** not all file systems support sparse files. In particular
FAT/exFAT do not. Rclone will perform very badly if the cache
directory is on a filesystem which doesn't support sparse files and it
will log an ERROR message if one is detected.
## VFS Performance ## VFS Performance
These flags may be used to enable/disable features of the VFS for These flags may be used to enable/disable features of the VFS for
@@ -4056,6 +4068,11 @@ whereas the --vfs-read-ahead is buffered on disk.
When using this mode it is recommended that --buffer-size is not set When using this mode it is recommended that --buffer-size is not set
too big and --vfs-read-ahead is set large if required. too big and --vfs-read-ahead is set large if required.
**IMPORTANT** not all file systems support sparse files. In particular
FAT/exFAT do not. Rclone will perform very badly if the cache
directory is on a filesystem which doesn't support sparse files and it
will log an ERROR message if one is detected.
## VFS Performance ## VFS Performance
These flags may be used to enable/disable features of the VFS for These flags may be used to enable/disable features of the VFS for
@@ -4514,6 +4531,11 @@ whereas the --vfs-read-ahead is buffered on disk.
When using this mode it is recommended that --buffer-size is not set When using this mode it is recommended that --buffer-size is not set
too big and --vfs-read-ahead is set large if required. too big and --vfs-read-ahead is set large if required.
**IMPORTANT** not all file systems support sparse files. In particular
FAT/exFAT do not. Rclone will perform very badly if the cache
directory is on a filesystem which doesn't support sparse files and it
will log an ERROR message if one is detected.
## VFS Performance ## VFS Performance
These flags may be used to enable/disable features of the VFS for These flags may be used to enable/disable features of the VFS for
@@ -5035,6 +5057,11 @@ whereas the --vfs-read-ahead is buffered on disk.
When using this mode it is recommended that --buffer-size is not set When using this mode it is recommended that --buffer-size is not set
too big and --vfs-read-ahead is set large if required. too big and --vfs-read-ahead is set large if required.
**IMPORTANT** not all file systems support sparse files. In particular
FAT/exFAT do not. Rclone will perform very badly if the cache
directory is on a filesystem which doesn't support sparse files and it
will log an ERROR message if one is detected.
## VFS Performance ## VFS Performance
These flags may be used to enable/disable features of the VFS for These flags may be used to enable/disable features of the VFS for
@@ -5502,6 +5529,11 @@ whereas the --vfs-read-ahead is buffered on disk.
When using this mode it is recommended that --buffer-size is not set When using this mode it is recommended that --buffer-size is not set
too big and --vfs-read-ahead is set large if required. too big and --vfs-read-ahead is set large if required.
**IMPORTANT** not all file systems support sparse files. In particular
FAT/exFAT do not. Rclone will perform very badly if the cache
directory is on a filesystem which doesn't support sparse files and it
will log an ERROR message if one is detected.
## VFS Performance ## VFS Performance
These flags may be used to enable/disable features of the VFS for These flags may be used to enable/disable features of the VFS for
@@ -6502,6 +6534,8 @@ This can be useful for tracking down problems with syncs in
combination with the `-v` flag. See the [Logging section](#logging) combination with the `-v` flag. See the [Logging section](#logging)
for more info. for more info.
If FILE exists then rclone will append to it.
Note that if you are using the `logrotate` program to manage rclone's Note that if you are using the `logrotate` program to manage rclone's
logs, then you should use the `copytruncate` option as rclone doesn't logs, then you should use the `copytruncate` option as rclone doesn't
have a signal to rotate logs. have a signal to rotate logs.
@@ -6996,11 +7030,17 @@ or with `--backup-dir`. See `--backup-dir` for more info.
For example For example
rclone sync -i /path/to/local/file remote:current --suffix .bak rclone copy -i /path/to/local/file remote:current --suffix .bak
will sync `/path/to/local` to `remote:current`, but for any files will copy `/path/to/local` to `remote:current`, but for any files
which would have been updated or deleted have .bak added. which would have been updated or deleted have .bak added.
If using `rclone sync` with `--suffix` and without `--backup-dir` then
it is recommended to put a filter rule in excluding the suffix
otherwise the `sync` will delete the backup files.
rclone sync -i /path/to/local/file remote:current --suffix .bak --exclude "*.bak"
### --suffix-keep-extension ### ### --suffix-keep-extension ###
When using `--suffix`, setting this causes rclone put the SUFFIX When using `--suffix`, setting this causes rclone put the SUFFIX
@@ -8893,6 +8933,8 @@ OR
"result": "<Raw command line output>" "result": "<Raw command line output>"
} }
```
**Authentication is required for this call.** **Authentication is required for this call.**
### core/gc: Runs a garbage collection. {#core-gc} ### core/gc: Runs a garbage collection. {#core-gc}
@@ -9568,7 +9610,7 @@ This allows you to remove a plugin using it's name
This takes parameters This takes parameters
- name: name of the plugin in the format <author>/<plugin_name> - name: name of the plugin in the format `author`/`plugin_name`
Eg Eg
@@ -9582,7 +9624,7 @@ This allows you to remove a plugin using it's name
This takes the following parameters This takes the following parameters
- name: name of the plugin in the format <author>/<plugin_name> - name: name of the plugin in the format `author`/`plugin_name`
Eg Eg
@@ -10527,7 +10569,7 @@ These flags are available for every command.
--use-json-log Use json log format. --use-json-log Use json log format.
--use-mmap Use mmap allocator (see docs). --use-mmap Use mmap allocator (see docs).
--use-server-modtime Use server modified time instead of object metadata --use-server-modtime Use server modified time instead of object metadata
--user-agent string Set the user-agent to a specified string. The default is rclone/ version (default "rclone/v1.53.0") --user-agent string Set the user-agent to a specified string. The default is rclone/ version (default "rclone/v1.53.2")
-v, --verbose count Print lots more stuff (repeat for more) -v, --verbose count Print lots more stuff (repeat for more)
``` ```
@@ -10626,7 +10668,7 @@ and may be set in the config file.
--drive-auth-owner-only Only consider files owned by the authenticated user. --drive-auth-owner-only Only consider files owned by the authenticated user.
--drive-auth-url string Auth server URL. --drive-auth-url string Auth server URL.
--drive-chunk-size SizeSuffix Upload chunk size. Must a power of 2 >= 256k. (default 8M) --drive-chunk-size SizeSuffix Upload chunk size. Must a power of 2 >= 256k. (default 8M)
--drive-client-id string OAuth Client Id --drive-client-id string Google Application Client Id
--drive-client-secret string OAuth Client Secret --drive-client-secret string OAuth Client Secret
--drive-disable-http2 Disable drive using http2 (default true) --drive-disable-http2 Disable drive using http2 (default true)
--drive-encoding MultiEncoder This sets the encoding for the backend. (default InvalidUtf8) --drive-encoding MultiEncoder This sets the encoding for the backend. (default InvalidUtf8)
@@ -11475,6 +11517,7 @@ The S3 backend can be used with a number of different providers:
- Minio - Minio
- Scaleway - Scaleway
- StackPath - StackPath
- Tencent Cloud Object Storage (COS)
- Wasabi - Wasabi
@@ -11595,7 +11638,7 @@ Choose a number from below, or type in your own value
/ Asia Pacific (Mumbai) / Asia Pacific (Mumbai)
13 | Needs location constraint ap-south-1. 13 | Needs location constraint ap-south-1.
\ "ap-south-1" \ "ap-south-1"
/ Asia Patific (Hong Kong) Region / Asia Pacific (Hong Kong) Region
14 | Needs location constraint ap-east-1. 14 | Needs location constraint ap-east-1.
\ "ap-east-1" \ "ap-east-1"
/ South America (Sao Paulo) Region / South America (Sao Paulo) Region
@@ -11912,7 +11955,7 @@ Vault API, so rclone cannot directly access Glacier Vaults.
### Standard Options ### Standard Options
Here are the standard options specific to s3 (Amazon S3 Compliant Storage Provider (AWS, Alibaba, Ceph, Digital Ocean, Dreamhost, IBM COS, Minio, etc)). Here are the standard options specific to s3 (Amazon S3 Compliant Storage Provider (AWS, Alibaba, Ceph, Digital Ocean, Dreamhost, IBM COS, Minio, Tencent COS, etc)).
#### --s3-provider #### --s3-provider
@@ -11943,6 +11986,8 @@ Choose your S3 provider.
- Scaleway Object Storage - Scaleway Object Storage
- "StackPath" - "StackPath"
- StackPath Object Storage - StackPath Object Storage
- "TencentCOS"
- Tencent Cloud Object Storage (COS)
- "Wasabi" - "Wasabi"
- Wasabi Object Storage - Wasabi Object Storage
- "Other" - "Other"
@@ -11999,12 +12044,12 @@ Region to connect to.
- "us-east-2" - "us-east-2"
- US East (Ohio) Region - US East (Ohio) Region
- Needs location constraint us-east-2. - Needs location constraint us-east-2.
- "us-west-2"
- US West (Oregon) Region
- Needs location constraint us-west-2.
- "us-west-1" - "us-west-1"
- US West (Northern California) Region - US West (Northern California) Region
- Needs location constraint us-west-1. - Needs location constraint us-west-1.
- "us-west-2"
- US West (Oregon) Region
- Needs location constraint us-west-2.
- "ca-central-1" - "ca-central-1"
- Canada (Central) Region - Canada (Central) Region
- Needs location constraint ca-central-1. - Needs location constraint ca-central-1.
@@ -12014,9 +12059,15 @@ Region to connect to.
- "eu-west-2" - "eu-west-2"
- EU (London) Region - EU (London) Region
- Needs location constraint eu-west-2. - Needs location constraint eu-west-2.
- "eu-west-3"
- EU (Paris) Region
- Needs location constraint eu-west-3.
- "eu-north-1" - "eu-north-1"
- EU (Stockholm) Region - EU (Stockholm) Region
- Needs location constraint eu-north-1. - Needs location constraint eu-north-1.
- "eu-south-1"
- EU (Milan) Region
- Needs location constraint eu-south-1.
- "eu-central-1" - "eu-central-1"
- EU (Frankfurt) Region - EU (Frankfurt) Region
- Needs location constraint eu-central-1. - Needs location constraint eu-central-1.
@@ -12032,15 +12083,36 @@ Region to connect to.
- "ap-northeast-2" - "ap-northeast-2"
- Asia Pacific (Seoul) - Asia Pacific (Seoul)
- Needs location constraint ap-northeast-2. - Needs location constraint ap-northeast-2.
- "ap-northeast-3"
- Asia Pacific (Osaka-Local)
- Needs location constraint ap-northeast-3.
- "ap-south-1" - "ap-south-1"
- Asia Pacific (Mumbai) - Asia Pacific (Mumbai)
- Needs location constraint ap-south-1. - Needs location constraint ap-south-1.
- "ap-east-1" - "ap-east-1"
- Asia Patific (Hong Kong) Region - Asia Pacific (Hong Kong) Region
- Needs location constraint ap-east-1. - Needs location constraint ap-east-1.
- "sa-east-1" - "sa-east-1"
- South America (Sao Paulo) Region - South America (Sao Paulo) Region
- Needs location constraint sa-east-1. - Needs location constraint sa-east-1.
- "me-south-1"
- Middle East (Bahrain) Region
- Needs location constraint me-south-1.
- "af-south-1"
- Africa (Cape Town) Region
- Needs location constraint af-south-1.
- "cn-north-1"
- China (Beijing) Region
- Needs location constraint cn-north-1.
- "cn-northwest-1"
- China (Ningxia) Region
- Needs location constraint cn-northwest-1.
- "us-gov-east-1"
- AWS GovCloud (US-East) Region
- Needs location constraint us-gov-east-1.
- "us-gov-west-1"
- AWS GovCloud (US) Region
- Needs location constraint us-gov-west-1.
#### --s3-region #### --s3-region
@@ -12296,6 +12368,54 @@ Endpoint for StackPath Object Storage.
#### --s3-endpoint #### --s3-endpoint
Endpoint for Tencent COS API.
- Config: endpoint
- Env Var: RCLONE_S3_ENDPOINT
- Type: string
- Default: ""
- Examples:
- "cos.ap-beijing.myqcloud.com"
- Beijing Region.
- "cos.ap-nanjing.myqcloud.com"
- Nanjing Region.
- "cos.ap-shanghai.myqcloud.com"
- Shanghai Region.
- "cos.ap-guangzhou.myqcloud.com"
- Guangzhou Region.
- "cos.ap-nanjing.myqcloud.com"
- Nanjing Region.
- "cos.ap-chengdu.myqcloud.com"
- Chengdu Region.
- "cos.ap-chongqing.myqcloud.com"
- Chongqing Region.
- "cos.ap-hongkong.myqcloud.com"
- Hong Kong (China) Region.
- "cos.ap-singapore.myqcloud.com"
- Singapore Region.
- "cos.ap-mumbai.myqcloud.com"
- Mumbai Region.
- "cos.ap-seoul.myqcloud.com"
- Seoul Region.
- "cos.ap-bangkok.myqcloud.com"
- Bangkok Region.
- "cos.ap-tokyo.myqcloud.com"
- Tokyo Region.
- "cos.na-siliconvalley.myqcloud.com"
- Silicon Valley Region.
- "cos.na-ashburn.myqcloud.com"
- Virginia Region.
- "cos.na-toronto.myqcloud.com"
- Toronto Region.
- "cos.eu-frankfurt.myqcloud.com"
- Frankfurt Region.
- "cos.eu-moscow.myqcloud.com"
- Moscow Region.
- "cos.accelerate.myqcloud.com"
- Use Tencent COS Accelerate Endpoint.
#### --s3-endpoint
Endpoint for S3 API. Endpoint for S3 API.
Required when using an S3 clone. Required when using an S3 clone.
@@ -12333,18 +12453,22 @@ Used when creating buckets only.
- Empty for US Region, Northern Virginia or Pacific Northwest. - Empty for US Region, Northern Virginia or Pacific Northwest.
- "us-east-2" - "us-east-2"
- US East (Ohio) Region. - US East (Ohio) Region.
- "us-west-2"
- US West (Oregon) Region.
- "us-west-1" - "us-west-1"
- US West (Northern California) Region. - US West (Northern California) Region.
- "us-west-2"
- US West (Oregon) Region.
- "ca-central-1" - "ca-central-1"
- Canada (Central) Region. - Canada (Central) Region.
- "eu-west-1" - "eu-west-1"
- EU (Ireland) Region. - EU (Ireland) Region.
- "eu-west-2" - "eu-west-2"
- EU (London) Region. - EU (London) Region.
- "eu-west-3"
- EU (Paris) Region.
- "eu-north-1" - "eu-north-1"
- EU (Stockholm) Region. - EU (Stockholm) Region.
- "eu-south-1"
- EU (Milan) Region.
- "EU" - "EU"
- EU Region. - EU Region.
- "ap-southeast-1" - "ap-southeast-1"
@@ -12354,13 +12478,27 @@ Used when creating buckets only.
- "ap-northeast-1" - "ap-northeast-1"
- Asia Pacific (Tokyo) Region. - Asia Pacific (Tokyo) Region.
- "ap-northeast-2" - "ap-northeast-2"
- Asia Pacific (Seoul) - Asia Pacific (Seoul) Region.
- "ap-northeast-3"
- Asia Pacific (Osaka-Local) Region.
- "ap-south-1" - "ap-south-1"
- Asia Pacific (Mumbai) - Asia Pacific (Mumbai) Region.
- "ap-east-1" - "ap-east-1"
- Asia Pacific (Hong Kong) - Asia Pacific (Hong Kong) Region.
- "sa-east-1" - "sa-east-1"
- South America (Sao Paulo) Region. - South America (Sao Paulo) Region.
- "me-south-1"
- Middle East (Bahrain) Region.
- "af-south-1"
- Africa (Cape Town) Region.
- "cn-north-1"
- China (Beijing) Region
- "cn-northwest-1"
- China (Ningxia) Region.
- "us-gov-east-1"
- AWS GovCloud (US-East) Region.
- "us-gov-west-1"
- AWS GovCloud (US) Region.
#### --s3-location-constraint #### --s3-location-constraint
@@ -12463,6 +12601,8 @@ doesn't copy the ACL from the source but rather writes a fresh one.
- Type: string - Type: string
- Default: "" - Default: ""
- Examples: - Examples:
- "default"
- Owner gets Full_CONTROL. No one else has access rights (default).
- "private" - "private"
- Owner gets FULL_CONTROL. No one else has access rights (default). - Owner gets FULL_CONTROL. No one else has access rights (default).
- "public-read" - "public-read"
@@ -12563,6 +12703,24 @@ The storage class to use when storing new objects in OSS.
#### --s3-storage-class #### --s3-storage-class
The storage class to use when storing new objects in Tencent COS.
- Config: storage_class
- Env Var: RCLONE_S3_STORAGE_CLASS
- Type: string
- Default: ""
- Examples:
- ""
- Default
- "STANDARD"
- Standard storage class
- "ARCHIVE"
- Archive storage mode.
- "STANDARD_IA"
- Infrequent access storage mode.
#### --s3-storage-class
The storage class to use when storing new objects in S3. The storage class to use when storing new objects in S3.
- Config: storage_class - Config: storage_class
@@ -12579,7 +12737,7 @@ The storage class to use when storing new objects in S3.
### Advanced Options ### Advanced Options
Here are the advanced options specific to s3 (Amazon S3 Compliant Storage Provider (AWS, Alibaba, Ceph, Digital Ocean, Dreamhost, IBM COS, Minio, etc)). Here are the advanced options specific to s3 (Amazon S3 Compliant Storage Provider (AWS, Alibaba, Ceph, Digital Ocean, Dreamhost, IBM COS, Minio, Tencent COS, etc)).
#### --s3-bucket-acl #### --s3-bucket-acl
@@ -12800,7 +12958,7 @@ if false then rclone will use virtual path style. See [the AWS S3
docs](https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingBucket.html#access-bucket-intro) docs](https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingBucket.html#access-bucket-intro)
for more info. for more info.
Some providers (eg AWS, Aliyun OSS or Netease COS) require this set to Some providers (eg AWS, Aliyun OSS, Netease COS or Tencent COS) require this set to
false - rclone will do this automatically based on the provider false - rclone will do this automatically based on the provider
setting. setting.
@@ -13669,6 +13827,138 @@ d) Delete this remote
y/e/d> y y/e/d> y
``` ```
### Tencent COS {#tencent-cos}
[Tencent Cloud Object Storage (COS)](https://intl.cloud.tencent.com/product/cos) is a distributed storage service offered by Tencent Cloud for unstructured data. It is secure, stable, massive, convenient, low-delay and low-cost.
To configure access to Tencent COS, follow the steps below:
1. Run `rclone config` and select `n` for a new remote.
```
rclone config
No remotes found - make a new one
n) New remote
s) Set configuration password
q) Quit config
n/s/q> n
```
2. Give the name of the configuration. For example, name it 'cos'.
```
name> cos
```
3. Select `s3` storage.
```
Choose a number from below, or type in your own value
1 / 1Fichier
\ "fichier"
2 / Alias for an existing remote
\ "alias"
3 / Amazon Drive
\ "amazon cloud drive"
4 / Amazon S3 Compliant Storage Provider (AWS, Alibaba, Ceph, Digital Ocean, Dreamhost, IBM COS, Minio, Tencent COS, etc)
\ "s3"
[snip]
Storage> s3
```
4. Select `TencentCOS` provider.
```
Choose a number from below, or type in your own value
1 / Amazon Web Services (AWS) S3
\ "AWS"
[snip]
11 / Tencent Cloud Object Storage (COS)
\ "TencentCOS"
[snip]
provider> TencentCOS
```
5. Enter your SecretId and SecretKey of Tencent Cloud.
```
Get AWS credentials from runtime (environment variables or EC2/ECS meta data if no env vars).
Only applies if access_key_id and secret_access_key is blank.
Enter a boolean value (true or false). Press Enter for the default ("false").
Choose a number from below, or type in your own value
1 / Enter AWS credentials in the next step
\ "false"
2 / Get AWS credentials from the environment (env vars or IAM)
\ "true"
env_auth> 1
AWS Access Key ID.
Leave blank for anonymous access or runtime credentials.
Enter a string value. Press Enter for the default ("").
access_key_id> AKIDxxxxxxxxxx
AWS Secret Access Key (password)
Leave blank for anonymous access or runtime credentials.
Enter a string value. Press Enter for the default ("").
secret_access_key> xxxxxxxxxxx
```
6. Select endpoint for Tencent COS. This is the standard endpoint for different region.
```
1 / Beijing Region.
\ "cos.ap-beijing.myqcloud.com"
2 / Nanjing Region.
\ "cos.ap-nanjing.myqcloud.com"
3 / Shanghai Region.
\ "cos.ap-shanghai.myqcloud.com"
4 / Guangzhou Region.
\ "cos.ap-guangzhou.myqcloud.com"
[snip]
endpoint> 4
```
7. Choose acl and storage class.
```
Note that this ACL is applied when server side copying objects as S3
doesn't copy the ACL from the source but rather writes a fresh one.
Enter a string value. Press Enter for the default ("").
Choose a number from below, or type in your own value
1 / Owner gets Full_CONTROL. No one else has access rights (default).
\ "default"
[snip]
acl> 1
The storage class to use when storing new objects in Tencent COS.
Enter a string value. Press Enter for the default ("").
Choose a number from below, or type in your own value
1 / Default
\ ""
[snip]
storage_class> 1
Edit advanced config? (y/n)
y) Yes
n) No (default)
y/n> n
Remote config
--------------------
[cos]
type = s3
provider = TencentCOS
env_auth = false
access_key_id = xxx
secret_access_key = xxx
endpoint = cos.ap-guangzhou.myqcloud.com
acl = default
--------------------
y) Yes this is OK (default)
e) Edit this remote
d) Delete this remote
y/e/d> y
Current remotes:
Name Type
==== ====
cos s3
```
### Netease NOS ### ### Netease NOS ###
For Netease NOS configure as per the configurator `rclone config` For Netease NOS configure as per the configurator `rclone config`
@@ -14587,7 +14877,8 @@ Note that Box is case insensitive so you can't have a file called
"Hello.doc" and one called "hello.doc". "Hello.doc" and one called "hello.doc".
Box file names can't have the `\` character in. rclone maps this to Box file names can't have the `\` character in. rclone maps this to
and from an identical looking unicode equivalent ``. and from an identical looking unicode equivalent `` (U+FF3C Fullwidth
Reverse Solidus).
Box only supports filenames up to 255 characters in length. Box only supports filenames up to 255 characters in length.
@@ -15869,23 +16160,26 @@ See: the [encoding section in the overview](https://rclone.org/overview/#encodin
Crypt Crypt
---------------------------------------- ----------------------------------------
The `crypt` remote encrypts and decrypts another remote. Rclone `crypt` remotes encrypt and decrypt other remotes.
To use it first set up the underlying remote following the config To use `crypt`, first set up the underlying remote. Follow the `rclone
instructions for that remote. You can also use a local pathname config` instructions for that remote.
instead of a remote which will encrypt and decrypt from that directory
which might be useful for encrypting onto a USB stick for example.
First check your chosen remote is working - we'll call it `crypt` applied to a local pathname instead of a remote will
`remote:path` in these docs. Note that anything inside `remote:path` encrypt and decrypt that directory, and can be used to encrypt USB
will be encrypted and anything outside won't. This means that if you removable drives.
are using a bucket based remote (eg S3, B2, swift) then you should
probably put the bucket in the remote `s3:bucket`. If you just use
`s3:` then rclone will make encrypted bucket names too (if using file
name encryption) which may or may not be what you want.
Now configure `crypt` using `rclone config`. We will call this one Before configuring the crypt remote, check the underlying remote is
`secret` to differentiate it from the `remote`. working. In this example the underlying remote is called `remote:path`.
Anything inside `remote:path` will be encrypted and anything outside
will not. In the case of an S3 based underlying remote (eg Amazon S3,
B2, Swift) it is generally advisable to define a crypt remote in the
underlying remote `s3:bucket`. If `s3:` alone is specified alongside
file name encryption, rclone will encrypt the bucket name.
Configure `crypt` using `rclone config`. In this example the `crypt`
remote is called `secret`, to differentiate it from the underlying
`remote`.
``` ```
No remotes found - make a new one No remotes found - make a new one
@@ -15959,49 +16253,42 @@ d) Delete this remote
y/e/d> y y/e/d> y
``` ```
**Important** The password is stored in the config file is lightly **Important** The crypt password stored in `rclone.conf` is lightly
obscured so it isn't immediately obvious what it is. It is in no way obscured. That only protects it from cursory inspection. It is not
secure unless you use config file encryption. secure unless encryption of `rclone.conf` is specified.
A long passphrase is recommended, or you can use a random one. A long passphrase is recommended, or `rclone config` can generate a
random one.
The obscured password is created by using AES-CTR with a static key, with The obscured password is created using AES-CTR with a static key. The
the salt stored verbatim at the beginning of the obscured password. This salt is stored verbatim at the beginning of the obscured password. This
static key is shared by between all versions of rclone. static key is shared between all versions of rclone.
If you reconfigure rclone with the same passwords/passphrases If you reconfigure rclone with the same passwords/passphrases
elsewhere it will be compatible, but the obscured version will be different elsewhere it will be compatible, but the obscured version will be different
due to the different salt. due to the different salt.
Note that rclone does not encrypt Rclone does not encrypt
* file length - this can be calculated within 16 bytes * file length - this can be calculated within 16 bytes
* modification time - used for syncing * modification time - used for syncing
## Specifying the remote ## ## Specifying the remote ##
In normal use, make sure the remote has a `:` in. If you specify the In normal use, ensure the remote has a `:` in. If specified without,
remote without a `:` then rclone will use a local directory of that rclone uses a local directory of that name. For example if a remote
name. So if you use a remote of `/path/to/secret/files` then rclone `/path/to/secret/files` is specified, rclone encrypts content to that
will encrypt stuff to that directory. If you use a remote of `name` directory. If a remote `name` is specified, rclone targets a directory
then rclone will put files in a directory called `name` in the current `name` in the current directory.
directory.
If you specify the remote as `remote:path/to/dir` then rclone will If remote `remote:path/to/dir` is specified, rclone stores encrypted
store encrypted files in `path/to/dir` on the remote. If you are using files in `path/to/dir` on the remote. With file name encryption, files
file name encryption, then when you save files to saved to `secret:subdir/subfile` are stored in the unencrypted path
`secret:subdir/subfile` this will store them in the unencrypted path `path/to/dir` but the `subdir/subpath` element is encrypted.
`path/to/dir` but the `subdir/subpath` bit will be encrypted.
Note that unless you want encrypted bucket names (which are difficult
to manage because you won't know what directory they represent in web
interfaces etc), you should probably specify a bucket, eg
`remote:secretbucket` when using bucket based remotes such as S3,
Swift, Hubic, B2, GCS.
## Example ## ## Example ##
To test I made a little directory of files using "standard" file name Create the following file structure using "standard" file name
encryption. encryption.
``` ```
@@ -16015,7 +16302,7 @@ plaintext/
└── file4.txt └── file4.txt
``` ```
Copy these to the remote and list them back Copy these to the remote, and list them
``` ```
$ rclone -q copy plaintext secret: $ rclone -q copy plaintext secret:
@@ -16027,7 +16314,7 @@ $ rclone -q ls secret:
9 subdir/file3.txt 9 subdir/file3.txt
``` ```
Now see what that looked like when encrypted The crypt remote looks like
``` ```
$ rclone -q ls remote:path $ rclone -q ls remote:path
@@ -16038,7 +16325,7 @@ $ rclone -q ls remote:path
56 86vhrsv86mpbtd3a0akjuqslj8/8njh1sk437gttmep3p70g81aps 56 86vhrsv86mpbtd3a0akjuqslj8/8njh1sk437gttmep3p70g81aps
``` ```
Note that this retains the directory structure which means you can do this The directory structure is preserved
``` ```
$ rclone -q ls secret:subdir $ rclone -q ls secret:subdir
@@ -16047,9 +16334,9 @@ $ rclone -q ls secret:subdir
10 subsubdir/file4.txt 10 subsubdir/file4.txt
``` ```
If don't use file name encryption then the remote will look like this Without file name encryption `.bin` extensions are added to underlying
- note the `.bin` extensions added to prevent the cloud provider names. This prevents the cloud provider attempting to interpret file
attempting to interpret the data. content.
``` ```
$ rclone -q ls remote:path $ rclone -q ls remote:path
@@ -16062,8 +16349,6 @@ $ rclone -q ls remote:path
### File name encryption modes ### ### File name encryption modes ###
Here are some of the features of the file name encryption modes
Off Off
* doesn't hide file names or directory structure * doesn't hide file names or directory structure
@@ -16082,17 +16367,19 @@ Standard
Obfuscation Obfuscation
This is a simple "rotate" of the filename, with each file having a rot This is a simple "rotate" of the filename, with each file having a rot
distance based on the filename. We store the distance at the beginning distance based on the filename. Rclone stores the distance at the
of the filename. So a file called "hello" may become "53.jgnnq". beginning of the filename. A file called "hello" may become "53.jgnnq".
This is not a strong encryption of filenames, but it may stop automated Obfuscation is not a strong encryption of filenames, but hinders
scanning tools from picking up on filename patterns. As such it's an automated scanning tools picking up on filename patterns. It is an
intermediate between "off" and "standard". The advantage is that it intermediate between "off" and "standard" which allows for longer path
allows for longer path segment names. segment names.
There is a possibility with some unicode based filenames that the There is a possibility with some unicode based filenames that the
obfuscation is weak and may map lower case characters to upper case obfuscation is weak and may map lower case characters to upper case
equivalents. You can not rely on this for strong protection. equivalents.
Obfuscation cannot be relied upon for strong protection.
* file names very lightly obfuscated * file names very lightly obfuscated
* file names can be longer than standard encryption * file names can be longer than standard encryption
@@ -16100,13 +16387,14 @@ equivalents. You can not rely on this for strong protection.
* directory structure visible * directory structure visible
* identical files names will have identical uploaded names * identical files names will have identical uploaded names
Cloud storage systems have various limits on file name length and Cloud storage systems have limits on file name length and
total path length which you are more likely to hit using "Standard" total path length which rclone is more likely to breach using
file name encryption. If you keep your file names to below 156 "Standard" file name encryption. Where file names are less thn 156
characters in length then you should be OK on all providers. characters in length issues should not be encountered, irrespective of
cloud storage provider.
There may be an even more secure file name encryption mode in the An alternative, future rclone file name encryption mode may tolerate
future which will address the long file name problem. backend provider path length limits.
### Directory name encryption ### ### Directory name encryption ###
Crypt offers the option of encrypting dir names or leaving them intact. Crypt offers the option of encrypting dir names or leaving them intact.
@@ -16135,7 +16423,7 @@ depends on that.
Hashes are not stored for crypt. However the data integrity is Hashes are not stored for crypt. However the data integrity is
protected by an extremely strong crypto authenticator. protected by an extremely strong crypto authenticator.
Note that you should use the `rclone cryptcheck` command to check the Use the `rclone cryptcheck` command to check the
integrity of a crypted remote instead of `rclone check` which can't integrity of a crypted remote instead of `rclone check` which can't
check the checksums properly. check the checksums properly.
@@ -17997,8 +18285,10 @@ Here are the standard options specific to drive (Google Drive).
#### --drive-client-id #### --drive-client-id
OAuth Client Id Google Application Client Id
Leave blank normally. Setting your own is recommended.
See https://rclone.org/drive/#making-your-own-client-id for how to create your own.
If you leave this blank, it will use an internal key which is low performance.
- Config: client_id - Config: client_id
- Env Var: RCLONE_DRIVE_CLIENT_ID - Env Var: RCLONE_DRIVE_CLIENT_ID
@@ -19690,6 +19980,11 @@ source does not have an MD5 checksum then the file will be cached
temporarily on disk (wherever the `TMPDIR` environment variable points temporarily on disk (wherever the `TMPDIR` environment variable points
to) before it is uploaded. Small files will be cached in memory - see to) before it is uploaded. Small files will be cached in memory - see
the [--jottacloud-md5-memory-limit](#jottacloud-md5-memory-limit) flag. the [--jottacloud-md5-memory-limit](#jottacloud-md5-memory-limit) flag.
When uploading from local disk the source checksum is always available,
so this does not apply. Starting with rclone version 1.52 the same is
true for crypted remotes (in older versions the crypt backend would not
calculate hashes for uploads from local disk, so the Jottacloud
backend had to do it as described above).
#### Restricted filename characters #### Restricted filename characters
@@ -25432,6 +25727,86 @@ Options:
# Changelog # Changelog
## v1.53.2 - 2020-10-26
[See commits](https://github.com/rclone/rclone/compare/v1.53.1...v1.53.2)
* Bug Fixes
* acounting
* Fix incorrect speed and transferTime in core/stats (Nick Craig-Wood)
* Stabilize display order of transfers on Windows (Nick Craig-Wood)
* operations
* Fix use of --suffix without --backup-dir (Nick Craig-Wood)
* Fix spurious "--checksum is in use but the source and destination have no hashes in common" (Nick Craig-Wood)
* build
* Work around GitHub actions brew problem (Nick Craig-Wood)
* Stop using set-env and set-path in the GitHub actions (Nick Craig-Wood)
* Mount
* mount2: Fix the swapped UID / GID values (Russell Cattelan)
* VFS
* Detect and recover from a file being removed externally from the cache (Nick Craig-Wood)
* Fix a deadlock vulnerability in downloaders.Close (Leo Luan)
* Fix a race condition in retryFailedResets (Leo Luan)
* Fix missed concurrency control between some item operations and reset (Leo Luan)
* Add exponential backoff during ENOSPC retries (Leo Luan)
* Add a missed update of used cache space (Leo Luan)
* Fix --no-modtime to not attempt to set modtimes (as documented) (Nick Craig-Wood)
* Local
* Fix sizes and syncing with --links option on Windows (Nick Craig-Wood)
* Chunker
* Disable ListR to fix missing files on GDrive (workaround) (Ivan Andreev)
* Fix upload over crypt (Ivan Andreev)
* Fichier
* Increase maximum file size from 100GB to 300GB (gyutw)
* Jottacloud
* Remove clientSecret from config when upgrading to token based authentication (buengese)
* Avoid double url escaping of device/mountpoint (albertony)
* Remove DirMove workaround as it's not required anymore - also (buengese)
* Mailru
* Fix uploads after recent changes on server (Ivan Andreev)
* Fix range requests after june changes on server (Ivan Andreev)
* Fix invalid timestamp on corrupted files (fixes) (Ivan Andreev)
* Onedrive
* Fix disk usage for sharepoint (Nick Craig-Wood)
* S3
* Add missing regions for AWS (Anagh Kumar Baranwal)
* Seafile
* Fix accessing libraries > 2GB on 32 bit systems (Muffin King)
* SFTP
* Always convert the checksum to lower case (buengese)
* Union
* Create root directories if none exist (Nick Craig-Wood)
## v1.53.1 - 2020-09-13
[See commits](https://github.com/rclone/rclone/compare/v1.53.0...v1.53.1)
* Bug Fixes
* accounting: Remove new line from end of --stats-one-line display (Nick Craig-Wood)
* check
* Add back missing --download flag (Nick Craig-Wood)
* Fix docs (Nick Craig-Wood)
* docs
* Note --log-file does append (Nick Craig-Wood)
* Add full stops for consistency in rclone --help (edwardxml)
* Add Tencent COS to s3 provider list (wjielai)
* Updated mount command to reflect that it requires Go 1.13 or newer (Evan Harris)
* jottacloud: Mention that uploads from local disk will not need to cache files to disk for md5 calculation (albertony)
* Fix formatting of rc docs page (Nick Craig-Wood)
* build
* Include vendor tar ball in release and fix startdev (Nick Craig-Wood)
* Fix "Illegal instruction" error for ARMv6 builds (Nick Craig-Wood)
* Fix architecture name in ARMv7 build (Nick Craig-Wood)
* VFS
* Fix spurious error "vfs cache: failed to _ensure cache EOF" (Nick Craig-Wood)
* Log an ERROR if we fail to set the file to be sparse (Nick Craig-Wood)
* Local
* Log an ERROR if we fail to set the file to be sparse (Nick Craig-Wood)
* Drive
* Re-adds special oauth help text (Tim Gallant)
* Opendrive
* Do not retry 400 errors (Evan Harris)
## v1.53.0 - 2020-09-02 ## v1.53.0 - 2020-09-02
[See commits](https://github.com/rclone/rclone/compare/v1.52.0...v1.53.0) [See commits](https://github.com/rclone/rclone/compare/v1.52.0...v1.53.0)

9364
MANUAL.txt generated

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,8 @@ VERSION := $(shell cat VERSION)
# Last tag on this branch # Last tag on this branch
LAST_TAG := $(shell git describe --tags --abbrev=0) LAST_TAG := $(shell git describe --tags --abbrev=0)
# Next version # Next version
NEXT_VERSION := $(shell echo $(VERSION) | perl -lpe 's/v//; $$_ += 0.01; $$_ = sprintf("v%.2f.0", $$_)') NEXT_VERSION := $(shell echo $(VERSION) | awk -F. -v OFS=. '{print $$1,$$2+1,0}')
NEXT_PATCH_VERSION := $(shell echo $(VERSION) | awk -F. -v OFS=. '{print $$1,$$2,$$3+1}')
# If we are working on a release, override branch to master # If we are working on a release, override branch to master
ifdef RELEASE_TAG ifdef RELEASE_TAG
BRANCH := master BRANCH := master
@@ -164,6 +165,11 @@ validate_website: website
tarball: tarball:
git archive -9 --format=tar.gz --prefix=rclone-$(TAG)/ -o build/rclone-$(TAG).tar.gz $(TAG) git archive -9 --format=tar.gz --prefix=rclone-$(TAG)/ -o build/rclone-$(TAG).tar.gz $(TAG)
vendorball:
go mod vendor
tar -zcf build/rclone-$(TAG)-vendor.tar.gz vendor
rm -rf vendor
sign_upload: sign_upload:
cd build && md5sum rclone-v* | gpg --clearsign > MD5SUMS cd build && md5sum rclone-v* | gpg --clearsign > MD5SUMS
cd build && sha1sum rclone-v* | gpg --clearsign > SHA1SUMS cd build && sha1sum rclone-v* | gpg --clearsign > SHA1SUMS
@@ -239,7 +245,15 @@ startdev:
echo -e "package fs\n\n// Version of rclone\nvar Version = \"$(NEXT_VERSION)-DEV\"\n" | gofmt > fs/version.go echo -e "package fs\n\n// Version of rclone\nvar Version = \"$(NEXT_VERSION)-DEV\"\n" | gofmt > fs/version.go
echo -n "$(NEXT_VERSION)" > docs/layouts/partials/version.html echo -n "$(NEXT_VERSION)" > docs/layouts/partials/version.html
echo "$(NEXT_VERSION)" > VERSION echo "$(NEXT_VERSION)" > VERSION
git commit -m "Start $(VERSION)-DEV development" fs/version.go git commit -m "Start $(NEXT_VERSION)-DEV development" fs/version.go VERSION docs/layouts/partials/version.html
startstable:
@echo "Version is $(VERSION)"
@echo "Next stable version is $(NEXT_PATCH_VERSION)"
echo -e "package fs\n\n// Version of rclone\nvar Version = \"$(NEXT_PATCH_VERSION)-DEV\"\n" | gofmt > fs/version.go
echo -n "$(NEXT_PATCH_VERSION)" > docs/layouts/partials/version.html
echo "$(NEXT_PATCH_VERSION)" > VERSION
git commit -m "Start $(NEXT_PATCH_VERSION)-DEV development" fs/version.go VERSION docs/layouts/partials/version.html
winzip: winzip:
zip -9 rclone-$(TAG).zip rclone.exe zip -9 rclone-$(TAG).zip rclone.exe

View File

@@ -64,6 +64,7 @@ Rclone *("rsync for cloud storage")* is a command line program to sync files and
* StackPath [:page_facing_up:](https://rclone.org/s3/#stackpath) * StackPath [:page_facing_up:](https://rclone.org/s3/#stackpath)
* SugarSync [:page_facing_up:](https://rclone.org/sugarsync/) * SugarSync [:page_facing_up:](https://rclone.org/sugarsync/)
* Tardigrade [:page_facing_up:](https://rclone.org/tardigrade/) * Tardigrade [:page_facing_up:](https://rclone.org/tardigrade/)
* Tencent Cloud Object Storage (COS) [:page_facing_up:](https://rclone.org/s3/#tencent-cos)
* Wasabi [:page_facing_up:](https://rclone.org/s3/#wasabi) * Wasabi [:page_facing_up:](https://rclone.org/s3/#wasabi)
* WebDAV [:page_facing_up:](https://rclone.org/webdav/) * WebDAV [:page_facing_up:](https://rclone.org/webdav/)
* Yandex Disk [:page_facing_up:](https://rclone.org/yandex/) * Yandex Disk [:page_facing_up:](https://rclone.org/yandex/)

View File

@@ -9,7 +9,7 @@ This file describes how to make the various kinds of releases
## Making a release ## Making a release
* git checkout master * git checkout master # see below for stable branch
* git pull * git pull
* git status - make sure everything is checked in * git status - make sure everything is checked in
* Check GitHub actions build for master is Green * Check GitHub actions build for master is Green
@@ -25,12 +25,13 @@ This file describes how to make the various kinds of releases
* # Wait for the GitHub builds to complete then... * # Wait for the GitHub builds to complete then...
* make fetch_binaries * make fetch_binaries
* make tarball * make tarball
* make vendorball
* make sign_upload * make sign_upload
* make check_sign * make check_sign
* make upload * make upload
* make upload_website * make upload_website
* make upload_github * make upload_github
* make startdev * make startdev # make startstable for stable branch
* # announce with forum post, twitter post, patreon post * # announce with forum post, twitter post, patreon post
Early in the next release cycle update the dependencies Early in the next release cycle update the dependencies
@@ -41,62 +42,35 @@ Early in the next release cycle update the dependencies
* git add new files * git add new files
* git commit -a -v * git commit -a -v
If `make update` fails with errors like this:
```
# github.com/cpuguy83/go-md2man/md2man
../../../../pkg/mod/github.com/cpuguy83/go-md2man@v1.0.8/md2man/md2man.go:11:16: undefined: blackfriday.EXTENSION_NO_INTRA_EMPHASIS
../../../../pkg/mod/github.com/cpuguy83/go-md2man@v1.0.8/md2man/md2man.go:12:16: undefined: blackfriday.EXTENSION_TABLES
```
Can be fixed with
* GO111MODULE=on go get -u github.com/russross/blackfriday@v1.5.2
* GO111MODULE=on go mod tidy
## Making a point release ## Making a point release
If rclone needs a point release due to some horrendous bug: If rclone needs a point release due to some horrendous bug:
First make the release branch. If this is a second point release then Set vars
this will be done already.
* BASE_TAG=v1.XX # eg v1.52 * BASE_TAG=v1.XX # eg v1.52
* NEW_TAG=${BASE_TAG}.Y # eg v1.52.1 * NEW_TAG=${BASE_TAG}.Y # eg v1.52.1
* echo $BASE_TAG $NEW_TAG # v1.52 v1.52.1 * echo $BASE_TAG $NEW_TAG # v1.52 v1.52.1
First make the release branch. If this is a second point release then
this will be done already.
* git branch ${BASE_TAG} ${BASE_TAG}-stable * git branch ${BASE_TAG} ${BASE_TAG}-stable
* git co ${BASE_TAG}-stable
* make startstable
Now Now
* FIXME this is now broken with new semver layout - needs fixing
* FIXME the TAG=${NEW_TAG} shouldn't be necessary any more
* git co ${BASE_TAG}-stable * git co ${BASE_TAG}-stable
* git cherry-pick any fixes * git cherry-pick any fixes
* Test (see above) * Do the steps as above
* make NEXT_VERSION=${NEW_TAG} tag * make startstable
* edit docs/content/changelog.md * NB this overwrites the current beta so we need to do this - FIXME is this true any more?
* make TAG=${NEW_TAG} doc
* git commit -a -v -m "Version ${NEW_TAG}"
* git tag -d ${NEW_TAG}
* git tag -s -m "Version ${NEW_TAG}" ${NEW_TAG}
* git push --tags -u origin ${BASE_TAG}-stable
* Wait for builds to complete
* make BRANCH_PATH= TAG=${NEW_TAG} fetch_binaries
* make TAG=${NEW_TAG} tarball
* make TAG=${NEW_TAG} sign_upload
* make TAG=${NEW_TAG} check_sign
* make TAG=${NEW_TAG} upload
* make TAG=${NEW_TAG} upload_website
* make TAG=${NEW_TAG} upload_github
* NB this overwrites the current beta so we need to do this
* git co master * git co master
* make VERSION=${NEW_TAG} startdev * # cherry pick the changes to the changelog
* # cherry pick the changes to the changelog and VERSION * git checkout ${BASE_TAG}-stable docs/content/changelog.md
* git checkout ${BASE_TAG}-stable VERSION docs/content/changelog.md * git commit -a -v -m "Changelog updates from Version ${NEW_TAG}"
* git commit --amend
* git push * git push
* Announce!
## Making a manual build of docker ## Making a manual build of docker

View File

@@ -1 +1 @@
v1.53.0 v1.53.2

View File

@@ -296,6 +296,8 @@ func NewFs(name, rpath string, m configmap.Mapper) (fs.Fs, error) {
ServerSideAcrossConfigs: true, ServerSideAcrossConfigs: true,
}).Fill(f).Mask(baseFs).WrapsFs(f, baseFs) }).Fill(f).Mask(baseFs).WrapsFs(f, baseFs)
f.features.Disable("ListR") // Recursive listing may cause chunker skip files
return f, err return f, err
} }
@@ -958,6 +960,8 @@ func (f *Fs) put(ctx context.Context, in io.Reader, src fs.ObjectInfo, remote st
} }
info := f.wrapInfo(src, chunkRemote, size) info := f.wrapInfo(src, chunkRemote, size)
// Refill chunkLimit and let basePut repeatedly call chunkingReader.Read()
c.chunkLimit = c.chunkSize
// TODO: handle range/limit options // TODO: handle range/limit options
chunk, errChunk := basePut(ctx, wrapIn, info, options...) chunk, errChunk := basePut(ctx, wrapIn, info, options...)
if errChunk != nil { if errChunk != nil {
@@ -1166,10 +1170,14 @@ func (c *chunkingReader) updateHashes() {
func (c *chunkingReader) Read(buf []byte) (bytesRead int, err error) { func (c *chunkingReader) Read(buf []byte) (bytesRead int, err error) {
if c.chunkLimit <= 0 { if c.chunkLimit <= 0 {
// Chunk complete - switch to next one. // Chunk complete - switch to next one.
// Note #1:
// We might not get here because some remotes (eg. box multi-uploader) // We might not get here because some remotes (eg. box multi-uploader)
// read the specified size exactly and skip the concluding EOF Read. // read the specified size exactly and skip the concluding EOF Read.
// Then a check in the put loop will kick in. // Then a check in the put loop will kick in.
c.chunkLimit = c.chunkSize // Note #2:
// The crypt backend after receiving EOF here will call Read again
// and we must insist on returning EOF, so we postpone refilling
// chunkLimit to the main loop.
return 0, io.EOF return 0, io.EOF
} }
if int64(len(buf)) > c.chunkLimit { if int64(len(buf)) > c.chunkLimit {

View File

@@ -157,6 +157,17 @@ func driveScopesContainsAppFolder(scopes []string) bool {
return false return false
} }
func driveOAuthOptions() []fs.Option {
opts := []fs.Option{}
for _, opt := range oauthutil.SharedOptions {
if opt.Name == config.ConfigClientID {
opt.Help = "Google Application Client Id\nSetting your own is recommended.\nSee https://rclone.org/drive/#making-your-own-client-id for how to create your own.\nIf you leave this blank, it will use an internal key which is low performance."
}
opts = append(opts, opt)
}
return opts
}
// Register with Fs // Register with Fs
func init() { func init() {
fs.Register(&fs.RegInfo{ fs.Register(&fs.RegInfo{
@@ -192,7 +203,7 @@ func init() {
log.Fatalf("Failed to configure team drive: %v", err) log.Fatalf("Failed to configure team drive: %v", err)
} }
}, },
Options: append(oauthutil.SharedOptions, []fs.Option{{ Options: append(driveOAuthOptions(), []fs.Option{{
Name: "scope", Name: "scope",
Help: "Scope that rclone should use when requesting access from drive.", Help: "Scope that rclone should use when requesting access from drive.",
Examples: []fs.OptionExample{{ Examples: []fs.OptionExample{{

View File

@@ -323,7 +323,7 @@ func (f *Fs) Put(ctx context.Context, in io.Reader, src fs.ObjectInfo, options .
// This will create a duplicate if we upload a new file without // This will create a duplicate if we upload a new file without
// checking to see if there is one already - use Put() for that. // checking to see if there is one already - use Put() for that.
func (f *Fs) putUnchecked(ctx context.Context, in io.Reader, remote string, size int64, options ...fs.OpenOption) (fs.Object, error) { func (f *Fs) putUnchecked(ctx context.Context, in io.Reader, remote string, size int64, options ...fs.OpenOption) (fs.Object, error) {
if size > int64(100e9) { if size > int64(300e9) {
return nil, errors.New("File too big, cant upload") return nil, errors.New("File too big, cant upload")
} else if size == 0 { } else if size == 0 {
return nil, fs.ErrorCantUploadEmptyFiles return nil, fs.ErrorCantUploadEmptyFiles

View File

@@ -373,6 +373,9 @@ func v2config(ctx context.Context, name string, m configmap.Mapper) {
fmt.Printf("Login Token> ") fmt.Printf("Login Token> ")
loginToken := config.ReadLine() loginToken := config.ReadLine()
m.Set(configClientID, "jottacli")
m.Set(configClientSecret, "")
token, err := doAuthV2(ctx, srv, loginToken, m) token, err := doAuthV2(ctx, srv, loginToken, m)
if err != nil { if err != nil {
log.Fatalf("Failed to get oauth token: %s", err) log.Fatalf("Failed to get oauth token: %s", err)
@@ -384,7 +387,6 @@ func v2config(ctx context.Context, name string, m configmap.Mapper) {
fmt.Printf("\nDo you want to use a non standard device/mountpoint e.g. for accessing files uploaded using the official Jottacloud client?\n\n") fmt.Printf("\nDo you want to use a non standard device/mountpoint e.g. for accessing files uploaded using the official Jottacloud client?\n\n")
if config.Confirm(false) { if config.Confirm(false) {
oauthConfig.ClientID = "jottacli"
oAuthClient, _, err := oauthutil.NewClient(name, m, oauthConfig) oAuthClient, _, err := oauthutil.NewClient(name, m, oauthConfig)
if err != nil { if err != nil {
log.Fatalf("Failed to load oAuthClient: %s", err) log.Fatalf("Failed to load oAuthClient: %s", err)
@@ -551,7 +553,7 @@ func (f *Fs) setEndpointURL() {
if f.opt.Mountpoint == "" { if f.opt.Mountpoint == "" {
f.opt.Mountpoint = defaultMountpoint f.opt.Mountpoint = defaultMountpoint
} }
f.endpointURL = urlPathEscape(path.Join(f.user, f.opt.Device, f.opt.Mountpoint)) f.endpointURL = path.Join(f.user, f.opt.Device, f.opt.Mountpoint)
} }
// readMetaDataForPath reads the metadata from the path // readMetaDataForPath reads the metadata from the path
@@ -1087,8 +1089,7 @@ func (f *Fs) copyOrMove(ctx context.Context, method, src, dest string) (info *ap
var resp *http.Response var resp *http.Response
err = f.pacer.Call(func() (bool, error) { err = f.pacer.Call(func() (bool, error) {
resp, err = f.srv.CallXML(ctx, &opts, nil, &info) resp, err = f.srv.CallXML(ctx, &opts, nil, &info)
retry, _ := shouldRetry(resp, err) return shouldRetry(resp, err)
return (retry && resp.StatusCode != 500), err
}) })
if err != nil { if err != nil {
return nil, err return nil, err
@@ -1192,18 +1193,6 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string
_, err = f.copyOrMove(ctx, "mvDir", path.Join(f.endpointURL, f.opt.Enc.FromStandardPath(srcPath))+"/", dstRemote) _, err = f.copyOrMove(ctx, "mvDir", path.Join(f.endpointURL, f.opt.Enc.FromStandardPath(srcPath))+"/", dstRemote)
// surprise! jottacloud fucked up dirmove - the api spits out an error but
// dir gets moved regardless
if apiErr, ok := err.(*api.Error); ok {
if apiErr.StatusCode == 500 {
_, err := f.NewObject(ctx, dstRemote)
if err == fs.ErrorNotAFile {
log.Printf("FIXME: ignoring DirMove error - move succeeded anyway\n")
return nil
}
return err
}
}
if err != nil { if err != nil {
return errors.Wrap(err, "couldn't move directory") return errors.Wrap(err, "couldn't move directory")
} }

View File

@@ -1213,7 +1213,7 @@ func (f *Fs) OpenWriterAt(ctx context.Context, remote string, size int64) (fs.Wr
// Set the file to be a sparse file (important on Windows) // Set the file to be a sparse file (important on Windows)
err = file.SetSparse(out) err = file.SetSparse(out)
if err != nil { if err != nil {
fs.Debugf(o, "Failed to set sparse: %v", err) fs.Errorf(o, "Failed to set sparse: %v", err)
} }
} }
@@ -1231,6 +1231,15 @@ func (o *Object) setMetadata(info os.FileInfo) {
o.modTime = info.ModTime() o.modTime = info.ModTime()
o.mode = info.Mode() o.mode = info.Mode()
o.fs.objectMetaMu.Unlock() o.fs.objectMetaMu.Unlock()
// On Windows links read as 0 size so set the correct size here
if runtime.GOOS == "windows" && o.translatedLink {
linkdst, err := os.Readlink(o.path)
if err != nil {
fs.Errorf(o, "Failed to read link size: %v", err)
} else {
o.size = int64(len(linkdst))
}
}
} }
// Stat an Object into info // Stat an Object into info

View File

@@ -6,7 +6,6 @@ import (
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
"runtime"
"testing" "testing"
"time" "time"
@@ -89,9 +88,6 @@ func TestSymlink(t *testing.T) {
// Object viewed as symlink // Object viewed as symlink
file2 := fstest.NewItem("symlink.txt"+linkSuffix, "file.txt", modTime2) file2 := fstest.NewItem("symlink.txt"+linkSuffix, "file.txt", modTime2)
if runtime.GOOS == "windows" {
file2.Size = 0 // symlinks are 0 length under Windows
}
// Object viewed as destination // Object viewed as destination
file2d := fstest.NewItem("symlink.txt", "hello", modTime1) file2d := fstest.NewItem("symlink.txt", "hello", modTime1)
@@ -121,9 +117,6 @@ func TestSymlink(t *testing.T) {
// Create a symlink // Create a symlink
modTime3 := fstest.Time("2002-03-03T04:05:10.123123123Z") modTime3 := fstest.Time("2002-03-03T04:05:10.123123123Z")
file3 := r.WriteObjectTo(ctx, r.Flocal, "symlink2.txt"+linkSuffix, "file.txt", modTime3, false) file3 := r.WriteObjectTo(ctx, r.Flocal, "symlink2.txt"+linkSuffix, "file.txt", modTime3, false)
if runtime.GOOS == "windows" {
file3.Size = 0 // symlinks are 0 length under Windows
}
fstest.CheckListingWithPrecision(t, r.Flocal, []fstest.Item{file1, file2, file3}, nil, fs.ModTimeNotSupported) fstest.CheckListingWithPrecision(t, r.Flocal, []fstest.Item{file1, file2, file3}, nil, fs.ModTimeNotSupported)
if haveLChtimes { if haveLChtimes {
fstest.CheckItems(t, r.Flocal, file1, file2, file3) fstest.CheckItems(t, r.Flocal, file1, file2, file3)
@@ -142,9 +135,7 @@ func TestSymlink(t *testing.T) {
o, err := r.Flocal.NewObject(ctx, "symlink2.txt"+linkSuffix) o, err := r.Flocal.NewObject(ctx, "symlink2.txt"+linkSuffix)
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, "symlink2.txt"+linkSuffix, o.Remote()) assert.Equal(t, "symlink2.txt"+linkSuffix, o.Remote())
if runtime.GOOS != "windows" {
assert.Equal(t, int64(8), o.Size()) assert.Equal(t, int64(8), o.Size())
}
// Check that NewObject doesn't see the non suffixed version // Check that NewObject doesn't see the non suffixed version
_, err = r.Flocal.NewObject(ctx, "symlink2.txt") _, err = r.Flocal.NewObject(ctx, "symlink2.txt")

View File

@@ -117,7 +117,7 @@ type ListItem struct {
Name string `json:"name"` Name string `json:"name"`
Home string `json:"home"` Home string `json:"home"`
Size int64 `json:"size"` Size int64 `json:"size"`
Mtime int64 `json:"mtime,omitempty"` Mtime uint64 `json:"mtime,omitempty"`
Hash string `json:"hash,omitempty"` Hash string `json:"hash,omitempty"`
VirusScan string `json:"virus_scan,omitempty"` VirusScan string `json:"virus_scan,omitempty"`
Tree string `json:"tree,omitempty"` Tree string `json:"tree,omitempty"`
@@ -159,71 +159,6 @@ type FolderInfoResponse struct {
Email string `json:"email"` Email string `json:"email"`
} }
// ShardInfoResponse ...
type ShardInfoResponse struct {
Email string `json:"email"`
Body struct {
Video []struct {
Count string `json:"count"`
URL string `json:"url"`
} `json:"video"`
ViewDirect []struct {
Count string `json:"count"`
URL string `json:"url"`
} `json:"view_direct"`
WeblinkView []struct {
Count string `json:"count"`
URL string `json:"url"`
} `json:"weblink_view"`
WeblinkVideo []struct {
Count string `json:"count"`
URL string `json:"url"`
} `json:"weblink_video"`
WeblinkGet []struct {
Count int `json:"count"`
URL string `json:"url"`
} `json:"weblink_get"`
Stock []struct {
Count string `json:"count"`
URL string `json:"url"`
} `json:"stock"`
WeblinkThumbnails []struct {
Count string `json:"count"`
URL string `json:"url"`
} `json:"weblink_thumbnails"`
PublicUpload []struct {
Count string `json:"count"`
URL string `json:"url"`
} `json:"public_upload"`
Auth []struct {
Count string `json:"count"`
URL string `json:"url"`
} `json:"auth"`
Web []struct {
Count string `json:"count"`
URL string `json:"url"`
} `json:"web"`
View []struct {
Count string `json:"count"`
URL string `json:"url"`
} `json:"view"`
Upload []struct {
Count string `json:"count"`
URL string `json:"url"`
} `json:"upload"`
Get []struct {
Count string `json:"count"`
URL string `json:"url"`
} `json:"get"`
Thumbnails []struct {
Count string `json:"count"`
URL string `json:"url"`
} `json:"thumbnails"`
} `json:"body"`
Time int64 `json:"time"`
Status int `json:"status"`
}
// CleanupResponse ... // CleanupResponse ...
type CleanupResponse struct { type CleanupResponse struct {
Email string `json:"email"` Email string `json:"email"`

View File

@@ -37,6 +37,7 @@ import (
"github.com/rclone/rclone/lib/encoder" "github.com/rclone/rclone/lib/encoder"
"github.com/rclone/rclone/lib/oauthutil" "github.com/rclone/rclone/lib/oauthutil"
"github.com/rclone/rclone/lib/pacer" "github.com/rclone/rclone/lib/pacer"
"github.com/rclone/rclone/lib/readers"
"github.com/rclone/rclone/lib/rest" "github.com/rclone/rclone/lib/rest"
"github.com/pkg/errors" "github.com/pkg/errors"
@@ -655,9 +656,14 @@ func (f *Fs) itemToDirEntry(ctx context.Context, item *api.ListItem) (entry fs.D
if err != nil { if err != nil {
return nil, -1, err return nil, -1, err
} }
mTime := int64(item.Mtime)
if mTime < 0 {
fs.Debugf(f, "Fixing invalid timestamp %d on mailru file %q", mTime, remote)
mTime = 0
}
switch item.Kind { switch item.Kind {
case "folder": case "folder":
dir := fs.NewDir(remote, time.Unix(item.Mtime, 0)).SetSize(item.Size) dir := fs.NewDir(remote, time.Unix(mTime, 0)).SetSize(item.Size)
dirSize := item.Count.Files + item.Count.Folders dirSize := item.Count.Files + item.Count.Folders
return dir, dirSize, nil return dir, dirSize, nil
case "file": case "file":
@@ -671,7 +677,7 @@ func (f *Fs) itemToDirEntry(ctx context.Context, item *api.ListItem) (entry fs.D
hasMetaData: true, hasMetaData: true,
size: item.Size, size: item.Size,
mrHash: binHash, mrHash: binHash,
modTime: time.Unix(item.Mtime, 0), modTime: time.Unix(mTime, 0),
} }
return file, -1, nil return file, -1, nil
default: default:
@@ -1861,30 +1867,30 @@ func (f *Fs) uploadShard(ctx context.Context) (string, error) {
return f.shardURL, nil return f.shardURL, nil
} }
token, err := f.accessToken()
if err != nil {
return "", err
}
opts := rest.Opts{ opts := rest.Opts{
RootURL: api.DispatchServerURL,
Method: "GET", Method: "GET",
Path: "/api/m1/dispatcher", Path: "/u",
Parameters: url.Values{
"client_id": {api.OAuthClientID},
"access_token": {token},
},
} }
var info api.ShardInfoResponse var (
res *http.Response
url string
err error
)
err = f.pacer.Call(func() (bool, error) { err = f.pacer.Call(func() (bool, error) {
res, err := f.srv.CallJSON(ctx, &opts, nil, &info) res, err = f.srv.Call(ctx, &opts)
return shouldRetry(res, err, f, &opts) if err == nil {
url, err = readBodyWord(res)
}
return fserrors.ShouldRetry(err), err
}) })
if err != nil { if err != nil {
closeBody(res)
return "", err return "", err
} }
f.shardURL = info.Body.Upload[0].URL f.shardURL = url
f.shardExpiry = time.Now().Add(shardExpirySec * time.Second) f.shardExpiry = time.Now().Add(shardExpirySec * time.Second)
fs.Debugf(f, "new upload shard: %s", f.shardURL) fs.Debugf(f, "new upload shard: %s", f.shardURL)
@@ -2116,7 +2122,18 @@ func (o *Object) Open(ctx context.Context, options ...fs.OpenOption) (in io.Read
return nil, err return nil, err
} }
start, end, partial := getTransferRange(o.size, options...) start, end, partialRequest := getTransferRange(o.size, options...)
headers := map[string]string{
"Accept": "*/*",
"Content-Type": "application/octet-stream",
}
if partialRequest {
rangeStr := fmt.Sprintf("bytes=%d-%d", start, end-1)
headers["Range"] = rangeStr
// headers["Content-Range"] = rangeStr
headers["Accept-Ranges"] = "bytes"
}
// TODO: set custom timeouts // TODO: set custom timeouts
opts := rest.Opts{ opts := rest.Opts{
@@ -2127,10 +2144,7 @@ func (o *Object) Open(ctx context.Context, options ...fs.OpenOption) (in io.Read
"client_id": {api.OAuthClientID}, "client_id": {api.OAuthClientID},
"token": {token}, "token": {token},
}, },
ExtraHeaders: map[string]string{ ExtraHeaders: headers,
"Accept": "*/*",
"Range": fmt.Sprintf("bytes=%d-%d", start, end-1),
},
} }
var res *http.Response var res *http.Response
@@ -2151,18 +2165,36 @@ func (o *Object) Open(ctx context.Context, options ...fs.OpenOption) (in io.Read
return nil, err return nil, err
} }
var hasher gohash.Hash // Server should respond with Status 206 and Content-Range header to a range
if !partial { // request. Status 200 (and no Content-Range) means a full-content response.
partialResponse := res.StatusCode == 206
var (
hasher gohash.Hash
wrapStream io.ReadCloser
)
if !partialResponse {
// Cannot check hash of partial download // Cannot check hash of partial download
hasher = mrhash.New() hasher = mrhash.New()
} }
wrapStream := &endHandler{ wrapStream = &endHandler{
ctx: ctx, ctx: ctx,
stream: res.Body, stream: res.Body,
hasher: hasher, hasher: hasher,
o: o, o: o,
server: server, server: server,
} }
if partialRequest && !partialResponse {
fs.Debugf(o, "Server returned full content instead of range")
if start > 0 {
// Discard the beginning of the data
_, err = io.CopyN(ioutil.Discard, wrapStream, start)
if err != nil {
return nil, err
}
}
wrapStream = readers.NewLimitedReadCloser(wrapStream, end-start)
}
return wrapStream, nil return wrapStream, nil
} }

View File

@@ -1247,6 +1247,10 @@ func (f *Fs) About(ctx context.Context) (usage *fs.Usage, err error) {
return nil, errors.Wrap(err, "about failed") return nil, errors.Wrap(err, "about failed")
} }
q := drive.Quota q := drive.Quota
// On (some?) Onedrive sharepoints these are all 0 so return unknown in that case
if q.Total == 0 && q.Used == 0 && q.Deleted == 0 && q.Remaining == 0 {
return &fs.Usage{}, nil
}
usage = &fs.Usage{ usage = &fs.Usage{
Total: fs.NewUsageValue(q.Total), // quota of bytes that can be used Total: fs.NewUsageValue(q.Total), // quota of bytes that can be used
Used: fs.NewUsageValue(q.Used), // bytes in use Used: fs.NewUsageValue(q.Used), // bytes in use

View File

@@ -646,7 +646,6 @@ func (f *Fs) Put(ctx context.Context, in io.Reader, src fs.ObjectInfo, options .
// retryErrorCodes is a slice of error codes that we will retry // retryErrorCodes is a slice of error codes that we will retry
var retryErrorCodes = []int{ var retryErrorCodes = []int{
400, // Bad request (seen in "Next token is expired")
401, // Unauthorized (seen in "Token has expired") 401, // Unauthorized (seen in "Token has expired")
408, // Request Timeout 408, // Request Timeout
423, // Locked - get this on folders sometimes 423, // Locked - get this on folders sometimes

View File

@@ -58,7 +58,7 @@ import (
func init() { func init() {
fs.Register(&fs.RegInfo{ fs.Register(&fs.RegInfo{
Name: "s3", Name: "s3",
Description: "Amazon S3 Compliant Storage Provider (AWS, Alibaba, Ceph, Digital Ocean, Dreamhost, IBM COS, Minio, etc)", Description: "Amazon S3 Compliant Storage Provider (AWS, Alibaba, Ceph, Digital Ocean, Dreamhost, IBM COS, Minio, Tencent COS, etc)",
NewFs: NewFs, NewFs: NewFs,
CommandHelp: commandHelp, CommandHelp: commandHelp,
Options: []fs.Option{{ Options: []fs.Option{{
@@ -94,6 +94,9 @@ func init() {
}, { }, {
Value: "StackPath", Value: "StackPath",
Help: "StackPath Object Storage", Help: "StackPath Object Storage",
}, {
Value: "TencentCOS",
Help: "Tencent Cloud Object Storage (COS)",
}, { }, {
Value: "Wasabi", Value: "Wasabi",
Help: "Wasabi Object Storage", Help: "Wasabi Object Storage",
@@ -119,6 +122,9 @@ func init() {
Name: "secret_access_key", Name: "secret_access_key",
Help: "AWS Secret Access Key (password)\nLeave blank for anonymous access or runtime credentials.", Help: "AWS Secret Access Key (password)\nLeave blank for anonymous access or runtime credentials.",
}, { }, {
// References:
// 1. https://docs.aws.amazon.com/general/latest/gr/rande.html
// 2. https://docs.aws.amazon.com/general/latest/gr/s3.html
Name: "region", Name: "region",
Help: "Region to connect to.", Help: "Region to connect to.",
Provider: "AWS", Provider: "AWS",
@@ -128,12 +134,12 @@ func init() {
}, { }, {
Value: "us-east-2", Value: "us-east-2",
Help: "US East (Ohio) Region\nNeeds location constraint us-east-2.", Help: "US East (Ohio) Region\nNeeds location constraint us-east-2.",
}, {
Value: "us-west-2",
Help: "US West (Oregon) Region\nNeeds location constraint us-west-2.",
}, { }, {
Value: "us-west-1", Value: "us-west-1",
Help: "US West (Northern California) Region\nNeeds location constraint us-west-1.", Help: "US West (Northern California) Region\nNeeds location constraint us-west-1.",
}, {
Value: "us-west-2",
Help: "US West (Oregon) Region\nNeeds location constraint us-west-2.",
}, { }, {
Value: "ca-central-1", Value: "ca-central-1",
Help: "Canada (Central) Region\nNeeds location constraint ca-central-1.", Help: "Canada (Central) Region\nNeeds location constraint ca-central-1.",
@@ -143,9 +149,15 @@ func init() {
}, { }, {
Value: "eu-west-2", Value: "eu-west-2",
Help: "EU (London) Region\nNeeds location constraint eu-west-2.", Help: "EU (London) Region\nNeeds location constraint eu-west-2.",
}, {
Value: "eu-west-3",
Help: "EU (Paris) Region\nNeeds location constraint eu-west-3.",
}, { }, {
Value: "eu-north-1", Value: "eu-north-1",
Help: "EU (Stockholm) Region\nNeeds location constraint eu-north-1.", Help: "EU (Stockholm) Region\nNeeds location constraint eu-north-1.",
}, {
Value: "eu-south-1",
Help: "EU (Milan) Region\nNeeds location constraint eu-south-1.",
}, { }, {
Value: "eu-central-1", Value: "eu-central-1",
Help: "EU (Frankfurt) Region\nNeeds location constraint eu-central-1.", Help: "EU (Frankfurt) Region\nNeeds location constraint eu-central-1.",
@@ -161,15 +173,36 @@ func init() {
}, { }, {
Value: "ap-northeast-2", Value: "ap-northeast-2",
Help: "Asia Pacific (Seoul)\nNeeds location constraint ap-northeast-2.", Help: "Asia Pacific (Seoul)\nNeeds location constraint ap-northeast-2.",
}, {
Value: "ap-northeast-3",
Help: "Asia Pacific (Osaka-Local)\nNeeds location constraint ap-northeast-3.",
}, { }, {
Value: "ap-south-1", Value: "ap-south-1",
Help: "Asia Pacific (Mumbai)\nNeeds location constraint ap-south-1.", Help: "Asia Pacific (Mumbai)\nNeeds location constraint ap-south-1.",
}, { }, {
Value: "ap-east-1", Value: "ap-east-1",
Help: "Asia Patific (Hong Kong) Region\nNeeds location constraint ap-east-1.", Help: "Asia Pacific (Hong Kong) Region\nNeeds location constraint ap-east-1.",
}, { }, {
Value: "sa-east-1", Value: "sa-east-1",
Help: "South America (Sao Paulo) Region\nNeeds location constraint sa-east-1.", Help: "South America (Sao Paulo) Region\nNeeds location constraint sa-east-1.",
}, {
Value: "me-south-1",
Help: "Middle East (Bahrain) Region\nNeeds location constraint me-south-1.",
}, {
Value: "af-south-1",
Help: "Africa (Cape Town) Region\nNeeds location constraint af-south-1.",
}, {
Value: "cn-north-1",
Help: "China (Beijing) Region\nNeeds location constraint cn-north-1.",
}, {
Value: "cn-northwest-1",
Help: "China (Ningxia) Region\nNeeds location constraint cn-northwest-1.",
}, {
Value: "us-gov-east-1",
Help: "AWS GovCloud (US-East) Region\nNeeds location constraint us-gov-east-1.",
}, {
Value: "us-gov-west-1",
Help: "AWS GovCloud (US) Region\nNeeds location constraint us-gov-west-1.",
}}, }},
}, { }, {
Name: "region", Name: "region",
@@ -185,7 +218,7 @@ func init() {
}, { }, {
Name: "region", Name: "region",
Help: "Region to connect to.\nLeave blank if you are using an S3 clone and you don't have a region.", Help: "Region to connect to.\nLeave blank if you are using an S3 clone and you don't have a region.",
Provider: "!AWS,Alibaba,Scaleway", Provider: "!AWS,Alibaba,Scaleway,TencentCOS",
Examples: []fs.OptionExample{{ Examples: []fs.OptionExample{{
Value: "", Value: "",
Help: "Use this if unsure. Will use v4 signatures and an empty region.", Help: "Use this if unsure. Will use v4 signatures and an empty region.",
@@ -476,10 +509,73 @@ func init() {
Value: "s3.eu-central-1.stackpathstorage.com", Value: "s3.eu-central-1.stackpathstorage.com",
Help: "EU Endpoint", Help: "EU Endpoint",
}}, }},
}, {
// cos endpoints: https://intl.cloud.tencent.com/document/product/436/6224
Name: "endpoint",
Help: "Endpoint for Tencent COS API.",
Provider: "TencentCOS",
Examples: []fs.OptionExample{{
Value: "cos.ap-beijing.myqcloud.com",
Help: "Beijing Region.",
}, {
Value: "cos.ap-nanjing.myqcloud.com",
Help: "Nanjing Region.",
}, {
Value: "cos.ap-shanghai.myqcloud.com",
Help: "Shanghai Region.",
}, {
Value: "cos.ap-guangzhou.myqcloud.com",
Help: "Guangzhou Region.",
}, {
Value: "cos.ap-nanjing.myqcloud.com",
Help: "Nanjing Region.",
}, {
Value: "cos.ap-chengdu.myqcloud.com",
Help: "Chengdu Region.",
}, {
Value: "cos.ap-chongqing.myqcloud.com",
Help: "Chongqing Region.",
}, {
Value: "cos.ap-hongkong.myqcloud.com",
Help: "Hong Kong (China) Region.",
}, {
Value: "cos.ap-singapore.myqcloud.com",
Help: "Singapore Region.",
}, {
Value: "cos.ap-mumbai.myqcloud.com",
Help: "Mumbai Region.",
}, {
Value: "cos.ap-seoul.myqcloud.com",
Help: "Seoul Region.",
}, {
Value: "cos.ap-bangkok.myqcloud.com",
Help: "Bangkok Region.",
}, {
Value: "cos.ap-tokyo.myqcloud.com",
Help: "Tokyo Region.",
}, {
Value: "cos.na-siliconvalley.myqcloud.com",
Help: "Silicon Valley Region.",
}, {
Value: "cos.na-ashburn.myqcloud.com",
Help: "Virginia Region.",
}, {
Value: "cos.na-toronto.myqcloud.com",
Help: "Toronto Region.",
}, {
Value: "cos.eu-frankfurt.myqcloud.com",
Help: "Frankfurt Region.",
}, {
Value: "cos.eu-moscow.myqcloud.com",
Help: "Moscow Region.",
}, {
Value: "cos.accelerate.myqcloud.com",
Help: "Use Tencent COS Accelerate Endpoint.",
}},
}, { }, {
Name: "endpoint", Name: "endpoint",
Help: "Endpoint for S3 API.\nRequired when using an S3 clone.", Help: "Endpoint for S3 API.\nRequired when using an S3 clone.",
Provider: "!AWS,IBMCOS,Alibaba,Scaleway,StackPath", Provider: "!AWS,IBMCOS,TencentCOS,Alibaba,Scaleway,StackPath",
Examples: []fs.OptionExample{{ Examples: []fs.OptionExample{{
Value: "objects-us-east-1.dream.io", Value: "objects-us-east-1.dream.io",
Help: "Dream Objects endpoint", Help: "Dream Objects endpoint",
@@ -519,12 +615,12 @@ func init() {
}, { }, {
Value: "us-east-2", Value: "us-east-2",
Help: "US East (Ohio) Region.", Help: "US East (Ohio) Region.",
}, {
Value: "us-west-2",
Help: "US West (Oregon) Region.",
}, { }, {
Value: "us-west-1", Value: "us-west-1",
Help: "US West (Northern California) Region.", Help: "US West (Northern California) Region.",
}, {
Value: "us-west-2",
Help: "US West (Oregon) Region.",
}, { }, {
Value: "ca-central-1", Value: "ca-central-1",
Help: "Canada (Central) Region.", Help: "Canada (Central) Region.",
@@ -534,9 +630,15 @@ func init() {
}, { }, {
Value: "eu-west-2", Value: "eu-west-2",
Help: "EU (London) Region.", Help: "EU (London) Region.",
}, {
Value: "eu-west-3",
Help: "EU (Paris) Region.",
}, { }, {
Value: "eu-north-1", Value: "eu-north-1",
Help: "EU (Stockholm) Region.", Help: "EU (Stockholm) Region.",
}, {
Value: "eu-south-1",
Help: "EU (Milan) Region.",
}, { }, {
Value: "EU", Value: "EU",
Help: "EU Region.", Help: "EU Region.",
@@ -551,16 +653,37 @@ func init() {
Help: "Asia Pacific (Tokyo) Region.", Help: "Asia Pacific (Tokyo) Region.",
}, { }, {
Value: "ap-northeast-2", Value: "ap-northeast-2",
Help: "Asia Pacific (Seoul)", Help: "Asia Pacific (Seoul) Region.",
}, {
Value: "ap-northeast-3",
Help: "Asia Pacific (Osaka-Local) Region.",
}, { }, {
Value: "ap-south-1", Value: "ap-south-1",
Help: "Asia Pacific (Mumbai)", Help: "Asia Pacific (Mumbai) Region.",
}, { }, {
Value: "ap-east-1", Value: "ap-east-1",
Help: "Asia Pacific (Hong Kong)", Help: "Asia Pacific (Hong Kong) Region.",
}, { }, {
Value: "sa-east-1", Value: "sa-east-1",
Help: "South America (Sao Paulo) Region.", Help: "South America (Sao Paulo) Region.",
}, {
Value: "me-south-1",
Help: "Middle East (Bahrain) Region.",
}, {
Value: "af-south-1",
Help: "Africa (Cape Town) Region.",
}, {
Value: "cn-north-1",
Help: "China (Beijing) Region",
}, {
Value: "cn-northwest-1",
Help: "China (Ningxia) Region.",
}, {
Value: "us-gov-east-1",
Help: "AWS GovCloud (US-East) Region.",
}, {
Value: "us-gov-west-1",
Help: "AWS GovCloud (US) Region.",
}}, }},
}, { }, {
Name: "location_constraint", Name: "location_constraint",
@@ -666,7 +789,7 @@ func init() {
}, { }, {
Name: "location_constraint", Name: "location_constraint",
Help: "Location constraint - must be set to match the Region.\nLeave blank if not sure. Used when creating buckets only.", Help: "Location constraint - must be set to match the Region.\nLeave blank if not sure. Used when creating buckets only.",
Provider: "!AWS,IBMCOS,Alibaba,Scaleway,StackPath", Provider: "!AWS,IBMCOS,Alibaba,Scaleway,StackPath,TencentCOS",
}, { }, {
Name: "acl", Name: "acl",
Help: `Canned ACL used when creating buckets and storing or copying objects. Help: `Canned ACL used when creating buckets and storing or copying objects.
@@ -678,9 +801,13 @@ For more info visit https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview
Note that this ACL is applied when server side copying objects as S3 Note that this ACL is applied when server side copying objects as S3
doesn't copy the ACL from the source but rather writes a fresh one.`, doesn't copy the ACL from the source but rather writes a fresh one.`,
Examples: []fs.OptionExample{{ Examples: []fs.OptionExample{{
Value: "default",
Help: "Owner gets Full_CONTROL. No one else has access rights (default).",
Provider: "TencentCOS",
}, {
Value: "private", Value: "private",
Help: "Owner gets FULL_CONTROL. No one else has access rights (default).", Help: "Owner gets FULL_CONTROL. No one else has access rights (default).",
Provider: "!IBMCOS", Provider: "!IBMCOS,TencentCOS",
}, { }, {
Value: "public-read", Value: "public-read",
Help: "Owner gets FULL_CONTROL. The AllUsers group gets READ access.", Help: "Owner gets FULL_CONTROL. The AllUsers group gets READ access.",
@@ -842,6 +969,24 @@ isn't set then "acl" is used instead.`,
Value: "STANDARD_IA", Value: "STANDARD_IA",
Help: "Infrequent access storage mode.", Help: "Infrequent access storage mode.",
}}, }},
}, {
// Mapping from here: https://intl.cloud.tencent.com/document/product/436/30925
Name: "storage_class",
Help: "The storage class to use when storing new objects in Tencent COS.",
Provider: "TencentCOS",
Examples: []fs.OptionExample{{
Value: "",
Help: "Default",
}, {
Value: "STANDARD",
Help: "Standard storage class",
}, {
Value: "ARCHIVE",
Help: "Archive storage mode.",
}, {
Value: "STANDARD_IA",
Help: "Infrequent access storage mode.",
}},
}, { }, {
// Mapping from here: https://www.scaleway.com/en/docs/object-storage-glacier/#-Scaleway-Storage-Classes // Mapping from here: https://www.scaleway.com/en/docs/object-storage-glacier/#-Scaleway-Storage-Classes
Name: "storage_class", Name: "storage_class",
@@ -975,7 +1120,7 @@ if false then rclone will use virtual path style. See [the AWS S3
docs](https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingBucket.html#access-bucket-intro) docs](https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingBucket.html#access-bucket-intro)
for more info. for more info.
Some providers (eg AWS, Aliyun OSS or Netease COS) require this set to Some providers (eg AWS, Aliyun OSS, Netease COS or Tencent COS) require this set to
false - rclone will do this automatically based on the provider false - rclone will do this automatically based on the provider
setting.`, setting.`,
Default: true, Default: true,
@@ -1305,7 +1450,7 @@ func s3Connection(opt *Options) (*s3.S3, *session.Session, error) {
if opt.Region == "" { if opt.Region == "" {
opt.Region = "us-east-1" opt.Region = "us-east-1"
} }
if opt.Provider == "AWS" || opt.Provider == "Alibaba" || opt.Provider == "Netease" || opt.Provider == "Scaleway" || opt.UseAccelerateEndpoint { if opt.Provider == "AWS" || opt.Provider == "Alibaba" || opt.Provider == "Netease" || opt.Provider == "Scaleway" || opt.Provider == "TencentCOS" || opt.UseAccelerateEndpoint {
opt.ForcePathStyle = false opt.ForcePathStyle = false
} }
if opt.Provider == "Scaleway" && opt.MaxUploadParts > 1000 { if opt.Provider == "Scaleway" && opt.MaxUploadParts > 1000 {
@@ -1587,7 +1732,7 @@ func (f *Fs) list(ctx context.Context, bucket, directory, prefix string, addBuck
// //
// So we enable only on providers we know supports it properly, all others can retry when a // So we enable only on providers we know supports it properly, all others can retry when a
// XML Syntax error is detected. // XML Syntax error is detected.
var urlEncodeListings = (f.opt.Provider == "AWS" || f.opt.Provider == "Wasabi" || f.opt.Provider == "Alibaba" || f.opt.Provider == "Minio") var urlEncodeListings = (f.opt.Provider == "AWS" || f.opt.Provider == "Wasabi" || f.opt.Provider == "Alibaba" || f.opt.Provider == "Minio" || f.opt.Provider == "TencentCOS")
for { for {
// FIXME need to implement ALL loop // FIXME need to implement ALL loop
req := s3.ListObjectsInput{ req := s3.ListObjectsInput{

View File

@@ -46,7 +46,7 @@ type Library struct {
Encrypted bool `json:"encrypted"` Encrypted bool `json:"encrypted"`
Owner string `json:"owner"` Owner string `json:"owner"`
ID string `json:"id"` ID string `json:"id"`
Size int `json:"size"` Size int64 `json:"size"`
Name string `json:"name"` Name string `json:"name"`
Modified int64 `json:"mtime"` Modified int64 `json:"mtime"`
} }

View File

@@ -1004,7 +1004,7 @@ func (f *Fs) listLibraries(ctx context.Context) (entries fs.DirEntries, err erro
for _, library := range libraries { for _, library := range libraries {
d := fs.NewDir(library.Name, time.Unix(library.Modified, 0)) d := fs.NewDir(library.Name, time.Unix(library.Modified, 0))
d.SetSize(int64(library.Size)) d.SetSize(library.Size)
entries = append(entries, d) entries = append(entries, d)
} }

View File

@@ -1087,7 +1087,7 @@ func shellEscape(str string) string {
func parseHash(bytes []byte) string { func parseHash(bytes []byte) string {
// For strings with backslash *sum writes a leading \ // For strings with backslash *sum writes a leading \
// https://unix.stackexchange.com/q/313733/94054 // https://unix.stackexchange.com/q/313733/94054
return strings.Split(strings.TrimLeft(string(bytes), "\\"), " ")[0] // Split at hash / filename separator return strings.ToLower(strings.Split(strings.TrimLeft(string(bytes), "\\"), " ")[0]) // Split at hash / filename separator / all convert to lowercase
} }
// Parses the byte array output from the SSH session // Parses the byte array output from the SSH session

View File

@@ -145,11 +145,16 @@ func (f *Fs) Hashes() hash.Set {
// Mkdir makes the root directory of the Fs object // Mkdir makes the root directory of the Fs object
func (f *Fs) Mkdir(ctx context.Context, dir string) error { func (f *Fs) Mkdir(ctx context.Context, dir string) error {
upstreams, err := f.create(ctx, dir) upstreams, err := f.create(ctx, dir)
if err == fs.ErrorObjectNotFound && dir != parentDir(dir) { if err == fs.ErrorObjectNotFound {
if dir != parentDir(dir) {
if err := f.Mkdir(ctx, parentDir(dir)); err != nil { if err := f.Mkdir(ctx, parentDir(dir)); err != nil {
return err return err
} }
upstreams, err = f.create(ctx, dir) upstreams, err = f.create(ctx, dir)
} else if dir == "" {
// If root dirs not created then create them
upstreams, err = f.upstreams, nil
}
} }
if err != nil { if err != nil {
return err return err
@@ -818,6 +823,7 @@ func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
fs.Debugf(f, "actionPolicy = %T, createPolicy = %T, searchPolicy = %T", f.actionPolicy, f.createPolicy, f.searchPolicy)
var features = (&fs.Features{ var features = (&fs.Features{
CaseInsensitive: true, CaseInsensitive: true,
DuplicateFiles: false, DuplicateFiles: false,

View File

@@ -280,7 +280,7 @@ func stripVersion(goarch string) string {
// build the binary in dir returning success or failure // build the binary in dir returning success or failure
func compileArch(version, goos, goarch, dir string) bool { func compileArch(version, goos, goarch, dir string) bool {
log.Printf("Compiling %s/%s", goos, goarch) log.Printf("Compiling %s/%s into %s", goos, goarch, dir)
output := filepath.Join(dir, "rclone") output := filepath.Join(dir, "rclone")
if goos == "windows" { if goos == "windows" {
output += ".exe" output += ".exe"
@@ -298,7 +298,6 @@ func compileArch(version, goos, goarch, dir string) bool {
"go", "build", "go", "build",
"--ldflags", "-s -X github.com/rclone/rclone/fs.Version=" + version, "--ldflags", "-s -X github.com/rclone/rclone/fs.Version=" + version,
"-trimpath", "-trimpath",
"-i",
"-o", output, "-o", output,
"-tags", *tags, "-tags", *tags,
"..", "..",
@@ -325,7 +324,7 @@ func compileArch(version, goos, goarch, dir string) bool {
artifacts := []string{buildZip(dir)} artifacts := []string{buildZip(dir)}
// build a .deb and .rpm if appropriate // build a .deb and .rpm if appropriate
if goos == "linux" { if goos == "linux" {
artifacts = append(artifacts, buildDebAndRpm(dir, version, goarch)...) artifacts = append(artifacts, buildDebAndRpm(dir, version, stripVersion(goarch))...)
} }
if *copyAs != "" { if *copyAs != "" {
for _, artifact := range artifacts { for _, artifact := range artifacts {

View File

@@ -29,6 +29,7 @@ var (
func init() { func init() {
cmd.Root.AddCommand(commandDefinition) cmd.Root.AddCommand(commandDefinition)
cmdFlags := commandDefinition.Flags() cmdFlags := commandDefinition.Flags()
flags.BoolVarP(cmdFlags, &download, "download", "", download, "Check by downloading rather than with hash.")
AddFlags(cmdFlags) AddFlags(cmdFlags)
} }
@@ -50,7 +51,7 @@ the source match the files in the destination, not the other way
around. This means that extra files in the destination that are not in around. This means that extra files in the destination that are not in
the source will not be detected. the source will not be detected.
The |--differ|, |--missing-on-dst|, |--missing-on-src|, |--src-only| The |--differ|, |--missing-on-dst|, |--missing-on-src|, |--match|
and |--error| flags write paths, one per line, to the file name (or and |--error| flags write paths, one per line, to the file name (or
stdout if it is |-|) supplied. What they write is described in the stdout if it is |-|) supplied. What they write is described in the
help below. For example |--differ| will write all paths which are help below. For example |--differ| will write all paths which are

View File

@@ -14,7 +14,7 @@ func init() {
var commandDefinition = &cobra.Command{ var commandDefinition = &cobra.Command{
Use: "cleanup remote:path", Use: "cleanup remote:path",
Short: `Clean up the remote if possible`, Short: `Clean up the remote if possible.`,
Long: ` Long: `
Clean up the remote if possible. Empty the trash or delete old file Clean up the remote if possible. Empty the trash or delete old file
versions. Not supported by all remotes. versions. Not supported by all remotes.

View File

@@ -22,7 +22,7 @@ func init() {
var commandDefinition = &cobra.Command{ var commandDefinition = &cobra.Command{
Use: "copy source:path dest:path", Use: "copy source:path dest:path",
Short: `Copy files from source to dest, skipping already copied`, Short: `Copy files from source to dest, skipping already copied.`,
Long: ` Long: `
Copy the source to the destination. Doesn't transfer Copy the source to the destination. Doesn't transfer
unchanged files, testing by size and modification time or unchanged files, testing by size and modification time or

View File

@@ -15,7 +15,7 @@ func init() {
var commandDefinition = &cobra.Command{ var commandDefinition = &cobra.Command{
Use: "copyto source:path dest:path", Use: "copyto source:path dest:path",
Short: `Copy files from source to dest, skipping already copied`, Short: `Copy files from source to dest, skipping already copied.`,
Long: ` Long: `
If source:path is a file or directory then it copies it to a file or If source:path is a file or directory then it copies it to a file or
directory named dest:path. directory named dest:path.

View File

@@ -44,7 +44,7 @@ func init() {
var commandDefinition = &cobra.Command{ var commandDefinition = &cobra.Command{
Use: "lsf remote:path", Use: "lsf remote:path",
Short: `List directories and objects in remote:path formatted for parsing`, Short: `List directories and objects in remote:path formatted for parsing.`,
Long: ` Long: `
List the contents of the source path (directories and objects) to List the contents of the source path (directories and objects) to
standard output in a form which is easy to parse by scripts. By standard output in a form which is easy to parse by scripts. By

View File

@@ -67,8 +67,8 @@ func setAttr(node vfs.Node, attr *fuse.Attr) {
modTime := node.ModTime() modTime := node.ModTime()
// set attributes // set attributes
vfs := node.VFS() vfs := node.VFS()
attr.Owner.Gid = vfs.Opt.UID attr.Owner.Gid = vfs.Opt.GID
attr.Owner.Uid = vfs.Opt.GID attr.Owner.Uid = vfs.Opt.UID
attr.Mode = getMode(node) attr.Mode = getMode(node)
attr.Size = Size attr.Size = Size
attr.Nlink = 1 attr.Nlink = 1

View File

@@ -192,6 +192,9 @@ Stopping the mount manually:
# OS X # OS X
umount /path/to/local/mount umount /path/to/local/mount
**Note**: As of ` + "`rclone` 1.52.2, `rclone mount`" + ` now requires Go version 1.13
or newer on some platforms depending on the underlying FUSE library in use.
### Installing on Windows ### Installing on Windows
To run rclone ` + commandName + ` on Windows, you will need to To run rclone ` + commandName + ` on Windows, you will need to
@@ -333,9 +336,6 @@ With --vfs-read-chunk-size 100M and --vfs-read-chunk-size-limit 0 the following
parts will be downloaded: 0-100M, 100M-200M, 200M-300M, 300M-400M and so on. parts will be downloaded: 0-100M, 100M-200M, 200M-300M, 300M-400M and so on.
When --vfs-read-chunk-size-limit 500M is specified, the result would be When --vfs-read-chunk-size-limit 500M is specified, the result would be
0-100M, 100M-300M, 300M-700M, 700M-1200M, 1200M-1700M and so on. 0-100M, 100M-300M, 300M-700M, 700M-1200M, 1200M-1700M and so on.
Chunked reading will only work with --vfs-cache-mode < full, as the file will always
be copied to the vfs cache before opening with --vfs-cache-mode full.
` + vfs.Help, ` + vfs.Help,
Run: func(command *cobra.Command, args []string) { Run: func(command *cobra.Command, args []string) {
cmd.CheckArgs(2, 2, command, args) cmd.CheckArgs(2, 2, command, args)

View File

@@ -17,7 +17,7 @@ func init() {
var commandDefinition = &cobra.Command{ var commandDefinition = &cobra.Command{
Use: "obscure password", Use: "obscure password",
Short: `Obscure password for use in the rclone config file`, Short: `Obscure password for use in the rclone config file.`,
Long: `In the rclone config file, human readable passwords are Long: `In the rclone config file, human readable passwords are
obscured. Obscuring them is done by encrypting them and writing them obscured. Obscuring them is done by encrypting them and writing them
out in base64. This is **not** a secure way of encrypting these out in base64. This is **not** a secure way of encrypting these

View File

@@ -148,6 +148,7 @@ WebDAV or S3, that work out of the box.)
{{< provider name="StackPath" home="https://www.stackpath.com/products/object-storage/" config="/s3/#stackpath" >}} {{< provider name="StackPath" home="https://www.stackpath.com/products/object-storage/" config="/s3/#stackpath" >}}
{{< provider name="SugarSync" home="https://sugarsync.com/" config="/sugarsync/" >}} {{< provider name="SugarSync" home="https://sugarsync.com/" config="/sugarsync/" >}}
{{< provider name="Tardigrade" home="https://tardigrade.io/" config="/tardigrade/" >}} {{< provider name="Tardigrade" home="https://tardigrade.io/" config="/tardigrade/" >}}
{{< provider name="Tencent Cloud Object Storage (COS)" home="https://intl.cloud.tencent.com/product/cos" config="/s3/#tencent-cos" >}}
{{< provider name="Wasabi" home="https://wasabi.com/" config="/s3/#wasabi" >}} {{< provider name="Wasabi" home="https://wasabi.com/" config="/s3/#wasabi" >}}
{{< provider name="WebDAV" home="https://en.wikipedia.org/wiki/WebDAV" config="/webdav/" >}} {{< provider name="WebDAV" home="https://en.wikipedia.org/wiki/WebDAV" config="/webdav/" >}}
{{< provider name="Yandex Disk" home="https://disk.yandex.com/" config="/yandex/" >}} {{< provider name="Yandex Disk" home="https://disk.yandex.com/" config="/yandex/" >}}

View File

@@ -404,6 +404,7 @@ Note that Box is case insensitive so you can't have a file called
"Hello.doc" and one called "hello.doc". "Hello.doc" and one called "hello.doc".
Box file names can't have the `\` character in. rclone maps this to Box file names can't have the `\` character in. rclone maps this to
and from an identical looking unicode equivalent ``. and from an identical looking unicode equivalent `` (U+FF3C Fullwidth
Reverse Solidus).
Box only supports filenames up to 255 characters in length. Box only supports filenames up to 255 characters in length.

View File

@@ -5,6 +5,86 @@ description: "Rclone Changelog"
# Changelog # Changelog
## v1.53.2 - 2020-10-26
[See commits](https://github.com/rclone/rclone/compare/v1.53.1...v1.53.2)
* Bug Fixes
* acounting
* Fix incorrect speed and transferTime in core/stats (Nick Craig-Wood)
* Stabilize display order of transfers on Windows (Nick Craig-Wood)
* operations
* Fix use of --suffix without --backup-dir (Nick Craig-Wood)
* Fix spurious "--checksum is in use but the source and destination have no hashes in common" (Nick Craig-Wood)
* build
* Work around GitHub actions brew problem (Nick Craig-Wood)
* Stop using set-env and set-path in the GitHub actions (Nick Craig-Wood)
* Mount
* mount2: Fix the swapped UID / GID values (Russell Cattelan)
* VFS
* Detect and recover from a file being removed externally from the cache (Nick Craig-Wood)
* Fix a deadlock vulnerability in downloaders.Close (Leo Luan)
* Fix a race condition in retryFailedResets (Leo Luan)
* Fix missed concurrency control between some item operations and reset (Leo Luan)
* Add exponential backoff during ENOSPC retries (Leo Luan)
* Add a missed update of used cache space (Leo Luan)
* Fix --no-modtime to not attempt to set modtimes (as documented) (Nick Craig-Wood)
* Local
* Fix sizes and syncing with --links option on Windows (Nick Craig-Wood)
* Chunker
* Disable ListR to fix missing files on GDrive (workaround) (Ivan Andreev)
* Fix upload over crypt (Ivan Andreev)
* Fichier
* Increase maximum file size from 100GB to 300GB (gyutw)
* Jottacloud
* Remove clientSecret from config when upgrading to token based authentication (buengese)
* Avoid double url escaping of device/mountpoint (albertony)
* Remove DirMove workaround as it's not required anymore - also (buengese)
* Mailru
* Fix uploads after recent changes on server (Ivan Andreev)
* Fix range requests after june changes on server (Ivan Andreev)
* Fix invalid timestamp on corrupted files (fixes) (Ivan Andreev)
* Onedrive
* Fix disk usage for sharepoint (Nick Craig-Wood)
* S3
* Add missing regions for AWS (Anagh Kumar Baranwal)
* Seafile
* Fix accessing libraries > 2GB on 32 bit systems (Muffin King)
* SFTP
* Always convert the checksum to lower case (buengese)
* Union
* Create root directories if none exist (Nick Craig-Wood)
## v1.53.1 - 2020-09-13
[See commits](https://github.com/rclone/rclone/compare/v1.53.0...v1.53.1)
* Bug Fixes
* accounting: Remove new line from end of --stats-one-line display (Nick Craig-Wood)
* check
* Add back missing --download flag (Nick Craig-Wood)
* Fix docs (Nick Craig-Wood)
* docs
* Note --log-file does append (Nick Craig-Wood)
* Add full stops for consistency in rclone --help (edwardxml)
* Add Tencent COS to s3 provider list (wjielai)
* Updated mount command to reflect that it requires Go 1.13 or newer (Evan Harris)
* jottacloud: Mention that uploads from local disk will not need to cache files to disk for md5 calculation (albertony)
* Fix formatting of rc docs page (Nick Craig-Wood)
* build
* Include vendor tar ball in release and fix startdev (Nick Craig-Wood)
* Fix "Illegal instruction" error for ARMv6 builds (Nick Craig-Wood)
* Fix architecture name in ARMv7 build (Nick Craig-Wood)
* VFS
* Fix spurious error "vfs cache: failed to _ensure cache EOF" (Nick Craig-Wood)
* Log an ERROR if we fail to set the file to be sparse (Nick Craig-Wood)
* Local
* Log an ERROR if we fail to set the file to be sparse (Nick Craig-Wood)
* Drive
* Re-adds special oauth help text (Tim Gallant)
* Opendrive
* Do not retry 400 errors (Evan Harris)
## v1.53.0 - 2020-09-02 ## v1.53.0 - 2020-09-02
[See commits](https://github.com/rclone/rclone/compare/v1.52.0...v1.53.0) [See commits](https://github.com/rclone/rclone/compare/v1.52.0...v1.53.0)

View File

@@ -39,10 +39,10 @@ See the [global flags page](/flags/) for global options not listed here.
* [rclone backend](/commands/rclone_backend/) - Run a backend specific command. * [rclone backend](/commands/rclone_backend/) - Run a backend specific command.
* [rclone cat](/commands/rclone_cat/) - Concatenates any files and sends them to stdout. * [rclone cat](/commands/rclone_cat/) - Concatenates any files and sends them to stdout.
* [rclone check](/commands/rclone_check/) - Checks the files in the source and destination match. * [rclone check](/commands/rclone_check/) - Checks the files in the source and destination match.
* [rclone cleanup](/commands/rclone_cleanup/) - Clean up the remote if possible * [rclone cleanup](/commands/rclone_cleanup/) - Clean up the remote if possible.
* [rclone config](/commands/rclone_config/) - Enter an interactive configuration session. * [rclone config](/commands/rclone_config/) - Enter an interactive configuration session.
* [rclone copy](/commands/rclone_copy/) - Copy files from source to dest, skipping already copied * [rclone copy](/commands/rclone_copy/) - Copy files from source to dest, skipping already copied.
* [rclone copyto](/commands/rclone_copyto/) - Copy files from source to dest, skipping already copied * [rclone copyto](/commands/rclone_copyto/) - Copy files from source to dest, skipping already copied.
* [rclone copyurl](/commands/rclone_copyurl/) - Copy url content to dest. * [rclone copyurl](/commands/rclone_copyurl/) - Copy url content to dest.
* [rclone cryptcheck](/commands/rclone_cryptcheck/) - Cryptcheck checks the integrity of a crypted remote. * [rclone cryptcheck](/commands/rclone_cryptcheck/) - Cryptcheck checks the integrity of a crypted remote.
* [rclone cryptdecode](/commands/rclone_cryptdecode/) - Cryptdecode returns unencrypted file names. * [rclone cryptdecode](/commands/rclone_cryptdecode/) - Cryptdecode returns unencrypted file names.
@@ -56,7 +56,7 @@ See the [global flags page](/flags/) for global options not listed here.
* [rclone listremotes](/commands/rclone_listremotes/) - List all the remotes in the config file. * [rclone listremotes](/commands/rclone_listremotes/) - List all the remotes in the config file.
* [rclone ls](/commands/rclone_ls/) - List the objects in the path with size and path. * [rclone ls](/commands/rclone_ls/) - List the objects in the path with size and path.
* [rclone lsd](/commands/rclone_lsd/) - List all directories/containers/buckets in the path. * [rclone lsd](/commands/rclone_lsd/) - List all directories/containers/buckets in the path.
* [rclone lsf](/commands/rclone_lsf/) - List directories and objects in remote:path formatted for parsing * [rclone lsf](/commands/rclone_lsf/) - List directories and objects in remote:path formatted for parsing.
* [rclone lsjson](/commands/rclone_lsjson/) - List directories and objects in the path in JSON format. * [rclone lsjson](/commands/rclone_lsjson/) - List directories and objects in the path in JSON format.
* [rclone lsl](/commands/rclone_lsl/) - List the objects in path with modification time, size and path. * [rclone lsl](/commands/rclone_lsl/) - List the objects in path with modification time, size and path.
* [rclone md5sum](/commands/rclone_md5sum/) - Produces an md5sum file for all the objects in the path. * [rclone md5sum](/commands/rclone_md5sum/) - Produces an md5sum file for all the objects in the path.
@@ -65,7 +65,7 @@ See the [global flags page](/flags/) for global options not listed here.
* [rclone move](/commands/rclone_move/) - Move files from source to dest. * [rclone move](/commands/rclone_move/) - Move files from source to dest.
* [rclone moveto](/commands/rclone_moveto/) - Move file or directory from source to dest. * [rclone moveto](/commands/rclone_moveto/) - Move file or directory from source to dest.
* [rclone ncdu](/commands/rclone_ncdu/) - Explore a remote with a text based user interface. * [rclone ncdu](/commands/rclone_ncdu/) - Explore a remote with a text based user interface.
* [rclone obscure](/commands/rclone_obscure/) - Obscure password for use in the rclone config file * [rclone obscure](/commands/rclone_obscure/) - Obscure password for use in the rclone config file.
* [rclone purge](/commands/rclone_purge/) - Remove the path and all of its contents. * [rclone purge](/commands/rclone_purge/) - Remove the path and all of its contents.
* [rclone rc](/commands/rclone_rc/) - Run a command against a running rclone. * [rclone rc](/commands/rclone_rc/) - Run a command against a running rclone.
* [rclone rcat](/commands/rclone_rcat/) - Copies standard input to file on remote. * [rclone rcat](/commands/rclone_rcat/) - Copies standard input to file on remote.

View File

@@ -29,7 +29,7 @@ the source match the files in the destination, not the other way
around. This means that extra files in the destination that are not in around. This means that extra files in the destination that are not in
the source will not be detected. the source will not be detected.
The `--differ`, `--missing-on-dst`, `--missing-on-src`, `--src-only` The `--differ`, `--missing-on-dst`, `--missing-on-src`, `--match`
and `--error` flags write paths, one per line, to the file name (or and `--error` flags write paths, one per line, to the file name (or
stdout if it is `-`) supplied. What they write is described in the stdout if it is `-`) supplied. What they write is described in the
help below. For example `--differ` will write all paths which are help below. For example `--differ` will write all paths which are
@@ -55,6 +55,7 @@ rclone check source:path dest:path [flags]
``` ```
--combined string Make a combined report of changes to this file --combined string Make a combined report of changes to this file
--differ string Report all non-matching files to this file --differ string Report all non-matching files to this file
--download Check by downloading rather than with hash.
--error string Report all files with errors (hashing or reading) to this file --error string Report all files with errors (hashing or reading) to this file
-h, --help help for check -h, --help help for check
--match string Report all matching files to this file --match string Report all matching files to this file

View File

@@ -1,13 +1,13 @@
--- ---
title: "rclone cleanup" title: "rclone cleanup"
description: "Clean up the remote if possible" description: "Clean up the remote if possible."
slug: rclone_cleanup slug: rclone_cleanup
url: /commands/rclone_cleanup/ url: /commands/rclone_cleanup/
# autogenerated - DO NOT EDIT, instead edit the source code in cmd/cleanup/ and as part of making a release run "make commanddocs" # autogenerated - DO NOT EDIT, instead edit the source code in cmd/cleanup/ and as part of making a release run "make commanddocs"
--- ---
# rclone cleanup # rclone cleanup
Clean up the remote if possible Clean up the remote if possible.
## Synopsis ## Synopsis

View File

@@ -1,13 +1,13 @@
--- ---
title: "rclone copy" title: "rclone copy"
description: "Copy files from source to dest, skipping already copied" description: "Copy files from source to dest, skipping already copied."
slug: rclone_copy slug: rclone_copy
url: /commands/rclone_copy/ url: /commands/rclone_copy/
# autogenerated - DO NOT EDIT, instead edit the source code in cmd/copy/ and as part of making a release run "make commanddocs" # autogenerated - DO NOT EDIT, instead edit the source code in cmd/copy/ and as part of making a release run "make commanddocs"
--- ---
# rclone copy # rclone copy
Copy files from source to dest, skipping already copied Copy files from source to dest, skipping already copied.
## Synopsis ## Synopsis

View File

@@ -1,13 +1,13 @@
--- ---
title: "rclone copyto" title: "rclone copyto"
description: "Copy files from source to dest, skipping already copied" description: "Copy files from source to dest, skipping already copied."
slug: rclone_copyto slug: rclone_copyto
url: /commands/rclone_copyto/ url: /commands/rclone_copyto/
# autogenerated - DO NOT EDIT, instead edit the source code in cmd/copyto/ and as part of making a release run "make commanddocs" # autogenerated - DO NOT EDIT, instead edit the source code in cmd/copyto/ and as part of making a release run "make commanddocs"
--- ---
# rclone copyto # rclone copyto
Copy files from source to dest, skipping already copied Copy files from source to dest, skipping already copied.
## Synopsis ## Synopsis

View File

@@ -40,7 +40,7 @@ the source match the files in the destination, not the other way
around. This means that extra files in the destination that are not in around. This means that extra files in the destination that are not in
the source will not be detected. the source will not be detected.
The `--differ`, `--missing-on-dst`, `--missing-on-src`, `--src-only` The `--differ`, `--missing-on-dst`, `--missing-on-src`, `--match`
and `--error` flags write paths, one per line, to the file name (or and `--error` flags write paths, one per line, to the file name (or
stdout if it is `-`) supplied. What they write is described in the stdout if it is `-`) supplied. What they write is described in the
help below. For example `--differ` will write all paths which are help below. For example `--differ` will write all paths which are

View File

@@ -1,13 +1,13 @@
--- ---
title: "rclone lsf" title: "rclone lsf"
description: "List directories and objects in remote:path formatted for parsing" description: "List directories and objects in remote:path formatted for parsing."
slug: rclone_lsf slug: rclone_lsf
url: /commands/rclone_lsf/ url: /commands/rclone_lsf/
# autogenerated - DO NOT EDIT, instead edit the source code in cmd/lsf/ and as part of making a release run "make commanddocs" # autogenerated - DO NOT EDIT, instead edit the source code in cmd/lsf/ and as part of making a release run "make commanddocs"
--- ---
# rclone lsf # rclone lsf
List directories and objects in remote:path formatted for parsing List directories and objects in remote:path formatted for parsing.
## Synopsis ## Synopsis

View File

@@ -49,6 +49,9 @@ Stopping the mount manually:
# OS X # OS X
umount /path/to/local/mount umount /path/to/local/mount
**Note**: As of `rclone` 1.52.2, `rclone mount` now requires Go version 1.13
or newer on some platforms depending on the underlying FUSE library in use.
## Installing on Windows ## Installing on Windows
To run rclone mount on Windows, you will need to To run rclone mount on Windows, you will need to
@@ -191,9 +194,6 @@ parts will be downloaded: 0-100M, 100M-200M, 200M-300M, 300M-400M and so on.
When --vfs-read-chunk-size-limit 500M is specified, the result would be When --vfs-read-chunk-size-limit 500M is specified, the result would be
0-100M, 100M-300M, 300M-700M, 700M-1200M, 1200M-1700M and so on. 0-100M, 100M-300M, 300M-700M, 700M-1200M, 1200M-1700M and so on.
Chunked reading will only work with --vfs-cache-mode < full, as the file will always
be copied to the vfs cache before opening with --vfs-cache-mode full.
## VFS - Virtual File System ## VFS - Virtual File System
This command uses the VFS layer. This adapts the cloud storage objects This command uses the VFS layer. This adapts the cloud storage objects
@@ -357,6 +357,11 @@ whereas the --vfs-read-ahead is buffered on disk.
When using this mode it is recommended that --buffer-size is not set When using this mode it is recommended that --buffer-size is not set
too big and --vfs-read-ahead is set large if required. too big and --vfs-read-ahead is set large if required.
**IMPORTANT** not all file systems support sparse files. In particular
FAT/exFAT do not. Rclone will perform very badly if the cache
directory is on a filesystem which doesn't support sparse files and it
will log an ERROR message if one is detected.
## VFS Performance ## VFS Performance
These flags may be used to enable/disable features of the VFS for These flags may be used to enable/disable features of the VFS for

View File

@@ -1,13 +1,13 @@
--- ---
title: "rclone obscure" title: "rclone obscure"
description: "Obscure password for use in the rclone config file" description: "Obscure password for use in the rclone config file."
slug: rclone_obscure slug: rclone_obscure
url: /commands/rclone_obscure/ url: /commands/rclone_obscure/
# autogenerated - DO NOT EDIT, instead edit the source code in cmd/obscure/ and as part of making a release run "make commanddocs" # autogenerated - DO NOT EDIT, instead edit the source code in cmd/obscure/ and as part of making a release run "make commanddocs"
--- ---
# rclone obscure # rclone obscure
Obscure password for use in the rclone config file Obscure password for use in the rclone config file.
## Synopsis ## Synopsis

View File

@@ -196,6 +196,11 @@ whereas the --vfs-read-ahead is buffered on disk.
When using this mode it is recommended that --buffer-size is not set When using this mode it is recommended that --buffer-size is not set
too big and --vfs-read-ahead is set large if required. too big and --vfs-read-ahead is set large if required.
**IMPORTANT** not all file systems support sparse files. In particular
FAT/exFAT do not. Rclone will perform very badly if the cache
directory is on a filesystem which doesn't support sparse files and it
will log an ERROR message if one is detected.
## VFS Performance ## VFS Performance
These flags may be used to enable/disable features of the VFS for These flags may be used to enable/disable features of the VFS for

View File

@@ -195,6 +195,11 @@ whereas the --vfs-read-ahead is buffered on disk.
When using this mode it is recommended that --buffer-size is not set When using this mode it is recommended that --buffer-size is not set
too big and --vfs-read-ahead is set large if required. too big and --vfs-read-ahead is set large if required.
**IMPORTANT** not all file systems support sparse files. In particular
FAT/exFAT do not. Rclone will perform very badly if the cache
directory is on a filesystem which doesn't support sparse files and it
will log an ERROR message if one is detected.
## VFS Performance ## VFS Performance
These flags may be used to enable/disable features of the VFS for These flags may be used to enable/disable features of the VFS for

View File

@@ -267,6 +267,11 @@ whereas the --vfs-read-ahead is buffered on disk.
When using this mode it is recommended that --buffer-size is not set When using this mode it is recommended that --buffer-size is not set
too big and --vfs-read-ahead is set large if required. too big and --vfs-read-ahead is set large if required.
**IMPORTANT** not all file systems support sparse files. In particular
FAT/exFAT do not. Rclone will perform very badly if the cache
directory is on a filesystem which doesn't support sparse files and it
will log an ERROR message if one is detected.
## VFS Performance ## VFS Performance
These flags may be used to enable/disable features of the VFS for These flags may be used to enable/disable features of the VFS for

View File

@@ -206,6 +206,11 @@ whereas the --vfs-read-ahead is buffered on disk.
When using this mode it is recommended that --buffer-size is not set When using this mode it is recommended that --buffer-size is not set
too big and --vfs-read-ahead is set large if required. too big and --vfs-read-ahead is set large if required.
**IMPORTANT** not all file systems support sparse files. In particular
FAT/exFAT do not. Rclone will perform very badly if the cache
directory is on a filesystem which doesn't support sparse files and it
will log an ERROR message if one is detected.
## VFS Performance ## VFS Performance
These flags may be used to enable/disable features of the VFS for These flags may be used to enable/disable features of the VFS for

View File

@@ -275,6 +275,11 @@ whereas the --vfs-read-ahead is buffered on disk.
When using this mode it is recommended that --buffer-size is not set When using this mode it is recommended that --buffer-size is not set
too big and --vfs-read-ahead is set large if required. too big and --vfs-read-ahead is set large if required.
**IMPORTANT** not all file systems support sparse files. In particular
FAT/exFAT do not. Rclone will perform very badly if the cache
directory is on a filesystem which doesn't support sparse files and it
will log an ERROR message if one is detected.
## VFS Performance ## VFS Performance
These flags may be used to enable/disable features of the VFS for These flags may be used to enable/disable features of the VFS for

View File

@@ -6,23 +6,26 @@ description: "Encryption overlay remote"
{{< icon "fa fa-lock" >}}Crypt {{< icon "fa fa-lock" >}}Crypt
---------------------------------------- ----------------------------------------
The `crypt` remote encrypts and decrypts another remote. Rclone `crypt` remotes encrypt and decrypt other remotes.
To use it first set up the underlying remote following the config To use `crypt`, first set up the underlying remote. Follow the `rclone
instructions for that remote. You can also use a local pathname config` instructions for that remote.
instead of a remote which will encrypt and decrypt from that directory
which might be useful for encrypting onto a USB stick for example.
First check your chosen remote is working - we'll call it `crypt` applied to a local pathname instead of a remote will
`remote:path` in these docs. Note that anything inside `remote:path` encrypt and decrypt that directory, and can be used to encrypt USB
will be encrypted and anything outside won't. This means that if you removable drives.
are using a bucket based remote (eg S3, B2, swift) then you should
probably put the bucket in the remote `s3:bucket`. If you just use
`s3:` then rclone will make encrypted bucket names too (if using file
name encryption) which may or may not be what you want.
Now configure `crypt` using `rclone config`. We will call this one Before configuring the crypt remote, check the underlying remote is
`secret` to differentiate it from the `remote`. working. In this example the underlying remote is called `remote:path`.
Anything inside `remote:path` will be encrypted and anything outside
will not. In the case of an S3 based underlying remote (eg Amazon S3,
B2, Swift) it is generally advisable to define a crypt remote in the
underlying remote `s3:bucket`. If `s3:` alone is specified alongside
file name encryption, rclone will encrypt the bucket name.
Configure `crypt` using `rclone config`. In this example the `crypt`
remote is called `secret`, to differentiate it from the underlying
`remote`.
``` ```
No remotes found - make a new one No remotes found - make a new one
@@ -96,49 +99,42 @@ d) Delete this remote
y/e/d> y y/e/d> y
``` ```
**Important** The password is stored in the config file is lightly **Important** The crypt password stored in `rclone.conf` is lightly
obscured so it isn't immediately obvious what it is. It is in no way obscured. That only protects it from cursory inspection. It is not
secure unless you use config file encryption. secure unless encryption of `rclone.conf` is specified.
A long passphrase is recommended, or you can use a random one. A long passphrase is recommended, or `rclone config` can generate a
random one.
The obscured password is created by using AES-CTR with a static key, with The obscured password is created using AES-CTR with a static key. The
the salt stored verbatim at the beginning of the obscured password. This salt is stored verbatim at the beginning of the obscured password. This
static key is shared by between all versions of rclone. static key is shared between all versions of rclone.
If you reconfigure rclone with the same passwords/passphrases If you reconfigure rclone with the same passwords/passphrases
elsewhere it will be compatible, but the obscured version will be different elsewhere it will be compatible, but the obscured version will be different
due to the different salt. due to the different salt.
Note that rclone does not encrypt Rclone does not encrypt
* file length - this can be calculated within 16 bytes * file length - this can be calculated within 16 bytes
* modification time - used for syncing * modification time - used for syncing
## Specifying the remote ## ## Specifying the remote ##
In normal use, make sure the remote has a `:` in. If you specify the In normal use, ensure the remote has a `:` in. If specified without,
remote without a `:` then rclone will use a local directory of that rclone uses a local directory of that name. For example if a remote
name. So if you use a remote of `/path/to/secret/files` then rclone `/path/to/secret/files` is specified, rclone encrypts content to that
will encrypt stuff to that directory. If you use a remote of `name` directory. If a remote `name` is specified, rclone targets a directory
then rclone will put files in a directory called `name` in the current `name` in the current directory.
directory.
If you specify the remote as `remote:path/to/dir` then rclone will If remote `remote:path/to/dir` is specified, rclone stores encrypted
store encrypted files in `path/to/dir` on the remote. If you are using files in `path/to/dir` on the remote. With file name encryption, files
file name encryption, then when you save files to saved to `secret:subdir/subfile` are stored in the unencrypted path
`secret:subdir/subfile` this will store them in the unencrypted path `path/to/dir` but the `subdir/subpath` element is encrypted.
`path/to/dir` but the `subdir/subpath` bit will be encrypted.
Note that unless you want encrypted bucket names (which are difficult
to manage because you won't know what directory they represent in web
interfaces etc), you should probably specify a bucket, eg
`remote:secretbucket` when using bucket based remotes such as S3,
Swift, Hubic, B2, GCS.
## Example ## ## Example ##
To test I made a little directory of files using "standard" file name Create the following file structure using "standard" file name
encryption. encryption.
``` ```
@@ -152,7 +148,7 @@ plaintext/
└── file4.txt └── file4.txt
``` ```
Copy these to the remote and list them back Copy these to the remote, and list them
``` ```
$ rclone -q copy plaintext secret: $ rclone -q copy plaintext secret:
@@ -164,7 +160,7 @@ $ rclone -q ls secret:
9 subdir/file3.txt 9 subdir/file3.txt
``` ```
Now see what that looked like when encrypted The crypt remote looks like
``` ```
$ rclone -q ls remote:path $ rclone -q ls remote:path
@@ -175,7 +171,7 @@ $ rclone -q ls remote:path
56 86vhrsv86mpbtd3a0akjuqslj8/8njh1sk437gttmep3p70g81aps 56 86vhrsv86mpbtd3a0akjuqslj8/8njh1sk437gttmep3p70g81aps
``` ```
Note that this retains the directory structure which means you can do this The directory structure is preserved
``` ```
$ rclone -q ls secret:subdir $ rclone -q ls secret:subdir
@@ -184,9 +180,9 @@ $ rclone -q ls secret:subdir
10 subsubdir/file4.txt 10 subsubdir/file4.txt
``` ```
If don't use file name encryption then the remote will look like this Without file name encryption `.bin` extensions are added to underlying
- note the `.bin` extensions added to prevent the cloud provider names. This prevents the cloud provider attempting to interpret file
attempting to interpret the data. content.
``` ```
$ rclone -q ls remote:path $ rclone -q ls remote:path
@@ -199,8 +195,6 @@ $ rclone -q ls remote:path
### File name encryption modes ### ### File name encryption modes ###
Here are some of the features of the file name encryption modes
Off Off
* doesn't hide file names or directory structure * doesn't hide file names or directory structure
@@ -219,17 +213,19 @@ Standard
Obfuscation Obfuscation
This is a simple "rotate" of the filename, with each file having a rot This is a simple "rotate" of the filename, with each file having a rot
distance based on the filename. We store the distance at the beginning distance based on the filename. Rclone stores the distance at the
of the filename. So a file called "hello" may become "53.jgnnq". beginning of the filename. A file called "hello" may become "53.jgnnq".
This is not a strong encryption of filenames, but it may stop automated Obfuscation is not a strong encryption of filenames, but hinders
scanning tools from picking up on filename patterns. As such it's an automated scanning tools picking up on filename patterns. It is an
intermediate between "off" and "standard". The advantage is that it intermediate between "off" and "standard" which allows for longer path
allows for longer path segment names. segment names.
There is a possibility with some unicode based filenames that the There is a possibility with some unicode based filenames that the
obfuscation is weak and may map lower case characters to upper case obfuscation is weak and may map lower case characters to upper case
equivalents. You can not rely on this for strong protection. equivalents.
Obfuscation cannot be relied upon for strong protection.
* file names very lightly obfuscated * file names very lightly obfuscated
* file names can be longer than standard encryption * file names can be longer than standard encryption
@@ -237,13 +233,14 @@ equivalents. You can not rely on this for strong protection.
* directory structure visible * directory structure visible
* identical files names will have identical uploaded names * identical files names will have identical uploaded names
Cloud storage systems have various limits on file name length and Cloud storage systems have limits on file name length and
total path length which you are more likely to hit using "Standard" total path length which rclone is more likely to breach using
file name encryption. If you keep your file names to below 156 "Standard" file name encryption. Where file names are less thn 156
characters in length then you should be OK on all providers. characters in length issues should not be encountered, irrespective of
cloud storage provider.
There may be an even more secure file name encryption mode in the An alternative, future rclone file name encryption mode may tolerate
future which will address the long file name problem. backend provider path length limits.
### Directory name encryption ### ### Directory name encryption ###
Crypt offers the option of encrypting dir names or leaving them intact. Crypt offers the option of encrypting dir names or leaving them intact.
@@ -272,7 +269,7 @@ depends on that.
Hashes are not stored for crypt. However the data integrity is Hashes are not stored for crypt. However the data integrity is
protected by an extremely strong crypto authenticator. protected by an extremely strong crypto authenticator.
Note that you should use the `rclone cryptcheck` command to check the Use the `rclone cryptcheck` command to check the
integrity of a crypted remote instead of `rclone check` which can't integrity of a crypted remote instead of `rclone check` which can't
check the checksums properly. check the checksums properly.

View File

@@ -757,6 +757,8 @@ This can be useful for tracking down problems with syncs in
combination with the `-v` flag. See the [Logging section](#logging) combination with the `-v` flag. See the [Logging section](#logging)
for more info. for more info.
If FILE exists then rclone will append to it.
Note that if you are using the `logrotate` program to manage rclone's Note that if you are using the `logrotate` program to manage rclone's
logs, then you should use the `copytruncate` option as rclone doesn't logs, then you should use the `copytruncate` option as rclone doesn't
have a signal to rotate logs. have a signal to rotate logs.
@@ -1251,11 +1253,17 @@ or with `--backup-dir`. See `--backup-dir` for more info.
For example For example
rclone sync -i /path/to/local/file remote:current --suffix .bak rclone copy -i /path/to/local/file remote:current --suffix .bak
will sync `/path/to/local` to `remote:current`, but for any files will copy `/path/to/local` to `remote:current`, but for any files
which would have been updated or deleted have .bak added. which would have been updated or deleted have .bak added.
If using `rclone sync` with `--suffix` and without `--backup-dir` then
it is recommended to put a filter rule in excluding the suffix
otherwise the `sync` will delete the backup files.
rclone sync -i /path/to/local/file remote:current --suffix .bak --exclude "*.bak"
### --suffix-keep-extension ### ### --suffix-keep-extension ###
When using `--suffix`, setting this causes rclone put the SUFFIX When using `--suffix`, setting this causes rclone put the SUFFIX

View File

@@ -547,8 +547,10 @@ Here are the standard options specific to drive (Google Drive).
#### --drive-client-id #### --drive-client-id
OAuth Client Id Google Application Client Id
Leave blank normally. Setting your own is recommended.
See https://rclone.org/drive/#making-your-own-client-id for how to create your own.
If you leave this blank, it will use an internal key which is low performance.
- Config: client_id - Config: client_id
- Env Var: RCLONE_DRIVE_CLIENT_ID - Env Var: RCLONE_DRIVE_CLIENT_ID

View File

@@ -147,7 +147,7 @@ These flags are available for every command.
--use-json-log Use json log format. --use-json-log Use json log format.
--use-mmap Use mmap allocator (see docs). --use-mmap Use mmap allocator (see docs).
--use-server-modtime Use server modified time instead of object metadata --use-server-modtime Use server modified time instead of object metadata
--user-agent string Set the user-agent to a specified string. The default is rclone/ version (default "rclone/v1.53.0") --user-agent string Set the user-agent to a specified string. The default is rclone/ version (default "rclone/v1.53.2")
-v, --verbose count Print lots more stuff (repeat for more) -v, --verbose count Print lots more stuff (repeat for more)
``` ```
@@ -246,7 +246,7 @@ and may be set in the config file.
--drive-auth-owner-only Only consider files owned by the authenticated user. --drive-auth-owner-only Only consider files owned by the authenticated user.
--drive-auth-url string Auth server URL. --drive-auth-url string Auth server URL.
--drive-chunk-size SizeSuffix Upload chunk size. Must a power of 2 >= 256k. (default 8M) --drive-chunk-size SizeSuffix Upload chunk size. Must a power of 2 >= 256k. (default 8M)
--drive-client-id string OAuth Client Id --drive-client-id string Google Application Client Id
--drive-client-secret string OAuth Client Secret --drive-client-secret string OAuth Client Secret
--drive-disable-http2 Disable drive using http2 (default true) --drive-disable-http2 Disable drive using http2 (default true)
--drive-encoding MultiEncoder This sets the encoding for the backend. (default InvalidUtf8) --drive-encoding MultiEncoder This sets the encoding for the backend. (default InvalidUtf8)

View File

@@ -150,6 +150,11 @@ source does not have an MD5 checksum then the file will be cached
temporarily on disk (wherever the `TMPDIR` environment variable points temporarily on disk (wherever the `TMPDIR` environment variable points
to) before it is uploaded. Small files will be cached in memory - see to) before it is uploaded. Small files will be cached in memory - see
the [--jottacloud-md5-memory-limit](#jottacloud-md5-memory-limit) flag. the [--jottacloud-md5-memory-limit](#jottacloud-md5-memory-limit) flag.
When uploading from local disk the source checksum is always available,
so this does not apply. Starting with rclone version 1.52 the same is
true for crypted remotes (in older versions the crypt backend would not
calculate hashes for uploads from local disk, so the Jottacloud
backend had to do it as described above).
#### Restricted filename characters #### Restricted filename characters

View File

@@ -537,6 +537,8 @@ OR
"result": "<Raw command line output>" "result": "<Raw command line output>"
} }
```
**Authentication is required for this call.** **Authentication is required for this call.**
### core/gc: Runs a garbage collection. {#core-gc} ### core/gc: Runs a garbage collection. {#core-gc}
@@ -1212,7 +1214,7 @@ This allows you to remove a plugin using it's name
This takes parameters This takes parameters
- name: name of the plugin in the format <author>/<plugin_name> - name: name of the plugin in the format `author`/`plugin_name`
Eg Eg
@@ -1226,7 +1228,7 @@ This allows you to remove a plugin using it's name
This takes the following parameters This takes the following parameters
- name: name of the plugin in the format <author>/<plugin_name> - name: name of the plugin in the format `author`/`plugin_name`
Eg Eg

View File

@@ -18,6 +18,7 @@ The S3 backend can be used with a number of different providers:
{{< provider name="Minio" home="https://www.minio.io/" config="/s3/#minio" >}} {{< provider name="Minio" home="https://www.minio.io/" config="/s3/#minio" >}}
{{< provider name="Scaleway" home="https://www.scaleway.com/en/object-storage/" config="/s3/#scaleway" >}} {{< provider name="Scaleway" home="https://www.scaleway.com/en/object-storage/" config="/s3/#scaleway" >}}
{{< provider name="StackPath" home="https://www.stackpath.com/products/object-storage/" config="/s3/#stackpath" >}} {{< provider name="StackPath" home="https://www.stackpath.com/products/object-storage/" config="/s3/#stackpath" >}}
{{< provider name="Tencent Cloud Object Storage (COS)" home="https://intl.cloud.tencent.com/product/cos" config="/s3/#tencent-cos" >}}
{{< provider name="Wasabi" home="https://wasabi.com/" config="/s3/#wasabi" end="true" >}} {{< provider name="Wasabi" home="https://wasabi.com/" config="/s3/#wasabi" end="true" >}}
{{< /provider_list >}} {{< /provider_list >}}
@@ -138,7 +139,7 @@ Choose a number from below, or type in your own value
/ Asia Pacific (Mumbai) / Asia Pacific (Mumbai)
13 | Needs location constraint ap-south-1. 13 | Needs location constraint ap-south-1.
\ "ap-south-1" \ "ap-south-1"
/ Asia Patific (Hong Kong) Region / Asia Pacific (Hong Kong) Region
14 | Needs location constraint ap-east-1. 14 | Needs location constraint ap-east-1.
\ "ap-east-1" \ "ap-east-1"
/ South America (Sao Paulo) Region / South America (Sao Paulo) Region
@@ -455,7 +456,7 @@ Vault API, so rclone cannot directly access Glacier Vaults.
{{< rem autogenerated options start" - DO NOT EDIT - instead edit fs.RegInfo in backend/s3/s3.go then run make backenddocs" >}} {{< rem autogenerated options start" - DO NOT EDIT - instead edit fs.RegInfo in backend/s3/s3.go then run make backenddocs" >}}
### Standard Options ### Standard Options
Here are the standard options specific to s3 (Amazon S3 Compliant Storage Provider (AWS, Alibaba, Ceph, Digital Ocean, Dreamhost, IBM COS, Minio, etc)). Here are the standard options specific to s3 (Amazon S3 Compliant Storage Provider (AWS, Alibaba, Ceph, Digital Ocean, Dreamhost, IBM COS, Minio, Tencent COS, etc)).
#### --s3-provider #### --s3-provider
@@ -486,6 +487,8 @@ Choose your S3 provider.
- Scaleway Object Storage - Scaleway Object Storage
- "StackPath" - "StackPath"
- StackPath Object Storage - StackPath Object Storage
- "TencentCOS"
- Tencent Cloud Object Storage (COS)
- "Wasabi" - "Wasabi"
- Wasabi Object Storage - Wasabi Object Storage
- "Other" - "Other"
@@ -542,12 +545,12 @@ Region to connect to.
- "us-east-2" - "us-east-2"
- US East (Ohio) Region - US East (Ohio) Region
- Needs location constraint us-east-2. - Needs location constraint us-east-2.
- "us-west-2"
- US West (Oregon) Region
- Needs location constraint us-west-2.
- "us-west-1" - "us-west-1"
- US West (Northern California) Region - US West (Northern California) Region
- Needs location constraint us-west-1. - Needs location constraint us-west-1.
- "us-west-2"
- US West (Oregon) Region
- Needs location constraint us-west-2.
- "ca-central-1" - "ca-central-1"
- Canada (Central) Region - Canada (Central) Region
- Needs location constraint ca-central-1. - Needs location constraint ca-central-1.
@@ -557,9 +560,15 @@ Region to connect to.
- "eu-west-2" - "eu-west-2"
- EU (London) Region - EU (London) Region
- Needs location constraint eu-west-2. - Needs location constraint eu-west-2.
- "eu-west-3"
- EU (Paris) Region
- Needs location constraint eu-west-3.
- "eu-north-1" - "eu-north-1"
- EU (Stockholm) Region - EU (Stockholm) Region
- Needs location constraint eu-north-1. - Needs location constraint eu-north-1.
- "eu-south-1"
- EU (Milan) Region
- Needs location constraint eu-south-1.
- "eu-central-1" - "eu-central-1"
- EU (Frankfurt) Region - EU (Frankfurt) Region
- Needs location constraint eu-central-1. - Needs location constraint eu-central-1.
@@ -575,15 +584,36 @@ Region to connect to.
- "ap-northeast-2" - "ap-northeast-2"
- Asia Pacific (Seoul) - Asia Pacific (Seoul)
- Needs location constraint ap-northeast-2. - Needs location constraint ap-northeast-2.
- "ap-northeast-3"
- Asia Pacific (Osaka-Local)
- Needs location constraint ap-northeast-3.
- "ap-south-1" - "ap-south-1"
- Asia Pacific (Mumbai) - Asia Pacific (Mumbai)
- Needs location constraint ap-south-1. - Needs location constraint ap-south-1.
- "ap-east-1" - "ap-east-1"
- Asia Patific (Hong Kong) Region - Asia Pacific (Hong Kong) Region
- Needs location constraint ap-east-1. - Needs location constraint ap-east-1.
- "sa-east-1" - "sa-east-1"
- South America (Sao Paulo) Region - South America (Sao Paulo) Region
- Needs location constraint sa-east-1. - Needs location constraint sa-east-1.
- "me-south-1"
- Middle East (Bahrain) Region
- Needs location constraint me-south-1.
- "af-south-1"
- Africa (Cape Town) Region
- Needs location constraint af-south-1.
- "cn-north-1"
- China (Beijing) Region
- Needs location constraint cn-north-1.
- "cn-northwest-1"
- China (Ningxia) Region
- Needs location constraint cn-northwest-1.
- "us-gov-east-1"
- AWS GovCloud (US-East) Region
- Needs location constraint us-gov-east-1.
- "us-gov-west-1"
- AWS GovCloud (US) Region
- Needs location constraint us-gov-west-1.
#### --s3-region #### --s3-region
@@ -839,6 +869,54 @@ Endpoint for StackPath Object Storage.
#### --s3-endpoint #### --s3-endpoint
Endpoint for Tencent COS API.
- Config: endpoint
- Env Var: RCLONE_S3_ENDPOINT
- Type: string
- Default: ""
- Examples:
- "cos.ap-beijing.myqcloud.com"
- Beijing Region.
- "cos.ap-nanjing.myqcloud.com"
- Nanjing Region.
- "cos.ap-shanghai.myqcloud.com"
- Shanghai Region.
- "cos.ap-guangzhou.myqcloud.com"
- Guangzhou Region.
- "cos.ap-nanjing.myqcloud.com"
- Nanjing Region.
- "cos.ap-chengdu.myqcloud.com"
- Chengdu Region.
- "cos.ap-chongqing.myqcloud.com"
- Chongqing Region.
- "cos.ap-hongkong.myqcloud.com"
- Hong Kong (China) Region.
- "cos.ap-singapore.myqcloud.com"
- Singapore Region.
- "cos.ap-mumbai.myqcloud.com"
- Mumbai Region.
- "cos.ap-seoul.myqcloud.com"
- Seoul Region.
- "cos.ap-bangkok.myqcloud.com"
- Bangkok Region.
- "cos.ap-tokyo.myqcloud.com"
- Tokyo Region.
- "cos.na-siliconvalley.myqcloud.com"
- Silicon Valley Region.
- "cos.na-ashburn.myqcloud.com"
- Virginia Region.
- "cos.na-toronto.myqcloud.com"
- Toronto Region.
- "cos.eu-frankfurt.myqcloud.com"
- Frankfurt Region.
- "cos.eu-moscow.myqcloud.com"
- Moscow Region.
- "cos.accelerate.myqcloud.com"
- Use Tencent COS Accelerate Endpoint.
#### --s3-endpoint
Endpoint for S3 API. Endpoint for S3 API.
Required when using an S3 clone. Required when using an S3 clone.
@@ -876,18 +954,22 @@ Used when creating buckets only.
- Empty for US Region, Northern Virginia or Pacific Northwest. - Empty for US Region, Northern Virginia or Pacific Northwest.
- "us-east-2" - "us-east-2"
- US East (Ohio) Region. - US East (Ohio) Region.
- "us-west-2"
- US West (Oregon) Region.
- "us-west-1" - "us-west-1"
- US West (Northern California) Region. - US West (Northern California) Region.
- "us-west-2"
- US West (Oregon) Region.
- "ca-central-1" - "ca-central-1"
- Canada (Central) Region. - Canada (Central) Region.
- "eu-west-1" - "eu-west-1"
- EU (Ireland) Region. - EU (Ireland) Region.
- "eu-west-2" - "eu-west-2"
- EU (London) Region. - EU (London) Region.
- "eu-west-3"
- EU (Paris) Region.
- "eu-north-1" - "eu-north-1"
- EU (Stockholm) Region. - EU (Stockholm) Region.
- "eu-south-1"
- EU (Milan) Region.
- "EU" - "EU"
- EU Region. - EU Region.
- "ap-southeast-1" - "ap-southeast-1"
@@ -897,13 +979,27 @@ Used when creating buckets only.
- "ap-northeast-1" - "ap-northeast-1"
- Asia Pacific (Tokyo) Region. - Asia Pacific (Tokyo) Region.
- "ap-northeast-2" - "ap-northeast-2"
- Asia Pacific (Seoul) - Asia Pacific (Seoul) Region.
- "ap-northeast-3"
- Asia Pacific (Osaka-Local) Region.
- "ap-south-1" - "ap-south-1"
- Asia Pacific (Mumbai) - Asia Pacific (Mumbai) Region.
- "ap-east-1" - "ap-east-1"
- Asia Pacific (Hong Kong) - Asia Pacific (Hong Kong) Region.
- "sa-east-1" - "sa-east-1"
- South America (Sao Paulo) Region. - South America (Sao Paulo) Region.
- "me-south-1"
- Middle East (Bahrain) Region.
- "af-south-1"
- Africa (Cape Town) Region.
- "cn-north-1"
- China (Beijing) Region
- "cn-northwest-1"
- China (Ningxia) Region.
- "us-gov-east-1"
- AWS GovCloud (US-East) Region.
- "us-gov-west-1"
- AWS GovCloud (US) Region.
#### --s3-location-constraint #### --s3-location-constraint
@@ -1006,6 +1102,8 @@ doesn't copy the ACL from the source but rather writes a fresh one.
- Type: string - Type: string
- Default: "" - Default: ""
- Examples: - Examples:
- "default"
- Owner gets Full_CONTROL. No one else has access rights (default).
- "private" - "private"
- Owner gets FULL_CONTROL. No one else has access rights (default). - Owner gets FULL_CONTROL. No one else has access rights (default).
- "public-read" - "public-read"
@@ -1106,6 +1204,24 @@ The storage class to use when storing new objects in OSS.
#### --s3-storage-class #### --s3-storage-class
The storage class to use when storing new objects in Tencent COS.
- Config: storage_class
- Env Var: RCLONE_S3_STORAGE_CLASS
- Type: string
- Default: ""
- Examples:
- ""
- Default
- "STANDARD"
- Standard storage class
- "ARCHIVE"
- Archive storage mode.
- "STANDARD_IA"
- Infrequent access storage mode.
#### --s3-storage-class
The storage class to use when storing new objects in S3. The storage class to use when storing new objects in S3.
- Config: storage_class - Config: storage_class
@@ -1122,7 +1238,7 @@ The storage class to use when storing new objects in S3.
### Advanced Options ### Advanced Options
Here are the advanced options specific to s3 (Amazon S3 Compliant Storage Provider (AWS, Alibaba, Ceph, Digital Ocean, Dreamhost, IBM COS, Minio, etc)). Here are the advanced options specific to s3 (Amazon S3 Compliant Storage Provider (AWS, Alibaba, Ceph, Digital Ocean, Dreamhost, IBM COS, Minio, Tencent COS, etc)).
#### --s3-bucket-acl #### --s3-bucket-acl
@@ -1343,7 +1459,7 @@ if false then rclone will use virtual path style. See [the AWS S3
docs](https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingBucket.html#access-bucket-intro) docs](https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingBucket.html#access-bucket-intro)
for more info. for more info.
Some providers (eg AWS, Aliyun OSS or Netease COS) require this set to Some providers (eg AWS, Aliyun OSS, Netease COS or Tencent COS) require this set to
false - rclone will do this automatically based on the provider false - rclone will do this automatically based on the provider
setting. setting.
@@ -2212,6 +2328,138 @@ d) Delete this remote
y/e/d> y y/e/d> y
``` ```
### Tencent COS {#tencent-cos}
[Tencent Cloud Object Storage (COS)](https://intl.cloud.tencent.com/product/cos) is a distributed storage service offered by Tencent Cloud for unstructured data. It is secure, stable, massive, convenient, low-delay and low-cost.
To configure access to Tencent COS, follow the steps below:
1. Run `rclone config` and select `n` for a new remote.
```
rclone config
No remotes found - make a new one
n) New remote
s) Set configuration password
q) Quit config
n/s/q> n
```
2. Give the name of the configuration. For example, name it 'cos'.
```
name> cos
```
3. Select `s3` storage.
```
Choose a number from below, or type in your own value
1 / 1Fichier
\ "fichier"
2 / Alias for an existing remote
\ "alias"
3 / Amazon Drive
\ "amazon cloud drive"
4 / Amazon S3 Compliant Storage Provider (AWS, Alibaba, Ceph, Digital Ocean, Dreamhost, IBM COS, Minio, Tencent COS, etc)
\ "s3"
[snip]
Storage> s3
```
4. Select `TencentCOS` provider.
```
Choose a number from below, or type in your own value
1 / Amazon Web Services (AWS) S3
\ "AWS"
[snip]
11 / Tencent Cloud Object Storage (COS)
\ "TencentCOS"
[snip]
provider> TencentCOS
```
5. Enter your SecretId and SecretKey of Tencent Cloud.
```
Get AWS credentials from runtime (environment variables or EC2/ECS meta data if no env vars).
Only applies if access_key_id and secret_access_key is blank.
Enter a boolean value (true or false). Press Enter for the default ("false").
Choose a number from below, or type in your own value
1 / Enter AWS credentials in the next step
\ "false"
2 / Get AWS credentials from the environment (env vars or IAM)
\ "true"
env_auth> 1
AWS Access Key ID.
Leave blank for anonymous access or runtime credentials.
Enter a string value. Press Enter for the default ("").
access_key_id> AKIDxxxxxxxxxx
AWS Secret Access Key (password)
Leave blank for anonymous access or runtime credentials.
Enter a string value. Press Enter for the default ("").
secret_access_key> xxxxxxxxxxx
```
6. Select endpoint for Tencent COS. This is the standard endpoint for different region.
```
1 / Beijing Region.
\ "cos.ap-beijing.myqcloud.com"
2 / Nanjing Region.
\ "cos.ap-nanjing.myqcloud.com"
3 / Shanghai Region.
\ "cos.ap-shanghai.myqcloud.com"
4 / Guangzhou Region.
\ "cos.ap-guangzhou.myqcloud.com"
[snip]
endpoint> 4
```
7. Choose acl and storage class.
```
Note that this ACL is applied when server side copying objects as S3
doesn't copy the ACL from the source but rather writes a fresh one.
Enter a string value. Press Enter for the default ("").
Choose a number from below, or type in your own value
1 / Owner gets Full_CONTROL. No one else has access rights (default).
\ "default"
[snip]
acl> 1
The storage class to use when storing new objects in Tencent COS.
Enter a string value. Press Enter for the default ("").
Choose a number from below, or type in your own value
1 / Default
\ ""
[snip]
storage_class> 1
Edit advanced config? (y/n)
y) Yes
n) No (default)
y/n> n
Remote config
--------------------
[cos]
type = s3
provider = TencentCOS
env_auth = false
access_key_id = xxx
secret_access_key = xxx
endpoint = cos.ap-guangzhou.myqcloud.com
acl = default
--------------------
y) Yes this is OK (default)
e) Edit this remote
d) Delete this remote
y/e/d> y
Current remotes:
Name Type
==== ====
cos s3
```
### Netease NOS ### ### Netease NOS ###
For Netease NOS configure as per the configurator `rclone config` For Netease NOS configure as per the configurator `rclone config`

View File

@@ -1 +1 @@
v1.53.0 v1.53.2

View File

@@ -272,7 +272,7 @@ func (s *StatsInfo) String() string {
} }
} }
_, _ = fmt.Fprintf(buf, "%s%10s / %s, %s, %s, ETA %s%s\n", _, _ = fmt.Fprintf(buf, "%s%10s / %s, %s, %s, ETA %s%s",
dateString, dateString,
fs.SizeSuffix(s.bytes), fs.SizeSuffix(s.bytes),
fs.SizeSuffix(totalSize).Unit("Bytes"), fs.SizeSuffix(totalSize).Unit("Bytes"),
@@ -283,6 +283,7 @@ func (s *StatsInfo) String() string {
) )
if !fs.Config.StatsOneLine { if !fs.Config.StatsOneLine {
_, _ = buf.WriteRune('\n')
errorDetails := "" errorDetails := ""
switch { switch {
case s.fatalError: case s.fatalError:
@@ -291,6 +292,7 @@ func (s *StatsInfo) String() string {
errorDetails = " (retrying may help)" errorDetails = " (retrying may help)"
case s.errors != 0: case s.errors != 0:
errorDetails = " (no need to retry)" errorDetails = " (no need to retry)"
} }
// Add only non zero stats // Add only non zero stats

View File

@@ -366,6 +366,8 @@ func (sg *statsGroups) sum() *StatsInfo {
sum.lastError = stats.lastError sum.lastError = stats.lastError
} }
sum.startedTransfers = append(sum.startedTransfers, stats.startedTransfers...) sum.startedTransfers = append(sum.startedTransfers, stats.startedTransfers...)
sum.oldDuration += stats.oldDuration
sum.oldTimeRanges = append(sum.oldTimeRanges, stats.oldTimeRanges...)
} }
stats.mu.RUnlock() stats.mu.RUnlock()
} }

View File

@@ -4,8 +4,10 @@ import (
"fmt" "fmt"
"runtime" "runtime"
"testing" "testing"
"time"
"github.com/rclone/rclone/fstest/testy" "github.com/rclone/rclone/fstest/testy"
"github.com/stretchr/testify/assert"
) )
func TestStatsGroupOperations(t *testing.T) { func TestStatsGroupOperations(t *testing.T) {
@@ -43,17 +45,26 @@ func TestStatsGroupOperations(t *testing.T) {
t.Parallel() t.Parallel()
stats1 := NewStats() stats1 := NewStats()
stats1.bytes = 5 stats1.bytes = 5
stats1.errors = 5 stats1.errors = 6
stats1.oldDuration = time.Second
stats1.oldTimeRanges = []timeRange{{time.Now(), time.Now().Add(time.Second)}}
stats2 := NewStats() stats2 := NewStats()
stats2.bytes = 10
stats2.errors = 12
stats2.oldDuration = 2 * time.Second
stats2.oldTimeRanges = []timeRange{{time.Now(), time.Now().Add(2 * time.Second)}}
sg := newStatsGroups() sg := newStatsGroups()
sg.set("test1", stats1) sg.set("test1", stats1)
sg.set("test2", stats2) sg.set("test2", stats2)
sum := sg.sum() sum := sg.sum()
if sum.bytes != stats1.bytes+stats2.bytes { assert.Equal(t, stats1.bytes+stats2.bytes, sum.bytes)
t.Fatalf("sum() => bytes %d, expected %d", sum.bytes, stats1.bytes+stats2.bytes) assert.Equal(t, stats1.errors+stats2.errors, sum.errors)
} assert.Equal(t, stats1.oldDuration+stats2.oldDuration, sum.oldDuration)
if sum.errors != stats1.errors+stats2.errors { // dict can iterate in either order
t.Fatalf("sum() => errors %d, expected %d", sum.errors, stats1.errors+stats2.errors) a := timeRanges{stats1.oldTimeRanges[0], stats2.oldTimeRanges[0]}
b := timeRanges{stats2.oldTimeRanges[0], stats1.oldTimeRanges[0]}
if !assert.ObjectsAreEqual(a, sum.oldTimeRanges) {
assert.Equal(t, b, sum.oldTimeRanges)
} }
}) })

View File

@@ -72,8 +72,16 @@ func (tm *transferMap) _sortedSlice() []*Transfer {
for _, tr := range tm.items { for _, tr := range tm.items {
s = append(s, tr) s = append(s, tr)
} }
// sort by time first and if equal by name. Note that the relatively
// low time resolution on Windows can cause equal times.
sort.Slice(s, func(i, j int) bool { sort.Slice(s, func(i, j int) bool {
return s[i].startedAt.Before(s[j].startedAt) a, b := s[i], s[j]
if a.startedAt.Before(b.startedAt) {
return true
} else if !a.startedAt.Equal(b.startedAt) {
return false
}
return a.remote < b.remote
}) })
return s return s
} }

View File

@@ -172,9 +172,12 @@ func equal(ctx context.Context, src fs.ObjectInfo, dst fs.Object, opt equalOpt)
return false return false
} }
if ht == hash.None { if ht == hash.None {
common := src.Fs().Hashes().Overlap(dst.Fs().Hashes())
if common.Count() == 0 {
checksumWarning.Do(func() { checksumWarning.Do(func() {
fs.Logf(dst.Fs(), "--checksum is in use but the source and destination have no hashes in common; falling back to --size-only") fs.Logf(dst.Fs(), "--checksum is in use but the source and destination have no hashes in common; falling back to --size-only")
}) })
}
fs.Debugf(src, "Size of src and dst objects identical") fs.Debugf(src, "Size of src and dst objects identical")
} else { } else {
fs.Debugf(src, "Size and %v of src and dst objects identical", ht) fs.Debugf(src, "Size and %v of src and dst objects identical", ht)
@@ -1522,12 +1525,11 @@ func BackupDir(fdst fs.Fs, fsrc fs.Fs, srcFileName string) (backupDir fs.Fs, err
} }
} }
} }
} else { } else if fs.Config.Suffix != "" {
if srcFileName == "" {
return nil, fserrors.FatalError(errors.New("--suffix must be used with a file or with --backup-dir"))
}
// --backup-dir is not set but --suffix is - use the destination as the backupDir // --backup-dir is not set but --suffix is - use the destination as the backupDir
backupDir = fdst backupDir = fdst
} else {
return nil, fserrors.FatalError(errors.New("internal error: BackupDir called when --backup-dir and --suffix both empty"))
} }
if !CanServerSideMove(backupDir) { if !CanServerSideMove(backupDir) {
return nil, fserrors.FatalError(errors.New("can't use --backup-dir on a remote which doesn't support server side move or copy")) return nil, fserrors.FatalError(errors.New("can't use --backup-dir on a remote which doesn't support server side move or copy"))

View File

@@ -379,7 +379,7 @@ OR
"result": "<Raw command line output>" "result": "<Raw command line output>"
} }
` + "```" + `
`, `,
}) })
} }

View File

@@ -45,7 +45,7 @@ func init() {
This takes the following parameters This takes the following parameters
- name: name of the plugin in the format <author>/<plugin_name> - name: name of the plugin in the format ` + "`author`/`plugin_name`" + `
Eg Eg
@@ -212,7 +212,7 @@ func init() {
This takes parameters This takes parameters
- name: name of the plugin in the format <author>/<plugin_name> - name: name of the plugin in the format ` + "`author`/`plugin_name`" + `
Eg Eg

View File

@@ -1590,7 +1590,7 @@ func TestSyncCopyDest(t *testing.T) {
} }
// Test with BackupDir set // Test with BackupDir set
func testSyncBackupDir(t *testing.T, suffix string, suffixKeepExtension bool) { func testSyncBackupDir(t *testing.T, backupDir string, suffix string, suffixKeepExtension bool) {
r := fstest.NewRun(t) r := fstest.NewRun(t)
defer r.Finalise() defer r.Finalise()
@@ -1599,7 +1599,23 @@ func testSyncBackupDir(t *testing.T, suffix string, suffixKeepExtension bool) {
} }
r.Mkdir(context.Background(), r.Fremote) r.Mkdir(context.Background(), r.Fremote)
fs.Config.BackupDir = r.FremoteName + "/backup" if backupDir != "" {
fs.Config.BackupDir = r.FremoteName + "/" + backupDir
backupDir += "/"
} else {
fs.Config.BackupDir = ""
backupDir = "dst/"
// Exclude the suffix from the sync otherwise the sync
// deletes the old backup files
flt, err := filter.NewFilter(nil)
require.NoError(t, err)
require.NoError(t, flt.AddRule("- *"+suffix))
oldFlt := filter.Active
filter.Active = flt
defer func() {
filter.Active = oldFlt
}()
}
fs.Config.Suffix = suffix fs.Config.Suffix = suffix
fs.Config.SuffixKeepExtension = suffixKeepExtension fs.Config.SuffixKeepExtension = suffixKeepExtension
defer func() { defer func() {
@@ -1627,14 +1643,14 @@ func testSyncBackupDir(t *testing.T, suffix string, suffixKeepExtension bool) {
require.NoError(t, err) require.NoError(t, err)
// one should be moved to the backup dir and the new one installed // one should be moved to the backup dir and the new one installed
file1.Path = "backup/one" + suffix file1.Path = backupDir + "one" + suffix
file1a.Path = "dst/one" file1a.Path = "dst/one"
// two should be unchanged // two should be unchanged
// three should be moved to the backup dir // three should be moved to the backup dir
if suffixKeepExtension { if suffixKeepExtension {
file3.Path = "backup/three" + suffix + ".txt" file3.Path = backupDir + "three" + suffix + ".txt"
} else { } else {
file3.Path = "backup/three.txt" + suffix file3.Path = backupDir + "three.txt" + suffix
} }
fstest.CheckItems(t, r.Fremote, file1, file2, file3, file1a) fstest.CheckItems(t, r.Fremote, file1, file2, file3, file1a)
@@ -1652,22 +1668,29 @@ func testSyncBackupDir(t *testing.T, suffix string, suffixKeepExtension bool) {
require.NoError(t, err) require.NoError(t, err)
// one should be moved to the backup dir and the new one installed // one should be moved to the backup dir and the new one installed
file1a.Path = "backup/one" + suffix file1a.Path = backupDir + "one" + suffix
file1b.Path = "dst/one" file1b.Path = "dst/one"
// two should be unchanged // two should be unchanged
// three should be moved to the backup dir // three should be moved to the backup dir
if suffixKeepExtension { if suffixKeepExtension {
file3a.Path = "backup/three" + suffix + ".txt" file3a.Path = backupDir + "three" + suffix + ".txt"
} else { } else {
file3a.Path = "backup/three.txt" + suffix file3a.Path = backupDir + "three.txt" + suffix
} }
fstest.CheckItems(t, r.Fremote, file1b, file2, file3a, file1a) fstest.CheckItems(t, r.Fremote, file1b, file2, file3a, file1a)
} }
func TestSyncBackupDir(t *testing.T) { testSyncBackupDir(t, "", false) } func TestSyncBackupDir(t *testing.T) {
func TestSyncBackupDirWithSuffix(t *testing.T) { testSyncBackupDir(t, ".bak", false) } testSyncBackupDir(t, "backup", "", false)
}
func TestSyncBackupDirWithSuffix(t *testing.T) {
testSyncBackupDir(t, "backup", ".bak", false)
}
func TestSyncBackupDirWithSuffixKeepExtension(t *testing.T) { func TestSyncBackupDirWithSuffixKeepExtension(t *testing.T) {
testSyncBackupDir(t, "-2019-01-01", true) testSyncBackupDir(t, "backup", "-2019-01-01", true)
}
func TestSyncBackupDirSuffixOnly(t *testing.T) {
testSyncBackupDir(t, "", ".bak", false)
} }
// Test with Suffix set // Test with Suffix set

View File

@@ -1,4 +1,4 @@
package fs package fs
// Version of rclone // Version of rclone
var Version = "v1.53.0-DEV" var Version = "v1.53.2-DEV"

View File

@@ -36,6 +36,7 @@ type Backend struct {
CleanUp bool // when running clean, run cleanup first CleanUp bool // when running clean, run cleanup first
Ignore []string // test names to ignore the failure of Ignore []string // test names to ignore the failure of
Tests []string // paths of tests to run, blank for all Tests []string // paths of tests to run, blank for all
ListRetries int // -list-retries if > 0
} }
// includeTest returns true if this backend should be included in this // includeTest returns true if this backend should be included in this
@@ -89,6 +90,7 @@ func (b *Backend) MakeRuns(t *Test) (runs []*Run) {
NoBinary: t.NoBinary, NoBinary: t.NoBinary,
SizeLimit: int64(maxSize), SizeLimit: int64(maxSize),
Ignore: ignore, Ignore: ignore,
ListRetries: b.ListRetries,
} }
if t.AddBackend { if t.AddBackend {
run.Path = path.Join(run.Path, b.Backend) run.Path = path.Join(run.Path, b.Backend)

View File

@@ -20,6 +20,7 @@ backends:
- backend: "b2" - backend: "b2"
remote: "TestB2:" remote: "TestB2:"
fastlist: true fastlist: true
listretries: 5
- backend: "crypt" - backend: "crypt"
remote: "TestCryptDrive:" remote: "TestCryptDrive:"
fastlist: true fastlist: true
@@ -41,15 +42,13 @@ backends:
remote: "TestChunkerChunk3bNometaLocal:" remote: "TestChunkerChunk3bNometaLocal:"
fastlist: true fastlist: true
maxfile: 6k maxfile: 6k
# Disable chunker with mailru tests until Mailru is fixed - see - backend: "chunker"
# https://github.com/rclone/rclone/issues/4376 remote: "TestChunkerMailru:"
# - backend: "chunker" fastlist: true
# remote: "TestChunkerMailru:" - backend: "chunker"
# fastlist: true remote: "TestChunkerChunk50bMailru:"
# - backend: "chunker" fastlist: true
# remote: "TestChunkerChunk50bMailru:" maxfile: 10k
# fastlist: true
# maxfile: 10k
- backend: "chunker" - backend: "chunker"
remote: "TestChunkerChunk50bYandex:" remote: "TestChunkerChunk50bYandex:"
fastlist: true fastlist: true
@@ -73,6 +72,10 @@ backends:
remote: "TestChunkerChunk50bSHA1HashS3:" remote: "TestChunkerChunk50bSHA1HashS3:"
fastlist: true fastlist: true
maxfile: 1k maxfile: 1k
- backend: "chunker"
remote: "TestChunkerOverCrypt:"
fastlist: true
maxfile: 6k
- backend: "chunker" - backend: "chunker"
remote: "TestChunkerChunk50bMD5QuickS3:" remote: "TestChunkerChunk50bMD5QuickS3:"
fastlist: true fastlist: true
@@ -144,12 +147,12 @@ backends:
# ignore: # ignore:
# - TestIntegration/FsMkdir/FsPutFiles/FsCopy # - TestIntegration/FsMkdir/FsPutFiles/FsCopy
# - TestIntegration/FsMkdir/FsPutFiles/SetTier # - TestIntegration/FsMkdir/FsPutFiles/SetTier
- backend: "s3" # - backend: "s3"
remote: "TestS3Ceph:" # remote: "TestS3Ceph:"
fastlist: true # fastlist: true
ignore: # ignore:
- TestIntegration/FsMkdir/FsPutFiles/FsCopy # - TestIntegration/FsMkdir/FsPutFiles/FsCopy
- TestIntegration/FsMkdir/FsPutFiles/SetTier # - TestIntegration/FsMkdir/FsPutFiles/SetTier
- backend: "s3" - backend: "s3"
remote: "TestS3Alibaba:" remote: "TestS3Alibaba:"
fastlist: true fastlist: true
@@ -170,11 +173,11 @@ backends:
- backend: "swift" - backend: "swift"
remote: "TestSwift:" remote: "TestSwift:"
fastlist: true fastlist: true
- backend: "swift" # - backend: "swift"
remote: "TestSwiftCeph:" # remote: "TestSwiftCeph:"
fastlist: true # fastlist: true
ignore: # ignore:
- TestIntegration/FsMkdir/FsPutFiles/FsCopy # - TestIntegration/FsMkdir/FsPutFiles/FsCopy
- backend: "yandex" - backend: "yandex"
remote: "TestYandex:" remote: "TestYandex:"
fastlist: false fastlist: false

View File

@@ -45,6 +45,7 @@ type Run struct {
NoBinary bool // set to not build a binary NoBinary bool // set to not build a binary
SizeLimit int64 // maximum test file size SizeLimit int64 // maximum test file size
Ignore map[string]struct{} Ignore map[string]struct{}
ListRetries int // -list-retries if > 0
// Internals // Internals
CmdLine []string CmdLine []string
CmdString string CmdString string
@@ -336,8 +337,12 @@ func (r *Run) Init() {
r.CmdLine = []string{"./" + r.BinaryName()} r.CmdLine = []string{"./" + r.BinaryName()}
} }
r.CmdLine = append(r.CmdLine, prefix+"v", prefix+"timeout", timeout.String(), "-remote", r.Remote) r.CmdLine = append(r.CmdLine, prefix+"v", prefix+"timeout", timeout.String(), "-remote", r.Remote)
if *listRetries > 0 { listRetries := *listRetries
r.CmdLine = append(r.CmdLine, "-list-retries", fmt.Sprint(*listRetries)) if r.ListRetries > 0 {
listRetries = r.ListRetries
}
if listRetries > 0 {
r.CmdLine = append(r.CmdLine, "-list-retries", fmt.Sprint(listRetries))
} }
r.Try = 1 r.Try = 1
if *verbose { if *verbose {

22988
rclone.1 generated

File diff suppressed because it is too large Load Diff

View File

@@ -342,9 +342,14 @@ func (f *File) Size() int64 {
} }
// SetModTime sets the modtime for the file // SetModTime sets the modtime for the file
//
// if NoModTime is set then it does nothing
func (f *File) SetModTime(modTime time.Time) error { func (f *File) SetModTime(modTime time.Time) error {
f.mu.Lock() f.mu.Lock()
defer f.mu.Unlock() defer f.mu.Unlock()
if f.d.vfs.Opt.NoModTime {
return nil
}
if f.d.vfs.Opt.ReadOnly { if f.d.vfs.Opt.ReadOnly {
return EROFS return EROFS
} }

View File

@@ -166,6 +166,11 @@ whereas the --vfs-read-ahead is buffered on disk.
When using this mode it is recommended that --buffer-size is not set When using this mode it is recommended that --buffer-size is not set
too big and --vfs-read-ahead is set large if required. too big and --vfs-read-ahead is set large if required.
**IMPORTANT** not all file systems support sparse files. In particular
FAT/exFAT do not. Rclone will perform very badly if the cache
directory is on a filesystem which doesn't support sparse files and it
will log an ERROR message if one is detected.
### VFS Performance ### VFS Performance
These flags may be used to enable/disable features of the VFS for These flags may be used to enable/disable features of the VFS for

View File

@@ -466,11 +466,17 @@ func (c *Cache) retryFailedResets() {
if len(c.errItems) != 0 { if len(c.errItems) != 0 {
fs.Debugf(nil, "vfs cache reset: before redoing reset errItems = %v", c.errItems) fs.Debugf(nil, "vfs cache reset: before redoing reset errItems = %v", c.errItems)
for itemName := range c.errItems { for itemName := range c.errItems {
_, _, err := c.item[itemName].Reset() if retryItem, ok := c.item[itemName]; ok {
_, _, err := retryItem.Reset()
if err == nil || !fserrors.IsErrNoSpace(err) { if err == nil || !fserrors.IsErrNoSpace(err) {
// TODO: not trying to handle non-ENOSPC errors yet // TODO: not trying to handle non-ENOSPC errors yet
delete(c.errItems, itemName) delete(c.errItems, itemName)
} }
} else {
// The retry item was deleted because it was closed.
// No need to redo the failed reset now.
delete(c.errItems, itemName)
}
} }
fs.Debugf(nil, "vfs cache reset: after redoing reset errItems = %v", c.errItems) fs.Debugf(nil, "vfs cache reset: after redoing reset errItems = %v", c.errItems)
} }
@@ -603,7 +609,7 @@ func (c *Cache) clean(removeCleanFiles bool) {
if os.IsNotExist(err) { if os.IsNotExist(err) {
return return
} }
c.updateUsed()
c.mu.Lock() c.mu.Lock()
oldItems, oldUsed := len(c.item), fs.SizeSuffix(c.used) oldItems, oldUsed := len(c.item), fs.SizeSuffix(c.used)
c.mu.Unlock() c.mu.Unlock()

View File

@@ -230,7 +230,11 @@ func (dls *Downloaders) Close(inErr error) (err error) {
} }
} }
dls.cancel() dls.cancel()
// dls may have entered the periodical (every 5 seconds) kickWaiters() call
// unlock the mutex to allow it to finish so that we can get its dls.wg.Done()
dls.mu.Unlock()
dls.wg.Wait() dls.wg.Wait()
dls.mu.Lock()
dls.dls = nil dls.dls = nil
dls._dispatchWaiters() dls._dispatchWaiters()
dls._closeWaiters(inErr) dls._closeWaiters(inErr)

View File

@@ -43,6 +43,13 @@ import (
// be taken before Item.mu. writeback may call into Item but Item may // be taken before Item.mu. writeback may call into Item but Item may
// **not** call writeback methods with Item.mu held // **not** call writeback methods with Item.mu held
// LL Item reset is invoked by cache cleaner for synchronous recovery
// from ENOSPC errors. The reset operation removes the cache file and
// closes/reopens the downloaders. Although most parts of reset and
// other item operations are done with the item mutex held, the mutex
// is released during fd.WriteAt and downloaders calls. We use preAccess
// and postAccess calls to serialize reset and other item operations.
// Item is stored in the item map // Item is stored in the item map
// //
// The Info field is written to the backing store to store status // The Info field is written to the backing store to store status
@@ -239,8 +246,23 @@ func (item *Item) _truncate(size int64) (err error) {
// Use open handle if available // Use open handle if available
fd := item.fd fd := item.fd
if fd == nil { if fd == nil {
// If the metadata says we have some blockes cached then the
// file should exist, so open without O_CREATE
oFlags := os.O_WRONLY
if item.info.Rs.Size() == 0 {
oFlags |= os.O_CREATE
}
osPath := item.c.toOSPath(item.name) // No locking in Cache osPath := item.c.toOSPath(item.name) // No locking in Cache
fd, err = file.OpenFile(osPath, oFlags, 0600)
if err != nil && os.IsNotExist(err) {
// If the metadata has info but the file doesn't
// not exist then it has been externally removed
fs.Errorf(item.name, "vfs cache: detected external removal of cache file")
item.info.Rs = nil // show we have no blocks cached
item.info.Dirty = false // file can't be dirty if it doesn't exist
item._removeMeta("cache file externally deleted")
fd, err = file.OpenFile(osPath, os.O_CREATE|os.O_WRONLY, 0600) fd, err = file.OpenFile(osPath, os.O_CREATE|os.O_WRONLY, 0600)
}
if err != nil { if err != nil {
return errors.Wrap(err, "vfs cache: truncate: failed to open cache file") return errors.Wrap(err, "vfs cache: truncate: failed to open cache file")
} }
@@ -249,7 +271,7 @@ func (item *Item) _truncate(size int64) (err error) {
err = file.SetSparse(fd) err = file.SetSparse(fd)
if err != nil { if err != nil {
fs.Debugf(item.name, "vfs cache: truncate: failed to set as a sparse file: %v", err) fs.Errorf(item.name, "vfs cache: truncate: failed to set as a sparse file: %v", err)
} }
} }
@@ -295,6 +317,8 @@ func (item *Item) _truncateToCurrentSize() (err error) {
// extended and the extended data will be filled with zeros. The // extended and the extended data will be filled with zeros. The
// object will be marked as dirty in this case also. // object will be marked as dirty in this case also.
func (item *Item) Truncate(size int64) (err error) { func (item *Item) Truncate(size int64) (err error) {
item.preAccess()
defer item.postAccess()
item.mu.Lock() item.mu.Lock()
defer item.mu.Unlock() defer item.mu.Unlock()
@@ -414,6 +438,8 @@ func (item *Item) _dirty() {
// Dirty marks the item as changed and needing writeback // Dirty marks the item as changed and needing writeback
func (item *Item) Dirty() { func (item *Item) Dirty() {
item.preAccess()
defer item.postAccess()
item.mu.Lock() item.mu.Lock()
item._dirty() item._dirty()
item.mu.Unlock() item.mu.Unlock()
@@ -446,7 +472,7 @@ func (item *Item) _createFile(osPath string) (err error) {
} }
err = file.SetSparse(fd) err = file.SetSparse(fd)
if err != nil { if err != nil {
fs.Debugf(item.name, "vfs cache: failed to set as a sparse file: %v", err) fs.Errorf(item.name, "vfs cache: failed to set as a sparse file: %v", err)
} }
item.fd = fd item.fd = fd
@@ -597,6 +623,8 @@ func (item *Item) store(ctx context.Context, storeFn StoreFn) (err error) {
// Close the cache file // Close the cache file
func (item *Item) Close(storeFn StoreFn) (err error) { func (item *Item) Close(storeFn StoreFn) (err error) {
// defer log.Trace(item.o, "Item.Close")("err=%v", &err) // defer log.Trace(item.o, "Item.Close")("err=%v", &err)
item.preAccess()
defer item.postAccess()
var ( var (
downloaders *downloaders.Downloaders downloaders *downloaders.Downloaders
syncWriteBack = item.c.opt.WriteBack <= 0 syncWriteBack = item.c.opt.WriteBack <= 0
@@ -1154,11 +1182,12 @@ func (item *Item) setModTime(modTime time.Time) {
// ReadAt bytes from the file at off // ReadAt bytes from the file at off
func (item *Item) ReadAt(b []byte, off int64) (n int, err error) { func (item *Item) ReadAt(b []byte, off int64) (n int, err error) {
n = 0 n = 0
var expBackOff int
for retries := 0; retries < fs.Config.LowLevelRetries; retries++ { for retries := 0; retries < fs.Config.LowLevelRetries; retries++ {
item.preAccess() item.preAccess()
n, err = item.readAt(b, off) n, err = item.readAt(b, off)
item.postAccess() item.postAccess()
if err == nil { if err == nil || err == io.EOF {
break break
} }
fs.Errorf(item.name, "vfs cache: failed to _ensure cache %v", err) fs.Errorf(item.name, "vfs cache: failed to _ensure cache %v", err)
@@ -1167,6 +1196,12 @@ func (item *Item) ReadAt(b []byte, off int64) (n int, err error) {
break break
} }
item.c.KickCleaner() item.c.KickCleaner()
expBackOff = 2 << uint(retries)
time.Sleep(time.Duration(expBackOff) * time.Millisecond) // Exponential back-off the retries
}
if fserrors.IsErrNoSpace(err) {
fs.Errorf(item.name, "vfs cache: failed to _ensure cache after retries %v", err)
} }
return n, err return n, err
@@ -1198,6 +1233,8 @@ func (item *Item) readAt(b []byte, off int64) (n int, err error) {
// WriteAt bytes to the file at off // WriteAt bytes to the file at off
func (item *Item) WriteAt(b []byte, off int64) (n int, err error) { func (item *Item) WriteAt(b []byte, off int64) (n int, err error) {
item.preAccess()
defer item.postAccess()
item.mu.Lock() item.mu.Lock()
if item.fd == nil { if item.fd == nil {
item.mu.Unlock() item.mu.Unlock()
@@ -1288,6 +1325,8 @@ func (item *Item) WriteAtNoOverwrite(b []byte, off int64) (n int, skipped int, e
// this means flushing the file system's in-memory copy of recently written // this means flushing the file system's in-memory copy of recently written
// data to disk. // data to disk.
func (item *Item) Sync() (err error) { func (item *Item) Sync() (err error) {
item.preAccess()
defer item.postAccess()
item.mu.Lock() item.mu.Lock()
defer item.mu.Unlock() defer item.mu.Unlock()
if item.fd == nil { if item.fd == nil {
@@ -1307,6 +1346,8 @@ func (item *Item) Sync() (err error) {
// rename the item // rename the item
func (item *Item) rename(name string, newName string, newObj fs.Object) (err error) { func (item *Item) rename(name string, newName string, newObj fs.Object) (err error) {
item.preAccess()
defer item.postAccess()
item.mu.Lock() item.mu.Lock()
// stop downloader // stop downloader
@@ -1336,6 +1377,5 @@ func (item *Item) rename(name string, newName string, newObj fs.Object) (err err
_ = downloaders.Close(nil) _ = downloaders.Close(nil)
} }
item.c.writeback.Rename(id, newName) item.c.writeback.Rename(id, newName)
return err return err
} }