package handlers import ( "git.ztn.sh/gwendolyn/docker-event-handler/events" "errors" "fmt" "strings" "text/template" "gopkg.in/ini.v1" ) type Volume struct { Action []string Name []string Driver []string Destination []string ID []string Label map[string]*string ContainerName []string ContainerImage []string ContainerID []string ContainerHostname []string ContainerLabel map[string]*string Run *template.Template } func (h Volume) Matches(event events.Event) bool { e, ok := event.(events.Volume) if !ok { return false } if !stringListMatches(h.Action, e.Action) { return false } if !stringListMatches(h.ID, e.ID) { return false } if e.Volume == nil { if len(h.Name) > 0 || len(h.Driver) > 0 || len(h.Label) > 0 { return false } } else { if !stringListMatches(h.Name, e.Volume.Name) { return false } if !stringListMatches(h.Driver, e.Volume.Driver) { return false } if !labelsMatch(h.Label, e.Volume.Labels) { return false } } if e.Destination == nil { if len(h.Destination) > 0 { return false } } else { if !stringListMatches(h.Destination, *e.Destination) { return false } } if e.Container == nil { if len(h.ContainerID) > 0 || len(h.ContainerName) > 0 || len(h.ContainerImage) > 0 || len(h.ContainerHostname) > 0 || len(h.ContainerLabel) > 0 { return false } } else { if !stringListMatches(h.ContainerID, e.Container.ID) { return false } if !stringListMatches(h.ContainerName, e.Container.Name) { return false } if !stringListMatches(h.ContainerImage, e.Container.Image) { return false } if !stringListMatches(h.ContainerHostname, e.Container.Config.Hostname) { return false } if !labelsMatch(h.ContainerLabel, e.Container.Config.Labels) { return false } } return true } func (h Volume) Invoke(event events.Event) error { e := event.(events.Volume) // enforce that the event is a volume event return runTemplatedScript(h.Run, e) } func readVolumeFromConfig(section *ini.Section) (Volume, error) { var handler Volume var err error handler.Label = make(map[string]*string) handler.ContainerLabel = make(map[string]*string) for _, key := range section.Keys() { values := key.ValueWithShadows() switch key.Name() { case "Action": handler.Action = values break case "Name": handler.Name = values break case "ID": handler.ID = values break case "Driver": handler.Driver = values break case "Destination": handler.Destination = values break case "Label": for _, val := range values { parts := strings.SplitN(val, "=", 2) var k string var v *string if len(parts) == 2 { k = parts[0] v = &parts[1] } else { k = parts[0] v = nil } handler.Label[k] = v } break case "ContainerName": handler.ContainerName = values break case "ContainerID": handler.ContainerID = values break case "ContainerImage": handler.ContainerImage = values break case "ContainerHostname": handler.ContainerHostname = values break case "ContainerLabel": for _, val := range values { parts := strings.SplitN(val, "=", 2) var k string var v *string if len(parts) == 2 { k = parts[0] v = &parts[1] } else { k = parts[0] v = nil } handler.ContainerLabel[k] = v } break case "Run": if len(values) > 1 { return handler, errors.New(fmt.Sprintf("duplicate key %v in section %v", key.Name(), section.Name())) } handler.Run, err = template.New("Run").Parse(values[0]) if err != nil { return handler, err } break default: return handler, errors.New(fmt.Sprintf("unknown key %v in section %v", key.Name(), section.Name())) } } return handler, nil }