-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathmain.go
113 lines (100 loc) · 2.72 KB
/
main.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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package main
import (
"fmt"
"net/http"
"time"
"io/ioutil"
"encoding/json"
"log"
"os"
// "strings"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ecs"
)
type instance struct {
Cluster string `json:"Cluster"`
Arn string `json:"ContainerInstanceArn"`
}
func getContainerInstance() instance {
client := http.Client{
Timeout: time.Second * 2, // Maximum of 2 secs
}
containerInstance := instance{}
req, err := http.NewRequest(http.MethodGet, "http://0.0.0.0:51678/v1/metadata", nil)
if err != nil {
log.Fatal(err)
}
res, getErr := client.Do(req)
if getErr != nil {
fmt.Println(getErr)
return containerInstance
// log.Fatal(getErr)
}
body, readErr := ioutil.ReadAll(res.Body)
if readErr != nil {
log.Fatal(readErr)
}
jsonErr := json.Unmarshal(body, &containerInstance)
if jsonErr != nil {
log.Fatal(jsonErr)
}
fmt.Printf("HTTP: %s\n", res.Status)
return containerInstance
}
func isStopping() bool {
client := http.Client{
Timeout: time.Second * 2, // Maximum of 2 secs
}
ec2_url := os.Getenv("EC2METADATA_URL")
if ec2_url == "" {
ec2_url = "169.254.169.254"
}
url := fmt.Sprintf("http://%s/latest/meta-data/spot/termination-time", ec2_url)
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
log.Fatal(err)
}
res, getErr := client.Do(req)
if getErr != nil {
log.Fatal(getErr)
}
fmt.Println("Checking spot status...")
return res.StatusCode == 200
}
func drain(containerInstance instance) {
// ecs stuff
svc := ecs.New(session.New())
input := &ecs.UpdateContainerInstancesStateInput {
ContainerInstances: []*string{aws.String(containerInstance.Arn)},
Cluster: aws.String(containerInstance.Cluster),
Status: aws.String("DRAINING"),
}
req, resp := svc.UpdateContainerInstancesStateRequest(input)
err := req.Send()
if err != nil { // resp is now filled
fmt.Println(resp)
fmt.Println(err)
}
fmt.Println("Successfully drained the instance")
os.Exit(0)
}
func main() {
containerInstance := getContainerInstance()
for containerInstance == (instance{}) {
fmt.Println("Cannot communicate with ECS Agent. Retrying...")
time.Sleep(time.Second * 5)
containerInstance = getContainerInstance()
}
fmt.Printf("Found ECS Container Instance %s\n", containerInstance.Arn)
fmt.Printf("on the %s cluster.\n", containerInstance.Cluster)
for true {
if isStopping() {
fmt.Println("Spot instance is being acted upon. Doing something")
fmt.Printf("Drain this %s\n", containerInstance.Arn)
// drain this one
drain(containerInstance)
}
time.Sleep(time.Second * 5)
}
}