@@ -13,9 +13,10 @@ import (
13
13
"os"
14
14
"os/exec"
15
15
"os/signal"
16
-
17
16
"strings"
17
+ "sync"
18
18
"syscall"
19
+ "time"
19
20
)
20
21
21
22
var (
24
25
onlyExposed bool
25
26
configFile string
26
27
configs ConfigFile
28
+ interval int
29
+ wg sync.WaitGroup
27
30
)
28
31
29
32
type Event struct {
@@ -49,6 +52,7 @@ type Config struct {
49
52
Watch bool
50
53
NotifyCmd string
51
54
OnlyExposed bool
55
+ Interval int
52
56
}
53
57
54
58
type ConfigFile struct {
@@ -73,7 +77,7 @@ func (r *RuntimeContainer) Equals(o RuntimeContainer) bool {
73
77
}
74
78
75
79
func usage () {
76
- println ("Usage: docker-gen [-config file] [-watch=false] [-notify=\" restart xyz\" ] <template> [<dest>]" )
80
+ println ("Usage: docker-gen [-config file] [-watch=false] [-notify=\" restart xyz\" ] [-interval=0] <template> [<dest>]" )
77
81
}
78
82
79
83
func newConn () (* httputil.ClientConn , error ) {
@@ -141,13 +145,12 @@ func getEvents() chan *Event {
141
145
return eventChan
142
146
}
143
147
144
- func generateFromContainers (client * docker.Client ) {
148
+ func getContainers (client * docker.Client ) ([] * RuntimeContainer , error ) {
145
149
apiContainers , err := client .ListContainers (docker.ListContainersOptions {
146
150
All : false ,
147
151
})
148
152
if err != nil {
149
- fmt .Printf ("error listing containers: %s\n " , err )
150
- return
153
+ return nil , err
151
154
}
152
155
153
156
containers := []* RuntimeContainer {}
@@ -179,15 +182,21 @@ func generateFromContainers(client *docker.Client) {
179
182
180
183
containers = append (containers , runtimeContainer )
181
184
}
185
+ return containers , nil
182
186
187
+ }
188
+ func generateFromContainers (client * docker.Client ) {
189
+ containers , err := getContainers (client )
190
+ if err != nil {
191
+ fmt .Printf ("error listing containers: %s\n " , err )
192
+ return
193
+ }
183
194
for _ , config := range configs .Config {
184
195
changed := generateFile (config , containers )
185
196
if changed {
186
197
runNotifyCmd (config )
187
198
}
188
-
189
199
}
190
-
191
200
}
192
201
193
202
func runNotifyCmd (config Config ) {
@@ -212,11 +221,62 @@ func loadConfig(file string) error {
212
221
return nil
213
222
}
214
223
224
+ func generateAtInterval (client * docker.Client , configs ConfigFile ) {
225
+ for _ , config := range configs .Config {
226
+
227
+ if config .Interval == 0 {
228
+ continue
229
+ }
230
+
231
+ wg .Add (1 )
232
+ ticker := time .NewTicker (time .Duration (config .Interval ) * time .Second )
233
+ quit := make (chan struct {})
234
+ go func () {
235
+ for {
236
+ select {
237
+ case <- ticker .C :
238
+ containers , err := getContainers (client )
239
+ if err != nil {
240
+ fmt .Printf ("error listing containers: %s\n " , err )
241
+ continue
242
+ }
243
+ // ignore changed return value. always run notify command
244
+ generateFile (config , containers )
245
+ runNotifyCmd (config )
246
+ case <- quit :
247
+ ticker .Stop ()
248
+ return
249
+ }
250
+ }
251
+ wg .Done ()
252
+ }()
253
+ }
254
+ }
255
+
256
+ func generateFromEvents (client * docker.Client , configs ConfigFile ) {
257
+ configs = configs .filterWatches ()
258
+ if len (configs .Config ) == 0 {
259
+ return
260
+ }
261
+
262
+ wg .Add (1 )
263
+ eventChan := getEvents ()
264
+ for {
265
+ event := <- eventChan
266
+ if event .Status == "start" || event .Status == "stop" || event .Status == "die" {
267
+ generateFromContainers (client )
268
+ }
269
+ }
270
+ wg .Done ()
271
+
272
+ }
273
+
215
274
func main () {
216
275
flag .BoolVar (& watch , "watch" , false , "watch for container changes" )
217
276
flag .BoolVar (& onlyExposed , "only-exposed" , false , "only include containers with exposed ports" )
218
277
flag .StringVar (& notifyCmd , "notify" , "" , "run command after template is regenerated" )
219
278
flag .StringVar (& configFile , "config" , "" , "config file with template directives" )
279
+ flag .IntVar (& interval , "interval" , 0 , "notify command interval (s)" )
220
280
flag .Parse ()
221
281
222
282
if flag .NArg () < 1 && configFile == "" {
@@ -237,6 +297,7 @@ func main() {
237
297
Watch : watch ,
238
298
NotifyCmd : notifyCmd ,
239
299
OnlyExposed : onlyExposed ,
300
+ Interval : interval ,
240
301
}
241
302
configs = ConfigFile {
242
303
Config : []Config {config }}
@@ -250,19 +311,7 @@ func main() {
250
311
}
251
312
252
313
generateFromContainers (client )
253
-
254
- configs = configs .filterWatches ()
255
-
256
- if len (configs .Config ) == 0 {
257
- return
258
- }
259
-
260
- eventChan := getEvents ()
261
- for {
262
- event := <- eventChan
263
- if event .Status == "start" || event .Status == "stop" || event .Status == "die" {
264
- generateFromContainers (client )
265
- }
266
- }
267
-
314
+ generateAtInterval (client , configs )
315
+ generateFromEvents (client , configs )
316
+ wg .Wait ()
268
317
}
0 commit comments