mirror of
https://github.com/appleboy/drone-ssh.git
synced 2025-05-09 18:23:21 +08:00
Support stream output logs. (#79)
* Support stream output logs. Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com> * fix block channel. Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
This commit is contained in:
parent
f26bd7f7f7
commit
2d568d1fde
37
plugin.go
37
plugin.go
@ -11,8 +11,6 @@ import (
|
|||||||
"github.com/appleboy/easyssh-proxy"
|
"github.com/appleboy/easyssh-proxy"
|
||||||
)
|
)
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
missingHostOrUser = "Error: missing server host or user"
|
missingHostOrUser = "Error: missing server host or user"
|
||||||
missingPasswordOrKey = "Error: can't connect without a private SSH key or password"
|
missingPasswordOrKey = "Error: can't connect without a private SSH key or password"
|
||||||
@ -59,6 +57,7 @@ func (p Plugin) Exec() error {
|
|||||||
return fmt.Errorf(setPasswordandKey)
|
return fmt.Errorf(setPasswordandKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wg := sync.WaitGroup{}
|
||||||
wg.Add(len(p.Config.Host))
|
wg.Add(len(p.Config.Host))
|
||||||
errChannel := make(chan error, 1)
|
errChannel := make(chan error, 1)
|
||||||
finished := make(chan bool, 1)
|
finished := make(chan bool, 1)
|
||||||
@ -85,18 +84,34 @@ func (p Plugin) Exec() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
p.log(host, "commands: ", strings.Join(p.Config.Script, "\n"))
|
p.log(host, "commands: ", strings.Join(p.Config.Script, "\n"))
|
||||||
outStr, errStr, isTimeout, err := ssh.Run(strings.Join(p.Config.Script, "\n"), p.Config.CommandTimeout)
|
stdoutChan, stderrChan, doneChan, errChan, err := ssh.Stream(strings.Join(p.Config.Script, "\n"), p.Config.CommandTimeout)
|
||||||
p.log(host, "outputs:", outStr)
|
|
||||||
if len(errStr) != 0 {
|
|
||||||
p.log(host, "errors:", errStr)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errChannel <- err
|
errChannel <- err
|
||||||
}
|
} else {
|
||||||
|
// read from the output channel until the done signal is passed
|
||||||
|
stillGoing := true
|
||||||
|
isTimeout := true
|
||||||
|
for stillGoing {
|
||||||
|
select {
|
||||||
|
case isTimeout = <-doneChan:
|
||||||
|
stillGoing = false
|
||||||
|
case outline := <-stdoutChan:
|
||||||
|
p.log(host, "outputs:", outline)
|
||||||
|
case errline := <-stderrChan:
|
||||||
|
p.log(host, "errors:", errline)
|
||||||
|
case err = <-errChan:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !isTimeout {
|
// get exit code or command error.
|
||||||
errChannel <- fmt.Errorf(commandTimeOut)
|
if err != nil {
|
||||||
|
errChannel <- err
|
||||||
|
}
|
||||||
|
|
||||||
|
// command time out
|
||||||
|
if !isTimeout {
|
||||||
|
errChannel <- fmt.Errorf(commandTimeOut)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Done()
|
wg.Done()
|
||||||
|
@ -121,6 +121,22 @@ func TestSSHScriptFromKeyFile(t *testing.T) {
|
|||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestStreamFromSSHCommand(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{"whoami", "for i in {1..5}; do echo ${i}; sleep 1; done", "echo 'done'"},
|
||||||
|
CommandTimeout: 60,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
err := plugin.Exec()
|
||||||
|
assert.Nil(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
func TestSSHScriptWithError(t *testing.T) {
|
func TestSSHScriptWithError(t *testing.T) {
|
||||||
plugin := Plugin{
|
plugin := Plugin{
|
||||||
Config: Config{
|
Config: Config{
|
||||||
|
Loading…
Reference in New Issue
Block a user