@@ -10,25 +10,41 @@ import (
10
10
"net/http"
11
11
"net/http/httputil"
12
12
"os"
13
+ "os/exec"
13
14
"os/signal"
14
15
"path/filepath"
16
+ "strings"
15
17
"syscall"
16
18
"text/template"
17
19
)
18
20
19
- var watch bool
21
+ var (
22
+ watch bool
23
+ notifyCmd string
24
+ )
20
25
21
26
type Event struct {
22
27
ContainerId string `json:"id"`
23
28
Status string `json:"status"`
24
29
Image string `json:"from"`
25
30
}
26
31
32
+ type Address struct {
33
+ IP string
34
+ Port string
35
+ }
36
+ type RuntimeContainer struct {
37
+ ID string
38
+ Addresses []Address
39
+ Image string
40
+ }
41
+
27
42
func usage () {
28
- println ("Usage: docker-gen [-watch] <template> [<dest>]" )
43
+ println ("Usage: docker-gen [-watch=false] [-notify= \" restart xyz \" ] <template> [<dest>]" )
29
44
}
30
45
31
- func generateFile (templatePath string , containers []docker.APIContainers ) {
46
+ func generateFile (templatePath string , containers []* RuntimeContainer ) {
47
+
32
48
tmpl , err := template .ParseFiles (templatePath )
33
49
if err != nil {
34
50
panic (err )
@@ -44,6 +60,9 @@ func generateFile(templatePath string, containers []docker.APIContainers) {
44
60
}
45
61
46
62
err = tmpl .ExecuteTemplate (dest , filepath .Base (templatePath ), containers )
63
+ if err != nil {
64
+ fmt .Printf ("template error: %s\n " , err )
65
+ }
47
66
}
48
67
49
68
func newConn () (* httputil.ClientConn , error ) {
@@ -110,20 +129,59 @@ func getEvents() chan *Event {
110
129
}
111
130
112
131
func generateFromContainers (client * docker.Client ) {
113
- containers , err := client .ListContainers (docker.ListContainersOptions {
132
+ apiContainers , err := client .ListContainers (docker.ListContainersOptions {
114
133
All : false ,
115
134
})
116
135
if err != nil {
117
136
fmt .Printf ("error listing containers: %s" , err )
118
137
return
119
138
}
120
139
140
+ containers := []* RuntimeContainer {}
141
+ for _ , apiContainer := range apiContainers {
142
+ container , err := client .InspectContainer (apiContainer .ID )
143
+ if err != nil {
144
+ fmt .Printf ("error inspecting container: %s: %s" , apiContainer .ID , err )
145
+ continue
146
+ }
147
+
148
+ runtimeContainer := & RuntimeContainer {
149
+ ID : container .ID ,
150
+ Image : container .Config .Image ,
151
+ Addresses : []Address {},
152
+ }
153
+ for k , _ := range container .NetworkSettings .Ports {
154
+ runtimeContainer .Addresses = append (runtimeContainer .Addresses ,
155
+ Address {
156
+ IP : container .NetworkSettings .IPAddress ,
157
+ Port : k .Port (),
158
+ })
159
+ }
160
+ containers = append (containers , runtimeContainer )
161
+ }
162
+
121
163
generateFile (flag .Arg (0 ), containers )
122
164
}
123
165
166
+ func runNotifyCmd () {
167
+ if notifyCmd == "" {
168
+ return
169
+ }
170
+
171
+ args := strings .Split (notifyCmd , " " )
172
+ cmd := exec .Command (args [0 ], args [1 :]... )
173
+ output , err := cmd .CombinedOutput ()
174
+ if err != nil {
175
+ fmt .Printf ("error running notify command: %s\n " , err )
176
+ }
177
+ print (string (output ))
178
+
179
+ }
180
+
124
181
func main () {
125
182
126
183
flag .BoolVar (& watch , "watch" , false , "watch for container changes" )
184
+ flag .StringVar (& notifyCmd , "notify" , "" , "run command after template is regenerated" )
127
185
flag .Parse ()
128
186
129
187
if flag .NArg () < 1 {
@@ -139,6 +197,7 @@ func main() {
139
197
}
140
198
141
199
generateFromContainers (client )
200
+ runNotifyCmd ()
142
201
if ! watch {
143
202
return
144
203
}
@@ -148,6 +207,7 @@ func main() {
148
207
event := <- eventChan
149
208
if event .Status == "start" || event .Status == "stop" {
150
209
generateFromContainers (client )
210
+ runNotifyCmd ()
151
211
}
152
212
}
153
213
0 commit comments