1
mirror of https://github.com/rclone/rclone synced 2024-12-27 19:43:48 +01:00

operations: Fix "optional feature not implemented" error with a crypted sftp

Before this change operations.SetDirModTime could return the error
"optional feature not implemented" when attempting to set modification
times on crypted sftp backends.

This was because crypt wraps the directories using fs.DirWrapper but
these return fs.ErrorNotImplemented for the SetModTime method.

The fix is to recognise that error and fall back to using the
DirSetModTime method on the backend which does work.

Fixes #7673
This commit is contained in:
Nick Craig-Wood 2024-03-13 16:53:19 +00:00
parent 5ee89bdcf8
commit ff855fe1fb
2 changed files with 14 additions and 3 deletions

View File

@ -2628,11 +2628,15 @@ func SetDirModTime(ctx context.Context, f fs.Fs, dst fs.Directory, dir string, m
if dst != nil {
if do, ok := dst.(fs.SetModTimer); ok {
err := do.SetModTime(ctx, modTime)
if err != nil {
if errors.Is(err, fs.ErrorNotImplemented) {
// Fall through and run the code below if not implemented
// This can happen for fs.DirWrapper instances
} else if err != nil {
return dst, err
} else {
fs.Infof(logName, "Set directory modification time (using SetModTime)")
return dst, nil
}
fs.Infof(logName, "Set directory modification time (using SetModTime)")
return dst, nil
}
}

View File

@ -1787,6 +1787,13 @@ func TestSetDirModTime(t *testing.T) {
fstest.CheckDirModTime(ctx, t, r.Fremote, newDst, t2)
}
fstest.CheckDirModTime(ctx, t, r.Fremote, fstest.NewDirectory(ctx, t, r.Fremote, name), t2)
// Now wrap the directory to make the SetModTime method return fs.ErrorNotImplemented and check that it falls back correctly
wrappedDir := fs.NewDirWrapper(existingDir.Remote(), fs.NewDir(existingDir.Remote(), existingDir.ModTime(ctx)))
newDst, err = operations.SetDirModTime(ctx, r.Fremote, wrappedDir, "SHOULD BE IGNORED", t1)
require.NoError(t, err)
require.NotNil(t, newDst)
fstest.CheckDirModTime(ctx, t, r.Fremote, fstest.NewDirectory(ctx, t, r.Fremote, name), t1)
}
func TestDirsEqual(t *testing.T) {