105 lines
2.2 KiB
Go
105 lines
2.2 KiB
Go
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)
|
|
}
|
|
}
|
|
|
|
}
|