package main import ( "git.ztn.sh/gwendolyn/docker-event-handler/events" "git.ztn.sh/gwendolyn/docker-event-handler/handlers" "context" "log" "os" "strconv" "time" "github.com/docker/docker/api/types" dockerEvents "github.com/docker/docker/api/types/events" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/client" "gopkg.in/ini.v1" ) type Configuration struct { handlers []handlers.Handler } func handleEvent(dockerClient *client.Client, event dockerEvents.Message, handlers []handlers.Handler) { e := events.Make(event, dockerClient) if e == nil { return } log.Printf("%T%+v", e, e) for _, handler := range handlers { if handler.Matches(e) { err := handler.Invoke(e) if err != nil { log.Printf("error invoking handler: %v", err) } } } } func readConfiguration(path string) (Configuration, error) { var config Configuration cfg, err := ini.LoadSources(ini.LoadOptions{ AllowNonUniqueSections: true, AllowShadows: true, }, path) if err != nil { return config, err } for _, section := range cfg.Sections() { if section.Name() == "DEFAULT" { continue } handler, err := handlers.ReadFromConfig(section) if err != nil { return config, err } config.handlers = append(config.handlers, handler) } return config, nil } func main() { configPath := "/etc/docker-event-handler.conf" if len(os.Args) > 1 { if len(os.Args) > 2 { log.Fatal("too many arguments") } configPath = os.Args[1] } config, err := readConfiguration(configPath) if err != nil { log.Fatal("configuration parsing failed", err) } dockerClient, err := client.NewClientWithOpts(client.WithAPIVersionNegotiation()) if err != nil { log.Fatal("docker connection failed", err) } evs, errs := dockerClient.Events(context.TODO(), types.EventsOptions{ Since: strconv.FormatInt(time.Now().Unix(), 10), Filters: filters.NewArgs( filters.Arg("type", dockerEvents.ContainerEventType), filters.Arg("type", dockerEvents.NetworkEventType), filters.Arg("type", dockerEvents.VolumeEventType), ), }) for { select { case err := <-errs: log.Fatal("event stream failed", err) case event := <-evs: handleEvent(dockerClient, event, config.handlers) } } }