Skip to content

Instantly share code, notes, and snippets.

@suapapa

suapapa/go-ssh.go

Created Sep 3, 2014
Embed
What would you like to do?
execute cmd on multiple server via ssh
package main
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"time"
"code.google.com/p/go.crypto/ssh"
)
func exitIf(err error) {
if err != nil {
fmt.Println("error:", err)
os.Exit(-1)
}
}
func makeKeyAuth(keyname string) ssh.AuthMethod {
fp, err := os.Open(keyname)
exitIf(err)
defer fp.Close()
buf, err := ioutil.ReadAll(fp)
exitIf(err)
signer, err := ssh.ParsePrivateKey(buf)
exitIf(err)
return ssh.PublicKeys(signer)
}
func executeCmd(cmd, hostname string, config *ssh.ClientConfig) string {
conn, err := ssh.Dial("tcp", hostname, config)
exitIf(err)
session, err := conn.NewSession()
exitIf(err)
defer session.Close()
var stdoutBuf bytes.Buffer
session.Stdout = &stdoutBuf
session.Run(cmd)
return hostname + ": " + stdoutBuf.String()
}
func main() {
cmd := os.Args[1]
hosts := os.Args[2:]
results := make(chan string, 10)
config := &ssh.ClientConfig{
User: os.Getenv("LOGNAME"),
Auth: []ssh.AuthMethod{
makeKeyAuth(os.Getenv("HOME") + "/.ssh/id_rsa"),
},
}
for _, hostname := range hosts {
go func(hostname string) {
results <- executeCmd(cmd, hostname, config)
}(hostname)
}
timeout := time.After(30 * time.Second)
for i := 0; i < len(hosts); i++ {
select {
case res := <-results:
fmt.Print(res)
case <-timeout:
fmt.Println("Timed out!")
return
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.