Skip to content

Commit 62014aa

Browse files
committed
Add filter for events emitted by docker daemon
This fix tries to cover the issue raised in moby#22463 by adding filter for events emitted by docker daemon so that user could utilize filter to receive events of interest. Documentations have been updated for this fix. Additional tests have been added to cover the changes in this fix. This fix fixes moby#22463. Signed-off-by: Yong Tang <[email protected]>
1 parent 382c152 commit 62014aa

7 files changed

Lines changed: 74 additions & 6 deletions

File tree

daemon/daemon.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1393,6 +1393,8 @@ func (daemon *Daemon) Reload(config *Config) error {
13931393
} else {
13941394
attributes["labels"] = "[]"
13951395
}
1396+
attributes["max-concurrent-downloads"] = fmt.Sprintf("%d", *daemon.configStore.MaxConcurrentDownloads)
1397+
attributes["max-concurrent-uploads"] = fmt.Sprintf("%d", *daemon.configStore.MaxConcurrentUploads)
13961398
daemon.LogDaemonEventWithAttributes("reload", attributes)
13971399

13981400
return nil

daemon/events.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ func (daemon *Daemon) LogNetworkEventWithAttributes(nw libnetwork.Network, actio
8383
// LogDaemonEventWithAttributes generates an event related to the daemon itself with specific given attributes.
8484
func (daemon *Daemon) LogDaemonEventWithAttributes(action string, attributes map[string]string) {
8585
if daemon.EventsService != nil {
86+
if info, err := daemon.SystemInfo(); err == nil && info.Name != "" {
87+
attributes["name"] = info.Name
88+
}
8689
actor := events.Actor{
8790
ID: daemon.ID,
8891
Attributes: attributes,

daemon/events/filter.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ func NewFilter(filter filters.Args) *Filter {
2020
func (ef *Filter) Include(ev events.Message) bool {
2121
return ef.filter.ExactMatch("event", ev.Action) &&
2222
ef.filter.ExactMatch("type", ev.Type) &&
23+
ef.matchDaemon(ev) &&
2324
ef.matchContainer(ev) &&
2425
ef.matchVolume(ev) &&
2526
ef.matchNetwork(ev) &&
@@ -34,6 +35,10 @@ func (ef *Filter) matchLabels(attributes map[string]string) bool {
3435
return ef.filter.MatchKVList("label", attributes)
3536
}
3637

38+
func (ef *Filter) matchDaemon(ev events.Message) bool {
39+
return ef.fuzzyMatchName(ev, events.DaemonEventType)
40+
}
41+
3742
func (ef *Filter) matchContainer(ev events.Message) bool {
3843
return ef.fuzzyMatchName(ev, events.ContainerEventType)
3944
}

docs/reference/api/docker_remote_api.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,8 @@ This section lists each version from latest to oldest. Each listing includes a
119119
* `POST /containers/create` now returns a HTTP 400 "bad parameter" message
120120
if no command is specified (instead of a HTTP 500 "server error")
121121
* `GET /images/search` now takes a `filters` query parameter.
122-
* `GET /events` now supports daemon events of `reload`.
122+
* `GET /events` now supports a `reload` event that is emitted when the daemon configuration is reloaded.
123+
* `GET /events` now supports filtering by daemon name or ID.
123124

124125
### v1.23 API changes
125126

docs/reference/api/docker_remote_api_v1.24.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2593,9 +2593,10 @@ Query Parameters:
25932593
- `event=<string>`; -- event to filter
25942594
- `image=<string>`; -- image to filter
25952595
- `label=<string>`; -- image and container label to filter
2596-
- `type=<string>`; -- either `container` or `image` or `volume` or `network`
2596+
- `type=<string>`; -- either `container` or `image` or `volume` or `network` or `daemon`
25972597
- `volume=<string>`; -- volume to filter
25982598
- `network=<string>`; -- network to filter
2599+
- `daemon=<string>`; -- daemon name or id to filter
25992600
26002601
Status Codes:
26012602

docs/reference/commandline/events.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,10 @@ The currently supported filters are:
7272
* event (`event=<event action>`)
7373
* image (`image=<tag or id>`)
7474
* label (`label=<key>` or `label=<key>=<value>`)
75-
* type (`type=<container or image or volume or network>`)
75+
* type (`type=<container or image or volume or network or daemon>`)
7676
* volume (`volume=<name or id>`)
7777
* network (`network=<name or id>`)
78+
* daemon (`daemon=<name or id>`)
7879

7980
## Examples
8081

integration-cli/docker_cli_events_unix_test.go

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -386,17 +386,19 @@ func (s *DockerDaemonSuite) TestDaemonEvents(c *check.C) {
386386
out, err := s.d.Cmd("info")
387387
c.Assert(err, checker.IsNil)
388388
daemonID := ""
389+
daemonName := ""
389390
for _, line := range strings.Split(out, "\n") {
390391
if strings.HasPrefix(line, "ID: ") {
391392
daemonID = strings.TrimPrefix(line, "ID: ")
392-
break
393+
} else if strings.HasPrefix(line, "Name: ") {
394+
daemonName = strings.TrimPrefix(line, "Name: ")
393395
}
394396
}
395397
c.Assert(daemonID, checker.Not(checker.Equals), "")
396398

397399
configFile, err = os.Create(configFilePath)
398400
c.Assert(err, checker.IsNil)
399-
daemonConfig = `{"labels":["bar=foo"]}`
401+
daemonConfig = `{"max-concurrent-downloads":1,"labels":["bar=foo"]}`
400402
fmt.Fprintf(configFile, "%s", daemonConfig)
401403
configFile.Close()
402404

@@ -406,5 +408,58 @@ func (s *DockerDaemonSuite) TestDaemonEvents(c *check.C) {
406408

407409
out, err = s.d.Cmd("events", "--since=0", "--until", daemonUnixTime(c))
408410
c.Assert(err, checker.IsNil)
409-
c.Assert(out, checker.Contains, fmt.Sprintf("daemon reload %s (cluster-advertise=, cluster-store=, cluster-store-opts={}, debug=true, labels=[\"bar=foo\"])", daemonID))
411+
c.Assert(out, checker.Contains, fmt.Sprintf("daemon reload %s (cluster-advertise=, cluster-store=, cluster-store-opts={}, debug=true, labels=[\"bar=foo\"], max-concurrent-downloads=1, max-concurrent-uploads=5, name=%s)", daemonID, daemonName))
412+
}
413+
414+
func (s *DockerDaemonSuite) TestDaemonEventsWithFilters(c *check.C) {
415+
testRequires(c, SameHostDaemon, DaemonIsLinux)
416+
417+
// daemon config file
418+
configFilePath := "test.json"
419+
configFile, err := os.Create(configFilePath)
420+
c.Assert(err, checker.IsNil)
421+
defer os.Remove(configFilePath)
422+
423+
daemonConfig := `{"labels":["foo=bar"]}`
424+
fmt.Fprintf(configFile, "%s", daemonConfig)
425+
configFile.Close()
426+
c.Assert(s.d.Start(fmt.Sprintf("--config-file=%s", configFilePath)), check.IsNil)
427+
428+
// Get daemon ID
429+
out, err := s.d.Cmd("info")
430+
c.Assert(err, checker.IsNil)
431+
daemonID := ""
432+
daemonName := ""
433+
for _, line := range strings.Split(out, "\n") {
434+
if strings.HasPrefix(line, "ID: ") {
435+
daemonID = strings.TrimPrefix(line, "ID: ")
436+
} else if strings.HasPrefix(line, "Name: ") {
437+
daemonName = strings.TrimPrefix(line, "Name: ")
438+
}
439+
}
440+
c.Assert(daemonID, checker.Not(checker.Equals), "")
441+
442+
syscall.Kill(s.d.cmd.Process.Pid, syscall.SIGHUP)
443+
444+
time.Sleep(3 * time.Second)
445+
446+
out, err = s.d.Cmd("events", "--since=0", "--until", daemonUnixTime(c), "--filter", fmt.Sprintf("daemon=%s", daemonID))
447+
c.Assert(err, checker.IsNil)
448+
c.Assert(out, checker.Contains, fmt.Sprintf("daemon reload %s", daemonID))
449+
450+
out, err = s.d.Cmd("events", "--since=0", "--until", daemonUnixTime(c), "--filter", fmt.Sprintf("daemon=%s", daemonName))
451+
c.Assert(err, checker.IsNil)
452+
c.Assert(out, checker.Contains, fmt.Sprintf("daemon reload %s", daemonID))
453+
454+
out, err = s.d.Cmd("events", "--since=0", "--until", daemonUnixTime(c), "--filter", "daemon=foo")
455+
c.Assert(err, checker.IsNil)
456+
c.Assert(out, checker.Not(checker.Contains), fmt.Sprintf("daemon reload %s", daemonID))
457+
458+
out, err = s.d.Cmd("events", "--since=0", "--until", daemonUnixTime(c), "--filter", "type=daemon")
459+
c.Assert(err, checker.IsNil)
460+
c.Assert(out, checker.Contains, fmt.Sprintf("daemon reload %s", daemonID))
461+
462+
out, err = s.d.Cmd("events", "--since=0", "--until", daemonUnixTime(c), "--filter", "type=container")
463+
c.Assert(err, checker.IsNil)
464+
c.Assert(out, checker.Not(checker.Contains), fmt.Sprintf("daemon reload %s", daemonID))
410465
}

0 commit comments

Comments
 (0)