-
Notifications
You must be signed in to change notification settings - Fork 79
/
ec2.go
80 lines (71 loc) · 1.96 KB
/
ec2.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
package ec2
import (
"fmt"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
"go.uber.org/zap"
)
// PollUntilRunning describes EC2 instances by batch,
// and waits until all instances are 'running'.
func PollUntilRunning(
timeout time.Duration,
lg *zap.Logger,
ec2API ec2iface.EC2API,
instanceIDs ...string) (ec2Instances map[string]*ec2.Instance, err error) {
retryStart := time.Now()
for time.Now().Sub(retryStart) < timeout {
ec2Instances, err = describeByBatch(lg, ec2API, instanceIDs...)
if err == nil {
return ec2Instances, nil
}
lg.Error("failed to describe instances", zap.Error(err))
time.Sleep(10 * time.Second)
}
return ec2Instances, err
}
func describeByBatch(
lg *zap.Logger,
ec2API ec2iface.EC2API,
instanceIDs ...string) (ec2Instances map[string]*ec2.Instance, err error) {
ec2Instances = make(map[string]*ec2.Instance, len(instanceIDs))
ids := make([]string, len(instanceIDs))
copy(ids, instanceIDs)
// batch by 10
for len(ids) > 0 {
iss := ids
if len(ids) > 10 {
iss = ids[:10]
}
var dout *ec2.DescribeInstancesOutput
dout, err = ec2API.DescribeInstances(&ec2.DescribeInstancesInput{
InstanceIds: aws.StringSlice(iss),
})
if err != nil {
return nil, fmt.Errorf("failed to describe instances %v", err)
}
runningCnt := 0
for _, rsrv := range dout.Reservations {
for _, iv := range rsrv.Instances {
if aws.StringValue(iv.State.Name) == ec2.InstanceStateNameRunning {
runningCnt++
}
ec2Instances[aws.StringValue(iv.InstanceId)] = iv
}
}
if runningCnt != len(iss) {
return nil, fmt.Errorf("running instances expected %d, got %d", len(iss), runningCnt)
}
lg.Info("EC2 instances are running",
zap.Int("reservations", len(dout.Reservations)),
zap.Int("instances-so-far", len(ec2Instances)),
)
if len(ids) <= 10 {
break
}
ids = ids[:10]
time.Sleep(5 * time.Second)
}
return ec2Instances, nil
}