filter.go 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. package events
  2. import (
  3. "github.com/docker/docker/reference"
  4. "github.com/docker/engine-api/types/events"
  5. "github.com/docker/engine-api/types/filters"
  6. )
  7. // Filter can filter out docker events from a stream
  8. type Filter struct {
  9. filter filters.Args
  10. }
  11. // NewFilter creates a new Filter
  12. func NewFilter(filter filters.Args) *Filter {
  13. return &Filter{filter: filter}
  14. }
  15. // Include returns true when the event ev is included by the filters
  16. func (ef *Filter) Include(ev events.Message) bool {
  17. return ef.filter.ExactMatch("event", ev.Action) &&
  18. ef.filter.ExactMatch("type", ev.Type) &&
  19. ef.matchDaemon(ev) &&
  20. ef.matchContainer(ev) &&
  21. ef.matchPlugin(ev) &&
  22. ef.matchVolume(ev) &&
  23. ef.matchNetwork(ev) &&
  24. ef.matchImage(ev) &&
  25. ef.matchLabels(ev.Actor.Attributes)
  26. }
  27. func (ef *Filter) matchLabels(attributes map[string]string) bool {
  28. if !ef.filter.Include("label") {
  29. return true
  30. }
  31. return ef.filter.MatchKVList("label", attributes)
  32. }
  33. func (ef *Filter) matchDaemon(ev events.Message) bool {
  34. return ef.fuzzyMatchName(ev, events.DaemonEventType)
  35. }
  36. func (ef *Filter) matchContainer(ev events.Message) bool {
  37. return ef.fuzzyMatchName(ev, events.ContainerEventType)
  38. }
  39. func (ef *Filter) matchPlugin(ev events.Message) bool {
  40. return ef.fuzzyMatchName(ev, events.PluginEventType)
  41. }
  42. func (ef *Filter) matchVolume(ev events.Message) bool {
  43. return ef.fuzzyMatchName(ev, events.VolumeEventType)
  44. }
  45. func (ef *Filter) matchNetwork(ev events.Message) bool {
  46. return ef.fuzzyMatchName(ev, events.NetworkEventType)
  47. }
  48. func (ef *Filter) fuzzyMatchName(ev events.Message, eventType string) bool {
  49. return ef.filter.FuzzyMatch(eventType, ev.Actor.ID) ||
  50. ef.filter.FuzzyMatch(eventType, ev.Actor.Attributes["name"])
  51. }
  52. // matchImage matches against both event.Actor.ID (for image events)
  53. // and event.Actor.Attributes["image"] (for container events), so that any container that was created
  54. // from an image will be included in the image events. Also compare both
  55. // against the stripped repo name without any tags.
  56. func (ef *Filter) matchImage(ev events.Message) bool {
  57. id := ev.Actor.ID
  58. nameAttr := "image"
  59. var imageName string
  60. if ev.Type == events.ImageEventType {
  61. nameAttr = "name"
  62. }
  63. if n, ok := ev.Actor.Attributes[nameAttr]; ok {
  64. imageName = n
  65. }
  66. return ef.filter.ExactMatch("image", id) ||
  67. ef.filter.ExactMatch("image", imageName) ||
  68. ef.filter.ExactMatch("image", stripTag(id)) ||
  69. ef.filter.ExactMatch("image", stripTag(imageName))
  70. }
  71. func stripTag(image string) string {
  72. ref, err := reference.ParseNamed(image)
  73. if err != nil {
  74. return image
  75. }
  76. return ref.Name()
  77. }