Skip to content

Instantly share code, notes, and snippets.

@mpobrien
Created January 3, 2015 05:23
Show Gist options
  • Save mpobrien/fec06f5c78df869aaf4d to your computer and use it in GitHub Desktop.
Save mpobrien/fec06f5c78df869aaf4d to your computer and use it in GitHub Desktop.
package main
import (
"bytes"
"code.google.com/p/go.crypto/ssh"
"fmt"
"io/ioutil"
"os"
"time"
)
func makeSigner(keyname string) (signer ssh.Signer, err error) {
fp, err := os.Open(keyname)
if err != nil {
return
}
defer fp.Close()
buf, _ := ioutil.ReadAll(fp)
signer, _ = ssh.ParsePrivateKey(buf)
return
}
func executeCmd(cmd, hostname string, config *ssh.ClientConfig) (string, error) {
conn, err := ssh.Dial("tcp", hostname+":22", config)
if err != nil {
return "", err
}
session, err := conn.NewSession()
if err != nil {
return "", err
}
defer session.Close()
var stdoutBuf bytes.Buffer
session.Stdout = &stdoutBuf
session.Run(cmd)
return hostname + ": " + stdoutBuf.String(), nil
}
func main() {
cmd := os.Args[1]
hosts := os.Args[2:]
keyPath := os.Getenv("HOME") + "/.ssh/id_rsa"
results := make(chan string, 10)
timeout := time.After(5 * time.Second)
signer, err := makeSigner(keyPath)
if err != nil {
fmt.Println("Couldn't get private key")
return
}
config := &ssh.ClientConfig{
User: os.Getenv("LOGNAME"),
Auth: []ssh.AuthMethod{ssh.PublicKeys(signer)},
}
for _, hostname := range hosts {
go func(hostname string) {
result, err := executeCmd(cmd, hostname, config)
if err != nil {
fmt.Println("error: ", err)
return
}
results <- result
}(hostname)
}
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