diff --git a/plugin_test.go b/plugin_test.go index 8372f36..1688ba6 100644 --- a/plugin_test.go +++ b/plugin_test.go @@ -121,6 +121,23 @@ func TestSSHScriptFromKeyFile(t *testing.T) { assert.Nil(t, err) } +func TestSSHScriptWithError(t *testing.T) { + plugin := Plugin{ + Config: Config{ + Host: []string{"localhost", "127.0.0.1"}, + UserName: "drone-scp", + Port: 22, + KeyPath: "./tests/.ssh/id_rsa", + Script: []string{"exit 1"}, + CommandTimeout: 60, + }, + } + + err := plugin.Exec() + // Process exited with status 1 + assert.NotNil(t, err) +} + func TestSSHCommandTimeOut(t *testing.T) { plugin := Plugin{ Config: Config{ diff --git a/vendor/github.com/appleboy/easyssh-proxy/easyssh.go b/vendor/github.com/appleboy/easyssh-proxy/easyssh.go index e28b954..60ac45b 100644 --- a/vendor/github.com/appleboy/easyssh-proxy/easyssh.go +++ b/vendor/github.com/appleboy/easyssh-proxy/easyssh.go @@ -155,36 +155,44 @@ func (ssh_conf *MakeConfig) connect() (*ssh.Session, error) { // Stream returns one channel that combines the stdout and stderr of the command // as it is run on the remote machine, and another that sends true when the // command is done. The sessions and channels will then be closed. -func (ssh_conf *MakeConfig) Stream(command string, timeout int) (stdout chan string, stderr chan string, done chan bool, err error) { +func (ssh_conf *MakeConfig) Stream(command string, timeout int) (stdout chan string, stderr chan string, done chan bool, errChan chan error, err error) { // connect to remote host session, err := ssh_conf.connect() if err != nil { - return stdout, stderr, done, err + return stdout, stderr, done, errChan, err } + // defer session.Close() // connect to both outputs (they are of type io.Reader) outReader, err := session.StdoutPipe() if err != nil { - return stdout, stderr, done, err + return stdout, stderr, done, errChan, err } errReader, err := session.StderrPipe() if err != nil { - return stdout, stderr, done, err + return stdout, stderr, done, errChan, err } + err = session.Start(command) + if err != nil { + return stdout, stderr, done, errChan, err + } + // combine outputs, create a line-by-line scanner stdoutReader := io.MultiReader(outReader) stderrReader := io.MultiReader(errReader) - err = session.Start(command) stdoutScanner := bufio.NewScanner(stdoutReader) stderrScanner := bufio.NewScanner(stderrReader) // continuously send the command's output over the channel stdoutChan := make(chan string) stderrChan := make(chan string) done = make(chan bool) + errChan = make(chan error) - go func(stdoutScanner, stderrScanner *bufio.Scanner, stdoutChan, stderrChan chan string, done chan bool) { + go func(stdoutScanner, stderrScanner *bufio.Scanner, stdoutChan, stderrChan chan string, done chan bool, errChan chan error) { defer close(stdoutChan) defer close(stderrChan) defer close(done) + defer close(errChan) + defer session.Close() timeoutChan := time.After(time.Duration(timeout) * time.Second) res := make(chan bool, 1) @@ -204,21 +212,22 @@ func (ssh_conf *MakeConfig) Stream(command string, timeout int) (stdout chan str case <-res: stdoutChan <- "" stderrChan <- "" + errChan <- session.Wait() done <- true case <-timeoutChan: stdoutChan <- "" stderrChan <- "Run Command Timeout!" + errChan <- nil done <- false } + }(stdoutScanner, stderrScanner, stdoutChan, stderrChan, done, errChan) - session.Close() - }(stdoutScanner, stderrScanner, stdoutChan, stderrChan, done) - return stdoutChan, stderrChan, done, err + return stdoutChan, stderrChan, done, errChan, err } // Run command on remote machine and returns its stdout as a string func (ssh_conf *MakeConfig) Run(command string, timeout int) (outStr string, errStr string, isTimeout bool, err error) { - stdoutChan, stderrChan, doneChan, err := ssh_conf.Stream(command, timeout) + stdoutChan, stderrChan, doneChan, errChan, err := ssh_conf.Stream(command, timeout) if err != nil { return outStr, errStr, isTimeout, err } @@ -236,6 +245,7 @@ func (ssh_conf *MakeConfig) Run(command string, timeout int) (outStr string, err if errline != "" { errStr += errline + "\n" } + case err = <-errChan: } } // return the concatenation of all signals from the output channel @@ -266,17 +276,20 @@ func (ssh_conf *MakeConfig) Scp(sourceFile string, etargetFile string) error { } go func() { - w, _ := session.StdinPipe() + w, err := session.StdinPipe() + + if err != nil { + return + } + defer w.Close() fmt.Fprintln(w, "C0644", srcStat.Size(), targetFile) if srcStat.Size() > 0 { io.Copy(w, src) fmt.Fprint(w, "\x00") - w.Close() } else { fmt.Fprint(w, "\x00") - w.Close() } }() diff --git a/vendor/vendor.json b/vendor/vendor.json index 870b5a6..1efbe80 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -3,12 +3,12 @@ "ignore": "test", "package": [ { - "checksumSHA1": "L3PugNJJOEpRmRbD+27LgTZC2E4=", + "checksumSHA1": "/Sb+z/BicEjhh6Ib7Tawr64BNHA=", "path": "github.com/appleboy/easyssh-proxy", - "revision": "a13ed86767b8e8a24d8147a4909a702e7cf6b465", - "revisionTime": "2017-04-14T13:46:38Z", - "version": "1.1.2", - "versionExact": "1.1.2" + "revision": "cf4f2bae639f692dbc7b3f852be35125a1a645e3", + "revisionTime": "2017-05-09T01:16:07Z", + "version": "1.1.3", + "versionExact": "1.1.3" }, { "checksumSHA1": "dvabztWVQX8f6oMLRyv4dLH+TGY=",