diff --git a/GLOCKFILE b/GLOCKFILE index f56ec658..caf5fde7 100644 --- a/GLOCKFILE +++ b/GLOCKFILE @@ -1,2 +1,2 @@ github.com/BurntSushi/toml 056c9bc7be7190eaa7715723883caffa5f8fa3e4 -github.com/fsouza/go-dockerclient e0d22d30691bcc996eca51f729a4777b8c7dc2a8 +github.com/fsouza/go-dockerclient 4bc6a18363f79b32c26f92e2e6d8bfd30d79a770 diff --git a/cmd/docker-gen/main.go b/cmd/docker-gen/main.go index 1bcbce5f..b033c688 100644 --- a/cmd/docker-gen/main.go +++ b/cmd/docker-gen/main.go @@ -23,6 +23,7 @@ var ( notifyCmd string notifyOutput bool notifySigHUPContainerID string + notifySigHUPServiceID string onlyExposed bool onlyPublished bool includeStopped bool @@ -97,6 +98,7 @@ func initFlags() { flag.StringVar(¬ifyCmd, "notify", "", "run command after template is regenerated (e.g `restart xyz`)") flag.StringVar(¬ifySigHUPContainerID, "notify-sighup", "", "send HUP signal to container. Equivalent to `docker kill -s HUP container-ID`") + flag.StringVar(¬ifySigHUPServiceID, "service-notify-sighup", "", "send HUP signal to all containers belong to a service.") flag.Var(&configFiles, "config", "config files with template directives. Config files will be merged if this option is specified multiple times.") flag.IntVar(&interval, "interval", 0, "notify command interval (secs)") flag.BoolVar(&keepBlankLines, "keep-blank-lines", false, "keep blank lines in the output file") @@ -143,6 +145,7 @@ func main() { NotifyCmd: notifyCmd, NotifyOutput: notifyOutput, NotifyContainers: make(map[string]docker.Signal), + NotifyServices: make(map[string]docker.Signal), OnlyExposed: onlyExposed, OnlyPublished: onlyPublished, IncludeStopped: includeStopped, @@ -152,6 +155,9 @@ func main() { if notifySigHUPContainerID != "" { config.NotifyContainers[notifySigHUPContainerID] = docker.SIGHUP } + if notifySigHUPServiceID != "" { + config.NotifyServices[notifySigHUPServiceID] = docker.SIGHUP + } configs = dockergen.ConfigFile{ Config: []dockergen.Config{config}} } diff --git a/config.go b/config.go index 773346c2..d49bf9c0 100644 --- a/config.go +++ b/config.go @@ -16,6 +16,7 @@ type Config struct { NotifyCmd string NotifyOutput bool NotifyContainers map[string]docker.Signal + NotifyServices map[string]docker.Signal OnlyExposed bool OnlyPublished bool IncludeStopped bool diff --git a/context.go b/context.go index da535fe2..f810f452 100644 --- a/context.go +++ b/context.go @@ -27,13 +27,13 @@ func (c *Context) Docker() Docker { return dockerInfo } -func SetServerInfo(d *docker.Env) { +func SetServerInfo(d *docker.DockerInfo) { mu.Lock() defer mu.Unlock() dockerInfo = Docker{ - Name: d.Get("Name"), - NumContainers: d.GetInt("Containers"), - NumImages: d.GetInt("Images"), + Name: d.Name, + NumContainers: d.Containers, + NumImages: d.Images, Version: dockerEnv.Get("Version"), ApiVersion: dockerEnv.Get("ApiVersion"), GoVersion: dockerEnv.Get("GoVersion"), diff --git a/generator.go b/generator.go index bf68be66..c3b8ac14 100644 --- a/generator.go +++ b/generator.go @@ -127,6 +127,7 @@ func (g *generator) generateFromContainers() { } g.runNotifyCmd(config) g.sendSignalToContainer(config) + g.sendSignalToService(config) } } @@ -156,6 +157,7 @@ func (g *generator) generateAtInterval() { GenerateFile(config, containers) g.runNotifyCmd(config) g.sendSignalToContainer(config) + g.sendSignalToService(config) case sig := <-sigChan: log.Printf("Received signal: %s\n", sig) switch sig { @@ -204,6 +206,7 @@ func (g *generator) generateFromEvents() { } g.runNotifyCmd(config) g.sendSignalToContainer(config) + g.sendSignalToService(config) } }(config, make(chan *docker.APIEvents, 100)) } @@ -341,6 +344,37 @@ func (g *generator) sendSignalToContainer(config Config) { } } +func (g *generator) sendSignalToService(config Config) { + if len(config.NotifyServices) < 1 { + return + } + + for service, signal := range config.NotifyServices { + log.Printf("Service '%s' needs notification", service) + taskOpts := docker.ListTasksOptions{ + Filters: map[string][]string{ + "service": []string{service}, + }, + } + tasks, err := g.Client.ListTasks(taskOpts) + if err != nil { + log.Printf("Error retrieving task list: %s", err) + } + for _, task := range tasks { + container := task.Status.ContainerStatus.ContainerID + + log.Printf("Sending container '%s' signal '%v'", container, signal) + killOpts := docker.KillContainerOptions{ + ID: container, + Signal: signal, + } + if err := g.Client.KillContainer(killOpts); err != nil { + log.Printf("Error sending signal to container: %s", err) + } + } + } +} + func (g *generator) getContainers() ([]*RuntimeContainer, error) { apiInfo, err := g.Client.Info() if err != nil {