@@ -3,9 +3,12 @@ package dockergen
33import (
44 "fmt"
55 "log"
6+ "os"
67 "os/exec"
8+ "os/signal"
79 "strings"
810 "sync"
11+ "syscall"
912 "time"
1013
1114 "github.com/fsouza/go-dockerclient"
@@ -63,16 +66,39 @@ func NewGenerator(gc GeneratorConfig) (*generator, error) {
6366}
6467
6568func (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 ()
6973 g .wg .Wait ()
7074
7175 return nil
7276}
7377
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 ()
76102 if err != nil {
77103 log .Printf ("error listing containers: %s\n " , err )
78104 return
@@ -84,12 +110,12 @@ func (g *generator) generateFromContainers(client *docker.Client) {
84110 continue
85111 }
86112 g .runNotifyCmd (config )
87- g .sendSignalToContainer (client , config )
113+ g .sendSignalToContainer (config )
88114 }
89115}
90116
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 {
93119
94120 if config .Interval == 0 {
95121 continue
@@ -99,39 +125,39 @@ func (g *generator) generateAtInterval(client *docker.Client, configs ConfigFile
99125 g .wg .Add (1 )
100126 ticker := time .NewTicker (time .Duration (config .Interval ) * time .Second )
101127 quit := make (chan struct {})
102- configCopy := config
103- go func () {
128+ go func (config Config ) {
104129 defer g .wg .Done ()
105130 for {
106131 select {
107132 case <- ticker .C :
108- containers , err := g .getContainers (client )
133+ containers , err := g .getContainers ()
109134 if err != nil {
110135 log .Printf ("Error listing containers: %s\n " , err )
111136 continue
112137 }
113138 // 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 )
117142 case <- quit :
118143 ticker .Stop ()
119144 return
120145 }
121146 }
122- }()
147+ }(config )
123148 }
124149}
125150
126- func (g * generator ) generateFromEvents (client * docker. Client , configs ConfigFile ) {
127- configs = configs .FilterWatches ()
151+ func (g * generator ) generateFromEvents () {
152+ configs := g . Configs .FilterWatches ()
128153 if len (configs .Config ) == 0 {
129154 return
130155 }
131156
132157 g .wg .Add (1 )
133158 defer g .wg .Done ()
134159
160+ client := g .Client
135161 for {
136162 if client == nil {
137163 var err error
@@ -148,7 +174,7 @@ func (g *generator) generateFromEvents(client *docker.Client, configs ConfigFile
148174 time .Sleep (10 * time .Second )
149175 continue
150176 }
151- g .generateFromContainers (client )
177+ g .generateFromContainers ()
152178 }
153179
154180 eventChan := make (chan * docker.APIEvents , 100 )
@@ -198,7 +224,7 @@ func (g *generator) generateFromEvents(client *docker.Client, configs ConfigFile
198224
199225 if event .Status == "start" || event .Status == "stop" || event .Status == "die" {
200226 log .Printf ("Received event %s for container %s" , event .Status , event .ID [:12 ])
201- g .generateFromContainers (client )
227+ g .generateFromContainers ()
202228 }
203229 case <- time .After (10 * time .Second ):
204230 // check for docker liveness
@@ -228,7 +254,7 @@ func (g *generator) runNotifyCmd(config Config) {
228254 }
229255}
230256
231- func (g * generator ) sendSignalToContainer (client * docker. Client , config Config ) {
257+ func (g * generator ) sendSignalToContainer (config Config ) {
232258 if len (config .NotifyContainers ) < 1 {
233259 return
234260 }
@@ -239,21 +265,21 @@ func (g *generator) sendSignalToContainer(client *docker.Client, config Config)
239265 ID : container ,
240266 Signal : signal ,
241267 }
242- if err := client .KillContainer (killOpts ); err != nil {
268+ if err := g . Client .KillContainer (killOpts ); err != nil {
243269 log .Printf ("Error sending signal to container: %s" , err )
244270 }
245271 }
246272}
247273
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 ()
250276 if err != nil {
251277 log .Printf ("error retrieving docker server info: %s\n " , err )
252278 }
253279
254280 SetServerInfo (apiInfo )
255281
256- apiContainers , err := client .ListContainers (docker.ListContainersOptions {
282+ apiContainers , err := g . Client .ListContainers (docker.ListContainersOptions {
257283 All : false ,
258284 Size : false ,
259285 })
@@ -263,7 +289,7 @@ func (g *generator) getContainers(client *docker.Client) ([]*RuntimeContainer, e
263289
264290 containers := []* RuntimeContainer {}
265291 for _ , apiContainer := range apiContainers {
266- container , err := client .InspectContainer (apiContainer .ID )
292+ container , err := g . Client .InspectContainer (apiContainer .ID )
267293 if err != nil {
268294 log .Printf ("error inspecting container: %s: %s\n " , apiContainer .ID , err )
269295 continue
0 commit comments