operations: copy: generate stable partial suffix

This commit is contained in:
Georg Welzel 2024-07-13 13:35:47 -07:00 committed by Nick Craig-Wood
parent 1bb89bc818
commit c63f1865f3
2 changed files with 11 additions and 6 deletions

View file

@ -1347,11 +1347,12 @@ flag set) such as:
- local
- ftp
- sftp
- pcloud
Without `--inplace` (the default) rclone will first upload to a
temporary file with an extension like this, where `XXXXXX` represents a
random string and `.partial` is [--partial-suffix](#partial-suffix) value
(`.partial` by default).
hash of the source file's fingerprint and `.partial` is
[--partial-suffix](#partial-suffix) value (`.partial` by default).
original-file-name.XXXXXX.partial

View file

@ -8,6 +8,7 @@ import (
"context"
"errors"
"fmt"
"hash/crc32"
"io"
"path"
"strings"
@ -20,7 +21,6 @@ import (
"github.com/rclone/rclone/fs/hash"
"github.com/rclone/rclone/lib/atexit"
"github.com/rclone/rclone/lib/pacer"
"github.com/rclone/rclone/lib/random"
)
// State of the copy
@ -87,7 +87,7 @@ func TruncateString(s string, n int) string {
}
// Check to see if we should be using a partial name and return the name for the copy and the inplace flag
func (c *copy) checkPartial() (remoteForCopy string, inplace bool, err error) {
func (c *copy) checkPartial(ctx context.Context) (remoteForCopy string, inplace bool, err error) {
remoteForCopy = c.remote
if c.ci.Inplace || c.dstFeatures.Move == nil || !c.dstFeatures.PartialUploads || strings.HasSuffix(c.remote, ".rclonelink") {
return remoteForCopy, true, nil
@ -97,7 +97,11 @@ func (c *copy) checkPartial() (remoteForCopy string, inplace bool, err error) {
}
// Avoid making the leaf name longer if it's already lengthy to avoid
// trouble with file name length limits.
suffix := "." + random.String(8) + c.ci.PartialSuffix
// generate a stable random suffix by hashing the fingerprint
hash := crc32.ChecksumIEEE([]byte(fs.Fingerprint(ctx, c.src, true)))
suffix := fmt.Sprintf(".%x%s", hash, c.ci.PartialSuffix)
base := path.Base(remoteForCopy)
if len(base) > 100 {
remoteForCopy = TruncateString(remoteForCopy, len(remoteForCopy)-len(suffix)) + suffix
@ -400,7 +404,7 @@ func Copy(ctx context.Context, f fs.Fs, dst fs.Object, remote string, src fs.Obj
// Are we using partials?
//
// If so set the flag and update the name we use for the copy
c.remoteForCopy, c.inplace, err = c.checkPartial()
c.remoteForCopy, c.inplace, err = c.checkPartial(ctx)
if err != nil {
return nil, err
}