Return errors from remote scp command
Currently file provisioners will silently fail when there is an error with the remote side. This commit checks the scp error code and will return the error message from the remote.
This commit is contained in:
parent
9ab04e953b
commit
ebd14bb2df
|
@ -1,6 +1,7 @@
|
|||
package ssh
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"code.google.com/p/go.crypto/ssh"
|
||||
"errors"
|
||||
|
@ -106,12 +107,6 @@ func (c *comm) Upload(path string, input io.Reader) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// Set stderr/stdout to a bytes buffer
|
||||
stderr := new(bytes.Buffer)
|
||||
stdout := new(bytes.Buffer)
|
||||
session.Stderr = stderr
|
||||
session.Stdout = stdout
|
||||
|
||||
// We only want to close once, so we nil w after we close it,
|
||||
// and only close in the defer if it hasn't been closed already.
|
||||
defer func() {
|
||||
|
@ -120,6 +115,17 @@ func (c *comm) Upload(path string, input io.Reader) error {
|
|||
}
|
||||
}()
|
||||
|
||||
// Get a pipe to stdout so that we can get responses back
|
||||
scp_reader, err := session.StdoutPipe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r := bufio.NewReader(scp_reader)
|
||||
|
||||
// Set stderr to a bytes buffer
|
||||
stderr := new(bytes.Buffer)
|
||||
session.Stderr = stderr
|
||||
|
||||
// The target directory and file for talking the SCP protocol
|
||||
target_dir := filepath.Dir(path)
|
||||
target_file := filepath.Base(path)
|
||||
|
@ -143,8 +149,17 @@ func (c *comm) Upload(path string, input io.Reader) error {
|
|||
// Start the protocol
|
||||
log.Println("Beginning file upload...")
|
||||
fmt.Fprintln(w, "C0644", input_memory.Len(), target_file)
|
||||
err = check_response(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
io.Copy(w, input_memory)
|
||||
fmt.Fprint(w, "\x00")
|
||||
err = check_response(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO(mitchellh): Each step above results in a 0/1/2 being sent by
|
||||
// the remote side to confirm. We should check for those confirmations.
|
||||
|
@ -178,7 +193,6 @@ func (c *comm) Upload(path string, input io.Reader) error {
|
|||
return err
|
||||
}
|
||||
|
||||
log.Printf("scp stdout (length %d): %#v", stdout.Len(), stdout.Bytes())
|
||||
log.Printf("scp stderr (length %d): %s", stderr.Len(), stderr.String())
|
||||
|
||||
return nil
|
||||
|
@ -223,3 +237,17 @@ func (c *comm) reconnect() (err error) {
|
|||
|
||||
return
|
||||
}
|
||||
|
||||
func check_response(r *bufio.Reader) (err error) {
|
||||
scp_status_code, err := r.ReadByte()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if scp_status_code != 0 {
|
||||
// Treat any non-zero (really 1 and 2) as fatal errors
|
||||
error_message, _, err := r.ReadLine()
|
||||
err = fmt.Errorf(string(error_message[:]))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue