-
Notifications
You must be signed in to change notification settings - Fork 2
/
watch.go
116 lines (87 loc) · 2.57 KB
/
watch.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
114
115
116
package main
import (
"fmt"
"strings"
"github.com/dynport/gocloud/aws/cloudformation"
"github.com/vito/cloudformer/aws/deployer"
"github.com/hotei/ansiterm"
"github.com/mgutz/ansi"
)
func watch(name string) {
deployer := deployer.New(cloudformation.NewFromEnv())
events := make(chan *cloudformation.StackEvent)
go deployer.Watch(events, name)
ok := streamEvents(events)
if !ok {
fmt.Println()
fatal(ansi.Color("formation failed and was rolled back", "yellow"))
}
}
func streamEvents(events <-chan *cloudformation.StackEvent) bool {
ok := true
inFlight := make(map[string]Process)
printedLines := 0
for ev := range events {
status := ev.ResourceStatus
for i := 0; i < printedLines; i++ {
fmt.Print("\x1b[1A")
ansiterm.ClearLine()
}
process, progress := parseStatus(status)
if progress == PendingProgress {
inFlight[ev.LogicalResourceId] = process
} else {
delete(inFlight, ev.LogicalResourceId)
label := process.CompletedLabel()
if progress == FailedProgress {
ok = false
fmt.Printf(ansi.Color("%s: %s (%s)\n", "red"), label, ev.LogicalResourceId, ev.ResourceStatusReason)
} else {
fmt.Printf(ansi.Color("%s: %s (%s)\n", "green"), label, ev.LogicalResourceId, ev.PhysicalResourceId)
}
}
printedLines = renderInFlight(inFlight)
}
return ok
}
func renderInFlight(inFlight map[string]Process) int {
byProcess := make(map[Process][]string)
for id, process := range inFlight {
byProcess[process] = append(byProcess[process], id)
}
printedLines := 0
for process, ids := range byProcess {
prefix := process.ActiveLabel() + ": "
for i, id := range ids {
if i == 0 {
fmt.Print(prefix)
} else {
fmt.Print(strings.Repeat(" ", len(prefix)))
}
fmt.Println(id)
printedLines++
}
}
return printedLines
}
func parseStatus(status string) (Process, Progress) {
var process Process
var progress Progress
if strings.Contains(status, "ROLLBACK") {
process = RollbackProcess
} else if strings.Contains(status, "UPDATE") {
process = UpdateProcess
} else if strings.Contains(status, "DELETE") {
process = DeleteProcess
} else if strings.Contains(status, "CREATE") {
process = CreateProcess
}
if strings.HasSuffix(status, "FAILED") {
progress = FailedProgress
} else if strings.HasSuffix(status, "COMPLETED") {
progress = CompletedProgress
} else if strings.HasSuffix(status, "IN_PROGRESS") {
progress = PendingProgress
}
return process, progress
}