Explorar o código

Fix some event filtering

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 <vincent@sbr.pm>
Vincent Demeester %!s(int64=8) %!d(string=hai) anos
pai
achega
71d8313ad4
Modificáronse 2 ficheiros con 50 adicións e 1 borrados
  1. 19 1
      daemon/events/filter.go
  2. 31 0
      integration-cli/docker_cli_events_test.go

+ 19 - 1
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

+ 31 - 0
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")