Add sync mode. (#101)

* Add sync mode.

Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>

* close channel in sync mode.

Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>

* close channel in sync mode.

Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
This commit is contained in:
Bo-Yi Wu 2017-10-29 21:31:51 -05:00 committed by GitHub
parent 2d5668ff17
commit 7220c94832
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 103 additions and 73 deletions

View File

@ -66,6 +66,11 @@ func main() {
EnvVar: "PLUGIN_PORT,SSH_PORT",
Value: 22,
},
cli.BoolFlag{
Name: "sync",
Usage: "sync mode",
EnvVar: "PLUGIN_SYNC",
},
cli.DurationFlag{
Name: "timeout,t",
Usage: "connection timeout",
@ -195,6 +200,7 @@ func run(c *cli.Context) error {
Secrets: c.StringSlice("secrets"),
Envs: c.StringSlice("envs"),
Debug: c.Bool("debug"),
Sync: c.Bool("sync"),
Proxy: easyssh.DefaultConfig{
Key: c.String("proxy.ssh-key"),
KeyPath: c.String("proxy.key-path"),

View File

@ -34,6 +34,7 @@ type (
Envs []string
Proxy easyssh.DefaultConfig
Debug bool
Sync bool
}
// Plugin structure
@ -42,34 +43,7 @@ type (
}
)
func (p Plugin) log(host string, message ...interface{}) {
if count := len(p.Config.Host); count == 1 {
fmt.Printf("%s", fmt.Sprintln(message...))
} else {
fmt.Printf("%s: %s", host, fmt.Sprintln(message...))
}
}
// Exec executes the plugin.
func (p Plugin) Exec() error {
if len(p.Config.Host) == 0 && len(p.Config.UserName) == 0 {
return fmt.Errorf(missingHostOrUser)
}
if len(p.Config.Key) == 0 && len(p.Config.Password) == 0 && len(p.Config.KeyPath) == 0 {
return fmt.Errorf(missingPasswordOrKey)
}
if len(p.Config.Key) != 0 && len(p.Config.Password) != 0 {
return fmt.Errorf(setPasswordandKey)
}
wg := sync.WaitGroup{}
wg.Add(len(p.Config.Host))
errChannel := make(chan error, 1)
finished := make(chan bool, 1)
for _, host := range p.Config.Host {
go func(host string) {
func (p Plugin) exec(host string, wg *sync.WaitGroup, errChannel chan error) {
// Create MakeConfig instance with remote username, server address and path to private key.
ssh := &easyssh.MakeConfig{
Server: host,
@ -141,7 +115,40 @@ func (p Plugin) Exec() error {
}
wg.Done()
}(host)
}
func (p Plugin) log(host string, message ...interface{}) {
if count := len(p.Config.Host); count == 1 {
fmt.Printf("%s", fmt.Sprintln(message...))
} else {
fmt.Printf("%s: %s", host, fmt.Sprintln(message...))
}
}
// Exec executes the plugin.
func (p Plugin) Exec() error {
if len(p.Config.Host) == 0 && len(p.Config.UserName) == 0 {
return fmt.Errorf(missingHostOrUser)
}
if len(p.Config.Key) == 0 && len(p.Config.Password) == 0 && len(p.Config.KeyPath) == 0 {
return fmt.Errorf(missingPasswordOrKey)
}
if len(p.Config.Key) != 0 && len(p.Config.Password) != 0 {
return fmt.Errorf(setPasswordandKey)
}
wg := sync.WaitGroup{}
wg.Add(len(p.Config.Host))
errChannel := make(chan error, 1)
finished := make(chan bool, 1)
for _, host := range p.Config.Host {
if p.Config.Sync {
p.exec(host, &wg, errChannel)
} else {
go p.exec(host, &wg, errChannel)
}
}
go func() {

View File

@ -256,3 +256,20 @@ func TestSetENV(t *testing.T) {
err := plugin.Exec()
assert.Nil(t, err)
}
func TestSyncMode(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..3}; do echo ${i}; sleep 1; done", "echo 'done'"},
CommandTimeout: 60,
Sync: true,
},
}
err := plugin.Exec()
assert.Nil(t, err)
}