Works with golang-1.6
package main
import (
"bytes"
"fmt"
"log"
"io/ioutil"
"os"
"time"
)
func executeCmd(cmd, hostname string, config *ssh.ClientConfig) string {
conn, _ := ssh.Dial("tcp", hostname+":22", config)
session, _ := conn.NewSession()
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)
timeout := time.After(5 * time.Second)
pkey, err := ioutil.ReadFile("/path/to/home/.ssh/id_rsa")
if err != nil {
log.Fatalf("unable to read private key: %v", err)
}
// Create the Signer for this private key.
signer, err := ssh.ParsePrivateKey(pkey)
if err != nil {
log.Fatalf("unable to parse private key: %v", err)
}
config := &ssh.ClientConfig{
User: os.Getenv("LOGNAME"),
Auth: []ssh.AuthMethod{
// Use the PublicKeys method for remote authentication.
ssh.PublicKeys(signer),
},
}
for _, hostname := range hosts {
go func(hostname string) {
results <- executeCmd(cmd, hostname, config)
}(hostname)
}
for i := 0; i < len(hosts); i++ {
select {
case res := <-results:
fmt.Print(res)
case <-timeout:
fmt.Println("Timed out!")
return