Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions cmd/nerdctl/system/system_events_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,18 @@ func testEventFilterExecutor(data test.Data, helpers test.Helpers) test.Testable
return cmd
}

func testEventLabelFilterExecutor(data test.Data, helpers test.Helpers) test.TestableCommand {
helpers.Ensure("pull", testutil.CommonImage)

cmd := helpers.Command("events", "--filter", data.Labels().Get("filter"), "--format", "json")
cmd.WithTimeout(10 * time.Second)
cmd.Background()

helpers.Ensure("run", "--rm", "--label", data.Labels().Get("containerLabel"), testutil.CommonImage)

return cmd
}

func TestEventFilters(t *testing.T) {
testCase := nerdtest.Setup()

Expand Down Expand Up @@ -115,6 +127,36 @@ func TestEventFilters(t *testing.T) {
"output": "\"Status\":\"unknown\"",
}),
},
{
Description: "LabelFilter",
Command: testEventLabelFilterExecutor,
Expected: func(data test.Data, helpers test.Helpers) *test.Expected {
return &test.Expected{
ExitCode: expect.ExitCodeTimeout,
Output: expect.Contains(data.Labels().Get("output")),
}
},
Data: test.WithLabels(map[string]string{
"filter": "label=com.example.app=myapp",
"containerLabel": "com.example.app=myapp",
"output": "\"Status\":\"start\"",
}),
},
{
Description: "LabelKeyOnlyFilter",
Command: testEventLabelFilterExecutor,
Expected: func(data test.Data, helpers test.Helpers) *test.Expected {
return &test.Expected{
ExitCode: expect.ExitCodeTimeout,
Output: expect.Contains(data.Labels().Get("output")),
}
},
Data: test.WithLabels(map[string]string{
"filter": "label=com.example.app",
"containerLabel": "com.example.app=myapp",
"output": "\"Status\":\"start\"",
}),
},
}

testCase.Run(t)
Expand Down
26 changes: 24 additions & 2 deletions pkg/cmd/system/events.go

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ type EventOut struct {
Topic string
Status Status
Event string
Labels map[string]string
}

type Status string
Expand Down Expand Up @@ -90,6 +91,20 @@ func generateEventFilter(filter, filterValue string) (func(e *EventOut) bool, er

return strings.EqualFold(string(e.Status), filterValue)
}, nil
case "LABEL":
return func(e *EventOut) bool {
if len(e.Labels) == 0 {
return false
}

parts := strings.SplitN(filterValue, "=", 2)
if len(parts) == 1 {
_, ok := e.Labels[parts[0]]
return ok
}

return e.Labels[parts[0]] == parts[1]
}, nil
}

return nil, fmt.Errorf("%s is an invalid or unsupported filter", filter)
Expand Down Expand Up @@ -175,6 +190,7 @@ func Events(ctx context.Context, client *containerd.Client, options types.System
if e != nil {
var out []byte
var id string
labels := map[string]string{}
if e.Event != nil {
v, err := typeurl.UnmarshalAny(e.Event)
if err != nil {
Expand All @@ -197,8 +213,14 @@ func Events(ctx context.Context, client *containerd.Client, options types.System
id = data["container_id"].(string)
}
}

eOut := EventOut{e.Timestamp, id, e.Namespace, e.Topic, TopicToStatus(e.Topic), string(out)}
if id != "" {
if container, err := client.ContainerService().Get(ctx, id); err != nil {
log.G(ctx).WithError(err).WithField("containerID", id).Debug("failed to retrieve container labels")
} else {
labels = container.Labels
}
}
eOut := EventOut{e.Timestamp, id, e.Namespace, e.Topic, TopicToStatus(e.Topic), string(out), labels}
match := applyFilters(&eOut, filterMap)
if match {
if tmpl != nil {
Expand Down
Loading