@@ -3,9 +3,12 @@ package dockergen
3
3
import (
4
4
"fmt"
5
5
"log"
6
+ "os"
6
7
"os/exec"
8
+ "os/signal"
7
9
"strings"
8
10
"sync"
11
+ "syscall"
9
12
"time"
10
13
11
14
"github.com/fsouza/go-dockerclient"
@@ -63,16 +66,39 @@ func NewGenerator(gc GeneratorConfig) (*generator, error) {
63
66
}
64
67
65
68
func (g * generator ) Generate () error {
66
- g .generateFromContainers (g .Client )
67
- g .generateAtInterval (g .Client , g .Configs )
68
- g .generateFromEvents (g .Client , g .Configs )
69
+ g .generateFromContainers ()
70
+ g .generateAtInterval ()
71
+ g .generateFromEvents ()
72
+ g .generateFromSignals ()
69
73
g .wg .Wait ()
70
74
71
75
return nil
72
76
}
73
77
74
- func (g * generator ) generateFromContainers (client * docker.Client ) {
75
- containers , err := g .getContainers (client )
78
+ func (g * generator ) generateFromSignals () {
79
+ sigs := make (chan os.Signal , 1 )
80
+ signal .Notify (sigs , syscall .SIGHUP , syscall .SIGINT , syscall .SIGTERM , syscall .SIGQUIT , syscall .SIGKILL )
81
+
82
+ g .wg .Add (1 )
83
+ go func () {
84
+ defer g .wg .Done ()
85
+
86
+ for {
87
+ sig := <- sigs
88
+ log .Printf ("Received signal: %s\n " , sig )
89
+ switch sig {
90
+ case syscall .SIGHUP :
91
+ g .generateFromContainers ()
92
+ case syscall .SIGQUIT , syscall .SIGKILL , syscall .SIGTERM , syscall .SIGINT :
93
+ // exit when context is done
94
+ return
95
+ }
96
+ }
97
+ }()
98
+ }
99
+
100
+ func (g * generator ) generateFromContainers () {
101
+ containers , err := g .getContainers ()
76
102
if err != nil {
77
103
log .Printf ("error listing containers: %s\n " , err )
78
104
return
@@ -84,12 +110,12 @@ func (g *generator) generateFromContainers(client *docker.Client) {
84
110
continue
85
111
}
86
112
g .runNotifyCmd (config )
87
- g .sendSignalToContainer (client , config )
113
+ g .sendSignalToContainer (config )
88
114
}
89
115
}
90
116
91
- func (g * generator ) generateAtInterval (client * docker. Client , configs ConfigFile ) {
92
- for _ , config := range configs .Config {
117
+ func (g * generator ) generateAtInterval () {
118
+ for _ , config := range g . Configs .Config {
93
119
94
120
if config .Interval == 0 {
95
121
continue
@@ -99,39 +125,39 @@ func (g *generator) generateAtInterval(client *docker.Client, configs ConfigFile
99
125
g .wg .Add (1 )
100
126
ticker := time .NewTicker (time .Duration (config .Interval ) * time .Second )
101
127
quit := make (chan struct {})
102
- configCopy := config
103
- go func () {
128
+ go func (config Config ) {
104
129
defer g .wg .Done ()
105
130
for {
106
131
select {
107
132
case <- ticker .C :
108
- containers , err := g .getContainers (client )
133
+ containers , err := g .getContainers ()
109
134
if err != nil {
110
135
log .Printf ("Error listing containers: %s\n " , err )
111
136
continue
112
137
}
113
138
// ignore changed return value. always run notify command
114
- GenerateFile (configCopy , containers )
115
- g .runNotifyCmd (configCopy )
116
- g .sendSignalToContainer (client , configCopy )
139
+ GenerateFile (config , containers )
140
+ g .runNotifyCmd (config )
141
+ g .sendSignalToContainer (config )
117
142
case <- quit :
118
143
ticker .Stop ()
119
144
return
120
145
}
121
146
}
122
- }()
147
+ }(config )
123
148
}
124
149
}
125
150
126
- func (g * generator ) generateFromEvents (client * docker. Client , configs ConfigFile ) {
127
- configs = configs .FilterWatches ()
151
+ func (g * generator ) generateFromEvents () {
152
+ configs := g . Configs .FilterWatches ()
128
153
if len (configs .Config ) == 0 {
129
154
return
130
155
}
131
156
132
157
g .wg .Add (1 )
133
158
defer g .wg .Done ()
134
159
160
+ client := g .Client
135
161
for {
136
162
if client == nil {
137
163
var err error
@@ -148,7 +174,7 @@ func (g *generator) generateFromEvents(client *docker.Client, configs ConfigFile
148
174
time .Sleep (10 * time .Second )
149
175
continue
150
176
}
151
- g .generateFromContainers (client )
177
+ g .generateFromContainers ()
152
178
}
153
179
154
180
eventChan := make (chan * docker.APIEvents , 100 )
@@ -198,7 +224,7 @@ func (g *generator) generateFromEvents(client *docker.Client, configs ConfigFile
198
224
199
225
if event .Status == "start" || event .Status == "stop" || event .Status == "die" {
200
226
log .Printf ("Received event %s for container %s" , event .Status , event .ID [:12 ])
201
- g .generateFromContainers (client )
227
+ g .generateFromContainers ()
202
228
}
203
229
case <- time .After (10 * time .Second ):
204
230
// check for docker liveness
@@ -228,7 +254,7 @@ func (g *generator) runNotifyCmd(config Config) {
228
254
}
229
255
}
230
256
231
- func (g * generator ) sendSignalToContainer (client * docker. Client , config Config ) {
257
+ func (g * generator ) sendSignalToContainer (config Config ) {
232
258
if len (config .NotifyContainers ) < 1 {
233
259
return
234
260
}
@@ -239,21 +265,21 @@ func (g *generator) sendSignalToContainer(client *docker.Client, config Config)
239
265
ID : container ,
240
266
Signal : signal ,
241
267
}
242
- if err := client .KillContainer (killOpts ); err != nil {
268
+ if err := g . Client .KillContainer (killOpts ); err != nil {
243
269
log .Printf ("Error sending signal to container: %s" , err )
244
270
}
245
271
}
246
272
}
247
273
248
- func (g * generator ) getContainers (client * docker. Client ) ([]* RuntimeContainer , error ) {
249
- apiInfo , err := client .Info ()
274
+ func (g * generator ) getContainers () ([]* RuntimeContainer , error ) {
275
+ apiInfo , err := g . Client .Info ()
250
276
if err != nil {
251
277
log .Printf ("error retrieving docker server info: %s\n " , err )
252
278
}
253
279
254
280
SetServerInfo (apiInfo )
255
281
256
- apiContainers , err := client .ListContainers (docker.ListContainersOptions {
282
+ apiContainers , err := g . Client .ListContainers (docker.ListContainersOptions {
257
283
All : false ,
258
284
Size : false ,
259
285
})
@@ -263,7 +289,7 @@ func (g *generator) getContainers(client *docker.Client) ([]*RuntimeContainer, e
263
289
264
290
containers := []* RuntimeContainer {}
265
291
for _ , apiContainer := range apiContainers {
266
- container , err := client .InspectContainer (apiContainer .ID )
292
+ container , err := g . Client .InspectContainer (apiContainer .ID )
267
293
if err != nil {
268
294
log .Printf ("error inspecting container: %s: %s\n " , apiContainer .ID , err )
269
295
continue
0 commit comments