From 870c58f7f8559a50d8e164342b191c033d790768 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Thu, 19 Apr 2018 09:45:46 +0100 Subject: [PATCH] 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. --- backend/sftp/sftp.go | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/backend/sftp/sftp.go b/backend/sftp/sftp.go index 8e1537455..51a7e7c98 100644 --- a/backend/sftp/sftp.go +++ b/backend/sftp/sftp.go @@ -5,6 +5,7 @@ package sftp import ( + "bytes" "context" "fmt" "io" @@ -733,40 +734,44 @@ func (o *Object) Remote() string { // Hash returns the selected checksum of the file // If no checksum is available it returns "" func (o *Object) Hash(r hash.Type) (string, error) { - if r == hash.MD5 && o.md5sum != nil { - return *o.md5sum, nil - } else if r == hash.SHA1 && o.sha1sum != nil { - return *o.sha1sum, nil + var hashCmd string + if r == hash.MD5 { + if o.md5sum != nil { + return *o.md5sum, nil + } + hashCmd = "md5sum" + } else if r == hash.SHA1 { + if o.sha1sum != nil { + return *o.sha1sum, nil + } + hashCmd = "sha1sum" + } else { + return "", hash.ErrUnsupported } c, err := o.fs.getSftpConnection() if err != nil { - return "", errors.Wrap(err, "Hash") + return "", errors.Wrap(err, "Hash get SFTP connection") } session, err := c.sshClient.NewSession() o.fs.putSftpConnection(&c, err) if err != nil { - o.fs.cachedHashes = nil // Something has changed on the remote system - return "", hash.ErrUnsupported + return "", errors.Wrap(err, "Hash put SFTP connection") } - err = hash.ErrUnsupported - var outputBytes []byte + var stdout, stderr bytes.Buffer + session.Stdout = &stdout + session.Stderr = &stderr escapedPath := shellEscape(o.path()) - if r == hash.MD5 { - outputBytes, err = session.Output("md5sum " + escapedPath) - } else if r == hash.SHA1 { - outputBytes, err = session.Output("sha1sum " + escapedPath) - } - + err = session.Run(hashCmd + " " + escapedPath) if err != nil { - o.fs.cachedHashes = nil // Something has changed on the remote system _ = 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() - str := parseHash(outputBytes) + str := parseHash(stdout.Bytes()) if r == hash.MD5 { o.md5sum = &str } else if r == hash.SHA1 {