Merge pull request #8103 from baude/eventlabels

filter events by labels
This commit is contained in:
OpenShift Merge Robot 2020-10-23 16:21:53 -04:00 committed by GitHub
commit 050dcadf69
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 83 additions and 2 deletions

View File

@ -86,6 +86,7 @@ filters are supported:
* container=name_or_id
* event=event_status (described above)
* image=name_or_id
* label=key=value
* pod=name_or_id
* volume=name_or_id
* type=event_type (described above)

View File

@ -26,6 +26,12 @@ func (c *Container) newContainerEvent(status events.Status) {
e.Name = c.Name()
e.Image = c.config.RootfsImageName
e.Type = events.Container
e.Details = events.Details{
ID: e.ID,
Attributes: c.Labels(),
}
if err := c.runtime.eventer.Write(e); err != nil {
logrus.Errorf("unable to write pod event: %q", err)
}

View File

@ -36,6 +36,18 @@ type Event struct {
Time time.Time
// Type of event that occurred
Type Type
Details
}
// Details describes specifics about certain events, specifically around
// container events
type Details struct {
// ID is the event ID
ID string
// Attributes can be used to describe specifics about the event
// in the case of a container event, labels for example
Attributes map[string]string
}
// EventerOptions describe options that need to be passed to create

View File

@ -69,7 +69,14 @@ func (e *Event) ToHumanReadable() string {
var humanFormat string
switch e.Type {
case Container, Pod:
humanFormat = fmt.Sprintf("%s %s %s %s (image=%s, name=%s)", e.Time, e.Type, e.Status, e.ID, e.Image, e.Name)
humanFormat = fmt.Sprintf("%s %s %s %s (image=%s, name=%s", e.Time, e.Type, e.Status, e.ID, e.Image, e.Name)
// check if the container has labels and add it to the output
if len(e.Attributes) > 0 {
for k, v := range e.Attributes {
humanFormat += fmt.Sprintf(", %s=%s", k, v)
}
}
humanFormat += ")"
case Image:
humanFormat = fmt.Sprintf("%s %s %s %s %s", e.Time, e.Type, e.Status, e.ID, e.Name)
case System:

View File

@ -55,6 +55,24 @@ func generateEventFilter(filter, filterValue string) (func(e *Event) bool, error
return func(e *Event) bool {
return string(e.Type) == filterValue
}, nil
case "LABEL":
return func(e *Event) bool {
var found bool
// iterate labels and see if we match a key and value
for eventKey, eventValue := range e.Attributes {
filterValueSplit := strings.SplitN(filterValue, "=", 2)
// if the filter isn't right, just return false
if len(filterValueSplit) < 2 {
return false
}
if eventKey == filterValueSplit[0] && eventValue == filterValueSplit[1] {
found = true
break
}
}
return found
}, nil
}
return nil, errors.Errorf("%s is an invalid filter", filter)
}
@ -74,7 +92,7 @@ func generateEventUntilOption(timeUntil time.Time) func(e *Event) bool {
func parseFilter(filter string) (string, string, error) {
filterSplit := strings.SplitN(filter, "=", 2)
if len(filterSplit) == 1 {
if len(filterSplit) != 2 {
return "", "", errors.Errorf("%s is an invalid filter", filter)
}
return filterSplit[0], filterSplit[1], nil

View File

@ -4,6 +4,7 @@ package events
import (
"context"
"encoding/json"
"strconv"
"time"
@ -46,6 +47,15 @@ func (e EventJournalD) Write(ee Event) error {
if ee.ContainerExitCode != 0 {
m["PODMAN_EXIT_CODE"] = strconv.Itoa(ee.ContainerExitCode)
}
// If we have container labels, we need to convert them to a string so they
// can be recorded with the event
if len(ee.Details.Attributes) > 0 {
b, err := json.Marshal(ee.Details.Attributes)
if err != nil {
return err
}
m["PODMAN_LABELS"] = string(b)
}
case Volume:
m["PODMAN_NAME"] = ee.Name
}
@ -174,6 +184,19 @@ func newEventFromJournalEntry(entry *sdjournal.JournalEntry) (*Event, error) { /
newEvent.ContainerExitCode = intCode
}
}
// we need to check for the presence of labels recorded to a container event
if stringLabels, ok := entry.Fields["PODMAN_LABELS"]; ok && len(stringLabels) > 0 {
labels := make(map[string]string, 0)
if err := json.Unmarshal([]byte(stringLabels), &labels); err != nil {
return nil, err
}
// if we have labels, add them to the event
if len(labels) > 0 {
newEvent.Details = Details{Attributes: labels}
}
}
case Image:
newEvent.ID = entry.Fields["PODMAN_ID"]
}

View File

@ -0,0 +1,14 @@
#!/usr/bin/env bats -*- bats -*-
#
# tests for podman events functionality
#
load helpers
@test "events with a filter by label" {
skip_if_remote "Need to talk to Ed on why this is failing on remote"
rand=$(random_string 30)
run_podman 0 run --label foo=bar --name test-$rand --rm $IMAGE ls
run_podman 0 events --filter type=container --filter container=test-$rand --filter label=foo=bar --filter event=start --stream=false
is "$output" ".*foo=bar" "check for label event on container with label"
}