Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: filter containers to notify #619

Merged
merged 5 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,14 @@ Options:
log the output(stdout/stderr) of notify command
-notify-container container-ID
container to send a signal to
-notify-filter key=value
container filter for notification (e.g -notify-filter name=foo).
You can have multiple of these.
https://docs.docker.com/engine/reference/commandline/ps/#filter
-notify-signal signal
signal to send to the -notify-container. -1 to call docker restart. Defaults to 1 aka. HUP.
All available signals available on the [dockerclient](https://github.com/fsouza/go-dockerclient/blob/01804dec8a84d0a77e63611f2b62d33e9bb2b64a/signal.go)
signal to send to the -notify-container and -notify-filter. -1 to call docker restart. Defaults to 1 aka. HUP.
All available signals available on the dockerclient
https://github.com/fsouza/go-dockerclient/blob/01804dec8a84d0a77e63611f2b62d33e9bb2b64a/signal.go
-notify-sighup container-ID
send HUP signal to container. Equivalent to 'docker kill -s HUP container-ID', or `-notify-container container-ID -notify-signal 1`
-only-exposed
Expand Down
23 changes: 22 additions & 1 deletion cmd/docker-gen/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"os"
"os/signal"
"path/filepath"
"strings"
"syscall"

"github.com/BurntSushi/toml"
Expand All @@ -16,6 +17,7 @@ import (
)

type stringslice []string
type mapstringslice map[string][]string

var (
buildVersion string
Expand All @@ -26,6 +28,7 @@ var (
notifyOutput bool
notifyContainerID string
notifyContainerSignal int
notifyContainerFilter mapstringslice = make(mapstringslice)
onlyExposed bool
onlyPublished bool
includeStopped bool
Expand All @@ -50,6 +53,18 @@ func (strings *stringslice) Set(value string) error {
return nil
}

func (filter *mapstringslice) String() string {
return "[string][]string"
}

func (filter *mapstringslice) Set(value string) error {
name, value, found := strings.Cut(value, "=")
if found {
(*filter)[name] = append((*filter)[name], value)
}
return nil
}

func usage() {
println(`Usage: docker-gen [options] template [dest]

Expand Down Expand Up @@ -100,8 +115,10 @@ func initFlags() {
"send HUP signal to container. Equivalent to docker kill -s HUP `container-ID`")
flag.StringVar(&notifyContainerID, "notify-container", "",
"container to send a signal to")
flag.Var(&notifyContainerFilter, "notify-filter",
"container filter for notification (e.g -notify-filter name=foo). You can have multiple of these. https://docs.docker.com/engine/reference/commandline/ps/#filter")
flag.IntVar(&notifyContainerSignal, "notify-signal", int(docker.SIGHUP),
"signal to send to the notify-container. Defaults to SIGHUP")
"signal to send to the notify-container and notify-filter. Defaults to SIGHUP")
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")
Expand Down Expand Up @@ -161,6 +178,10 @@ func main() {
if notifyContainerID != "" {
cfg.NotifyContainers[notifyContainerID] = notifyContainerSignal
}
if len(notifyContainerFilter) > 0 {
cfg.NotifyContainersFilter = notifyContainerFilter
cfg.NotifyContainersSignal = notifyContainerSignal
}
configs = config.ConfigFile{
Config: []config.Config{cfg}}
}
Expand Down
26 changes: 14 additions & 12 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,20 @@ import (
)

type Config struct {
Template string
Dest string
Watch bool
Wait *Wait
NotifyCmd string
NotifyOutput bool
NotifyContainers map[string]int
OnlyExposed bool
OnlyPublished bool
IncludeStopped bool
Interval int
KeepBlankLines bool
Template string
Dest string
Watch bool
Wait *Wait
NotifyCmd string
NotifyOutput bool
NotifyContainers map[string]int
NotifyContainersFilter map[string][]string
NotifyContainersSignal int
OnlyExposed bool
OnlyPublished bool
IncludeStopped bool
Interval int
KeepBlankLines bool
}

type ConfigFile struct {
Expand Down
61 changes: 43 additions & 18 deletions internal/generator/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@ func (g *generator) generateFromContainers() {
continue
}
g.runNotifyCmd(config)
g.sendSignalToContainer(config)
g.sendSignalToContainers(config)
g.sendSignalToFilteredContainers(config)
}
}

Expand Down Expand Up @@ -162,7 +163,8 @@ func (g *generator) generateAtInterval() {
// ignore changed return value. always run notify command
template.GenerateFile(cfg, containers)
g.runNotifyCmd(cfg)
g.sendSignalToContainer(cfg)
g.sendSignalToContainers(cfg)
g.sendSignalToFilteredContainers(cfg)
case sig := <-sigChan:
log.Printf("Received signal: %s\n", sig)
switch sig {
Expand Down Expand Up @@ -210,7 +212,8 @@ func (g *generator) generateFromEvents() {
continue
}
g.runNotifyCmd(cfg)
g.sendSignalToContainer(cfg)
g.sendSignalToContainers(cfg)
g.sendSignalToFilteredContainers(cfg)
}
}(cfg)
}
Expand Down Expand Up @@ -332,28 +335,50 @@ func (g *generator) runNotifyCmd(config config.Config) {
}
}

func (g *generator) sendSignalToContainer(config config.Config) {
func (g *generator) sendSignalToContainer(container string, signal int) {
log.Printf("Sending container '%s' signal '%v'", container, signal)

if signal == -1 {
if err := g.Client.RestartContainer(container, 10); err != nil {
log.Printf("Error sending restarting container: %s", err)
}
return
}

killOpts := docker.KillContainerOptions{
ID: container,
Signal: docker.Signal(signal),
}
if err := g.Client.KillContainer(killOpts); err != nil {
log.Printf("Error sending signal to container: %s", err)
}
}

func (g *generator) sendSignalToContainers(config config.Config) {
if len(config.NotifyContainers) < 1 {
return
}

for container, signal := range config.NotifyContainers {
log.Printf("Sending container '%s' signal '%v'", container, signal)
g.sendSignalToContainer(container, signal)
}
}

if signal == -1 {
if err := g.Client.RestartContainer(container, 10); err != nil {
log.Printf("Error sending restarting container: %s", err)
}
return
}
func (g *generator) sendSignalToFilteredContainers(config config.Config) {
if len(config.NotifyContainersFilter) < 1 {
return
}

killOpts := docker.KillContainerOptions{
ID: container,
Signal: docker.Signal(signal),
}
if err := g.Client.KillContainer(killOpts); err != nil {
log.Printf("Error sending signal to container: %s", err)
}
containers, err := g.Client.ListContainers(docker.ListContainersOptions{
Filters: config.NotifyContainersFilter,
})
if err != nil {
log.Printf("Error getting containers: %s", err)
return
}

for _, container := range containers {
g.sendSignalToContainer(container.ID, config.NotifyContainersSignal)
}
}

Expand Down