summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbaude <bbaude@redhat.com>2020-10-21 11:59:35 -0500
committerbaude <bbaude@redhat.com>2020-10-23 12:07:34 -0500
commitc593e49701b3a4bb48050f3d8829f2fe6ac457ef (patch)
treef69648182082c37d4416efdb5405a9431984463c
parent51fa8ded9ffb7924288a2728ce92af7f6cc66d34 (diff)
downloadpodman-c593e49701b3a4bb48050f3d8829f2fe6ac457ef.tar.gz
podman-c593e49701b3a4bb48050f3d8829f2fe6ac457ef.tar.bz2
podman-c593e49701b3a4bb48050f3d8829f2fe6ac457ef.zip
filter events by labels
adding the ability to filter evens by the container labels. this requires that container labels be added to the events data being recorded and subsequently read. Signed-off-by: baude <bbaude@redhat.com>
-rw-r--r--docs/source/markdown/podman-events.1.md1
-rw-r--r--libpod/events.go6
-rw-r--r--libpod/events/config.go12
-rw-r--r--libpod/events/events.go9
-rw-r--r--libpod/events/filters.go20
-rw-r--r--libpod/events/journal_linux.go23
-rw-r--r--test/system/090-events.bats14
7 files changed, 83 insertions, 2 deletions
diff --git a/docs/source/markdown/podman-events.1.md b/docs/source/markdown/podman-events.1.md
index 0d91cdf17..d0bc3cef8 100644
--- a/docs/source/markdown/podman-events.1.md
+++ b/docs/source/markdown/podman-events.1.md
@@ -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)
diff --git a/libpod/events.go b/libpod/events.go
index b519fe324..95317eb01 100644
--- a/libpod/events.go
+++ b/libpod/events.go
@@ -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)
}
diff --git a/libpod/events/config.go b/libpod/events/config.go
index bb35c03c0..2ec3111fe 100644
--- a/libpod/events/config.go
+++ b/libpod/events/config.go
@@ -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
diff --git a/libpod/events/events.go b/libpod/events/events.go
index 722c9595e..42939d64c 100644
--- a/libpod/events/events.go
+++ b/libpod/events/events.go
@@ -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:
diff --git a/libpod/events/filters.go b/libpod/events/filters.go
index 171e2237f..62891d32c 100644
--- a/libpod/events/filters.go
+++ b/libpod/events/filters.go
@@ -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
diff --git a/libpod/events/journal_linux.go b/libpod/events/journal_linux.go
index dc55dbc77..5d17a85b4 100644
--- a/libpod/events/journal_linux.go
+++ b/libpod/events/journal_linux.go
@@ -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"]
}
diff --git a/test/system/090-events.bats b/test/system/090-events.bats
new file mode 100644
index 000000000..06e28ec3a
--- /dev/null
+++ b/test/system/090-events.bats
@@ -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"
+}