forked from docker/machine
/
ssh.go
77 lines (63 loc) · 1.73 KB
/
ssh.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package ssh
import (
"fmt"
"net"
"os"
"os/exec"
"strings"
log "github.com/Sirupsen/logrus"
)
func GetSSHCommand(host string, port int, user string, sshKey string, args ...string) *exec.Cmd {
defaultSSHArgs := []string{
"-o", "IdentitiesOnly=yes",
"-o", "StrictHostKeyChecking=no", // don't bother checking in ~/.ssh/known_hosts
"-o", "UserKnownHostsFile=/dev/null", // don't write anything to ~/.ssh/known_hosts
"-o", "ConnectionAttempts=30", // retry 30 times if SSH connection fails
"-o", "LogLevel=quiet", // suppress "Warning: Permanently added '[localhost]:2022' (ECDSA) to the list of known hosts."
"-p", fmt.Sprintf("%d", port),
"-i", sshKey,
fmt.Sprintf("%s@%s", user, host),
}
sshArgs := append(defaultSSHArgs, args...)
cmd := exec.Command("ssh", sshArgs...)
cmd.Stderr = os.Stderr
if os.Getenv("DEBUG") != "" {
cmd.Stdout = os.Stdout
}
log.Debugf("executing: %v", strings.Join(cmd.Args, " "))
return cmd
}
func GenerateSSHKey(path string) error {
if _, err := exec.LookPath("ssh-keygen"); err != nil {
return fmt.Errorf("ssh-keygen not found in the path, please install ssh-keygen")
}
if _, err := os.Stat(path); err != nil {
if !os.IsNotExist(err) {
return err
}
cmd := exec.Command("ssh-keygen", "-t", "rsa", "-N", "", "-f", path)
if os.Getenv("DEBUG") != "" {
cmd.Stdout = os.Stdout
}
cmd.Stderr = os.Stderr
log.Debugf("executing: %v %v\n", cmd.Path, strings.Join(cmd.Args, " "))
if err := cmd.Run(); err != nil {
return err
}
}
return nil
}
func WaitForTCP(addr string) error {
for {
conn, err := net.Dial("tcp", addr)
if err != nil {
continue
}
defer conn.Close()
if _, err = conn.Read(make([]byte, 1)); err != nil {
continue
}
break
}
return nil
}