mirror of
https://github.com/rclone/rclone.git
synced 2025-12-25 20:53:28 +00:00
sftp: fail soft with a debug on hash failure #1474
If md5sum/sha1sum fails we debug what it outputed on stderr and return an empty hash indicating we didn't have a hash, rather than hash.ErrUnsupported indicating that we don't support this hash type. This fixes lots of ERROR messages for sftp and synology NAS which, while it supports md5sum the SFTP paths and the SSH paths are different so md5sum doesn't work. We also stop disabling md5sum/sha1sum on errors since typically Hashes is only checked at the start of a sync run and isn't expected to change dynamically.
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
package sftp
|
package sftp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@@ -733,40 +734,44 @@ func (o *Object) Remote() string {
|
|||||||
// Hash returns the selected checksum of the file
|
// Hash returns the selected checksum of the file
|
||||||
// If no checksum is available it returns ""
|
// If no checksum is available it returns ""
|
||||||
func (o *Object) Hash(r hash.Type) (string, error) {
|
func (o *Object) Hash(r hash.Type) (string, error) {
|
||||||
if r == hash.MD5 && o.md5sum != nil {
|
var hashCmd string
|
||||||
|
if r == hash.MD5 {
|
||||||
|
if o.md5sum != nil {
|
||||||
return *o.md5sum, nil
|
return *o.md5sum, nil
|
||||||
} else if r == hash.SHA1 && o.sha1sum != nil {
|
}
|
||||||
|
hashCmd = "md5sum"
|
||||||
|
} else if r == hash.SHA1 {
|
||||||
|
if o.sha1sum != nil {
|
||||||
return *o.sha1sum, nil
|
return *o.sha1sum, nil
|
||||||
}
|
}
|
||||||
|
hashCmd = "sha1sum"
|
||||||
|
} else {
|
||||||
|
return "", hash.ErrUnsupported
|
||||||
|
}
|
||||||
|
|
||||||
c, err := o.fs.getSftpConnection()
|
c, err := o.fs.getSftpConnection()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.Wrap(err, "Hash")
|
return "", errors.Wrap(err, "Hash get SFTP connection")
|
||||||
}
|
}
|
||||||
session, err := c.sshClient.NewSession()
|
session, err := c.sshClient.NewSession()
|
||||||
o.fs.putSftpConnection(&c, err)
|
o.fs.putSftpConnection(&c, err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
o.fs.cachedHashes = nil // Something has changed on the remote system
|
return "", errors.Wrap(err, "Hash put SFTP connection")
|
||||||
return "", hash.ErrUnsupported
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = hash.ErrUnsupported
|
var stdout, stderr bytes.Buffer
|
||||||
var outputBytes []byte
|
session.Stdout = &stdout
|
||||||
|
session.Stderr = &stderr
|
||||||
escapedPath := shellEscape(o.path())
|
escapedPath := shellEscape(o.path())
|
||||||
if r == hash.MD5 {
|
err = session.Run(hashCmd + " " + escapedPath)
|
||||||
outputBytes, err = session.Output("md5sum " + escapedPath)
|
|
||||||
} else if r == hash.SHA1 {
|
|
||||||
outputBytes, err = session.Output("sha1sum " + escapedPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
o.fs.cachedHashes = nil // Something has changed on the remote system
|
|
||||||
_ = session.Close()
|
_ = session.Close()
|
||||||
return "", hash.ErrUnsupported
|
fs.Debugf(o, "Failed to calculate %v hash: %v (%s)", r, err, bytes.TrimSpace(stderr.Bytes()))
|
||||||
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = session.Close()
|
_ = session.Close()
|
||||||
str := parseHash(outputBytes)
|
str := parseHash(stdout.Bytes())
|
||||||
if r == hash.MD5 {
|
if r == hash.MD5 {
|
||||||
o.md5sum = &str
|
o.md5sum = &str
|
||||||
} else if r == hash.SHA1 {
|
} else if r == hash.SHA1 {
|
||||||
|
|||||||
Reference in New Issue
Block a user