This repository has been archived by the owner on Jul 25, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 11
/
utils.go
92 lines (85 loc) · 1.66 KB
/
utils.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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package ec2
import (
"fmt"
"net"
"strings"
"time"
)
func IpForSsh(instance *Instance) (openIp string, e error) {
cnt := 0
type status struct {
ip string
ok bool
}
c := make(chan *status)
for _, i := range []string{instance.PrivateIpAddress, instance.IpAddress} {
cnt++
go func(ip string, ch chan *status) {
rsp := &status{ip: ip}
defer func() { c <- rsp }()
c, e := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", ip, 22), 100*time.Millisecond)
if e != nil {
return
}
defer c.Close()
rsp.ok = true
}(i, c)
}
timeout := time.After(2 * time.Second)
for cnt > 0 {
select {
case s := <-c:
cnt--
if s.ok {
return s.ip, nil
}
case <-timeout:
return "", fmt.Errorf("timed out")
}
}
return "", nil
}
func waitForSsh(instance *Instance, timeoutDuration time.Duration) (string, error) {
ticker := time.Tick(1 * time.Second)
timeout := time.After(timeoutDuration)
for {
select {
case <-ticker:
ip, e := IpForSsh(instance)
if e == nil {
return ip, nil
}
case <-timeout:
return "", fmt.Errorf("timeout waiting for ssh")
}
}
}
func WaitForInstances(instances []*Instance, timeout time.Duration) error {
cnt := 0
type result struct {
Error error
Ip string
}
finished := make(chan *result)
for _, i := range instances {
cnt++
go func(inst *Instance) {
ip, e := waitForSsh(inst, timeout)
finished <- &result{Error: e, Ip: ip}
}(i)
}
errors := []string{}
for cnt > 0 {
select {
case r := <-finished:
cnt--
if r.Error != nil {
errors = append(errors, r.Ip+": "+r.Error.Error())
}
}
}
if len(errors) > 0 {
return fmt.Errorf(strings.Join(errors, ", "))
}
return nil
}