/
main.go
156 lines (140 loc) · 3.8 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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package main
import (
"encoding/json"
"errors"
"fmt"
"net/http"
"net/url"
"os"
"github.com/codegangsta/cli"
"github.com/fatih/color"
"github.com/garyburd/redigo/redis"
"github.com/octoblu/go-logentry/logentry"
)
func main() {
app := cli.NewApp()
app.Name = "tattle"
app.Action = run
app.Version = VERSION
app.Flags = []cli.Flag{
cli.StringFlag{
Name: "docker-url, d",
EnvVar: "TATTLE_DOCKER_URL",
Usage: "Docker URL of the service",
},
cli.StringFlag{
Name: "etcd-dir, e",
EnvVar: "TATTLE_ETCD_DIR",
Usage: "Etcd dir of the service",
},
cli.IntFlag{
Name: "exit-code, x",
EnvVar: "TATTLE_EXIT_CODE",
Usage: "Code that the service failed with",
},
cli.StringFlag{
Name: "redis-uri, r",
EnvVar: "TATTLE_REDIS_URI",
Usage: "Redis server to tattle to",
},
cli.StringFlag{
Name: "redis-queue, q",
EnvVar: "TATTLE_REDIS_QUEUE",
Usage: "Redis queue to place the tattle in",
},
cli.StringFlag{
Name: "uri, u",
EnvVar: "TATTLE_URI",
Usage: "Uri to POST to with a cancellation notice",
},
cli.StringFlag{
Name: "worker-name, w",
EnvVar: "TATTLE_WORKER_NAME",
Usage: "Name of the worker to tattle on",
},
}
app.Run(os.Args)
}
func run(context *cli.Context) error {
dockerURL := context.String("docker-url")
etcdDir := context.String("etcd-dir")
exitCode := context.Int("exit-code")
redisURI := context.String("redis-uri")
redisQueue := context.String("redis-queue")
uri := context.String("uri")
workerName := context.String("worker-name")
if dockerURL == "" || etcdDir == "" || exitCode == 0 || redisURI == "" || redisQueue == "" || uri == "" || workerName == "" {
cli.ShowAppHelp(context)
if dockerURL == "" {
color.Red(" Missing required flag --docker-url or TATTLE_DOCKER_URL")
}
if etcdDir == "" {
color.Red(" Missing required flag --etcd-dir or TATTLE_ETCD_DIR")
}
if exitCode == 0 {
color.Red(" Missing required flag --exit-code or TATTLE_EXIT_CODE")
}
if redisURI == "" {
color.Red(" Missing required flag --redis-uri or TATTLE_REDIS_URI")
}
if redisQueue == "" {
color.Red(" Missing required flag --redis-queue or TATTLE_REDIS_QUEUE")
}
if uri == "" {
color.Red(" Missing required flag --uri or TATTLE_URI")
}
if workerName == "" {
color.Red(" Missing required flag --worker-name or TATTLE_WORKER_NAME")
}
os.Exit(1)
}
logErrorChannel := make(chan error)
postErrorChannel := make(chan error)
go func() {
logErrorChannel <- logJob(redisURI, redisQueue, dockerURL, workerName, exitCode)
}()
go func() {
postErrorChannel <- postToGovernator(uri, dockerURL, etcdDir, exitCode)
}()
logError := <-logErrorChannel
postError := <-postErrorChannel
if logError != nil || postError != nil {
if logError != nil {
fmt.Fprintln(os.Stderr, color.RedString("logError: %v", logError.Error()))
}
if postError != nil {
fmt.Fprintln(os.Stderr, color.RedString("postError: %v", postError.Error()))
}
os.Exit(1)
}
return nil
}
func postToGovernator(uri, dockerURL, etcdDir string, exitCode int) error {
exitCodeStr := fmt.Sprintf("%v", exitCode)
res, err := http.PostForm(uri, url.Values{
"dockerUrl": {dockerURL},
"exitCode": {exitCodeStr},
"etcdDir": {etcdDir},
})
if err != nil {
return err
}
if res.StatusCode != 201 {
message := fmt.Sprintf("Cancellation failed with code '%v'", res.StatusCode)
return errors.New(message)
}
return nil
}
func logJob(redisURI, redisQueue, dockerURL, workerName string, exitCode int) error {
redisConn, err := redis.DialURL(redisURI)
if err != nil {
return err
}
logEntry := logentry.New("metric:tattle", "tattle", dockerURL, workerName, exitCode, 0, false)
logEntryBytes, err := json.Marshal(logEntry)
if err != nil {
return err
}
_, err = redisConn.Do("LPUSH", redisQueue, logEntryBytes)
return err
}