From 71d8313ad415b8ec6efff3e88f48b5465f30c9a9 Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Thu, 27 Oct 2016 16:14:13 -0700 Subject: [PATCH] Fix some event filtering MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make it possible to use health_status, exec_start and exec_create as is in event filter. This way, using `health_status` as filter will allow to get all health_status events (healthy, unhealthy, …) instead of having to us all combination (`health_status: healthy`, `health_status: unhealthy`, …). Same goes for `exec_start` and `exec_create`. Signed-off-by: Vincent Demeester --- daemon/events/filter.go | 20 ++++++++++++++- integration-cli/docker_cli_events_test.go | 31 +++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/daemon/events/filter.go b/daemon/events/filter.go index 78da87de30..5c9c527692 100644 --- a/daemon/events/filter.go +++ b/daemon/events/filter.go @@ -18,7 +18,7 @@ func NewFilter(filter filters.Args) *Filter { // Include returns true when the event ev is included by the filters func (ef *Filter) Include(ev events.Message) bool { - return ef.filter.ExactMatch("event", ev.Action) && + return ef.matchEvent(ev) && ef.filter.ExactMatch("type", ev.Type) && ef.matchDaemon(ev) && ef.matchContainer(ev) && @@ -29,6 +29,24 @@ func (ef *Filter) Include(ev events.Message) bool { ef.matchLabels(ev.Actor.Attributes) } +func (ef *Filter) matchEvent(ev events.Message) bool { + // #25798 if an event filter contains either health_status, exec_create or exec_start without a colon + // Let's to a FuzzyMatch instead of an ExactMatch. + if ef.filterContains("event", map[string]struct{}{"health_status": {}, "exec_create": {}, "exec_start": {}}) { + return ef.filter.FuzzyMatch("event", ev.Action) + } + return ef.filter.ExactMatch("event", ev.Action) +} + +func (ef *Filter) filterContains(field string, values map[string]struct{}) bool { + for _, v := range ef.filter.Get(field) { + if _, ok := values[v]; ok { + return true + } + } + return false +} + func (ef *Filter) matchLabels(attributes map[string]string) bool { if !ef.filter.Include("label") { return true diff --git a/integration-cli/docker_cli_events_test.go b/integration-cli/docker_cli_events_test.go index 69175eb1f8..bfb33dcce6 100644 --- a/integration-cli/docker_cli_events_test.go +++ b/integration-cli/docker_cli_events_test.go @@ -641,6 +641,37 @@ func (s *DockerSuite) TestEventsFilterType(c *check.C) { c.Assert(len(events), checker.GreaterOrEqualThan, 1, check.Commentf("Events == %s", events)) } +// #25798 +func (s *DockerSuite) TestEventsSpecialFiltersWithExecCreate(c *check.C) { + since := daemonUnixTime(c) + runSleepingContainer(c, "--name", "test-container", "-d") + waitRun("test-container") + + dockerCmd(c, "exec", "test-container", "echo", "hello-world") + + out, _ := dockerCmd( + c, + "events", + "--since", since, + "--until", daemonUnixTime(c), + "--filter", + "event='exec_create: echo hello-world'", + ) + + events := strings.Split(strings.TrimSpace(out), "\n") + c.Assert(len(events), checker.Equals, 1, check.Commentf(out)) + + out, _ = dockerCmd( + c, + "events", + "--since", since, + "--until", daemonUnixTime(c), + "--filter", + "event=exec_create", + ) + c.Assert(len(events), checker.Equals, 1, check.Commentf(out)) +} + func (s *DockerSuite) TestEventsFilterImageInContainerAction(c *check.C) { since := daemonUnixTime(c) dockerCmd(c, "run", "--name", "test-container", "-d", "busybox", "true")