events.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package plugin // import "github.com/docker/docker/plugin"
  2. import (
  3. "fmt"
  4. "reflect"
  5. "github.com/docker/docker/api/types"
  6. )
  7. // Event is emitted for actions performed on the plugin manager
  8. type Event interface {
  9. matches(Event) bool
  10. }
  11. // EventCreate is an event which is emitted when a plugin is created
  12. // This is either by pull or create from context.
  13. //
  14. // Use the `Interfaces` field to match only plugins that implement a specific
  15. // interface.
  16. // These are matched against using "or" logic.
  17. // If no interfaces are listed, all are matched.
  18. type EventCreate struct {
  19. Interfaces map[string]bool
  20. Plugin types.Plugin
  21. }
  22. func (e EventCreate) matches(observed Event) bool {
  23. oe, ok := observed.(EventCreate)
  24. if !ok {
  25. return false
  26. }
  27. if len(e.Interfaces) == 0 {
  28. return true
  29. }
  30. var ifaceMatch bool
  31. for _, in := range oe.Plugin.Config.Interface.Types {
  32. if e.Interfaces[in.Capability] {
  33. ifaceMatch = true
  34. break
  35. }
  36. }
  37. return ifaceMatch
  38. }
  39. // EventRemove is an event which is emitted when a plugin is removed
  40. // It maches on the passed in plugin's ID only.
  41. type EventRemove struct {
  42. Plugin types.Plugin
  43. }
  44. func (e EventRemove) matches(observed Event) bool {
  45. oe, ok := observed.(EventRemove)
  46. if !ok {
  47. return false
  48. }
  49. return e.Plugin.ID == oe.Plugin.ID
  50. }
  51. // EventDisable is an event that is emitted when a plugin is disabled
  52. // It maches on the passed in plugin's ID only.
  53. type EventDisable struct {
  54. Plugin types.Plugin
  55. }
  56. func (e EventDisable) matches(observed Event) bool {
  57. oe, ok := observed.(EventDisable)
  58. if !ok {
  59. return false
  60. }
  61. return e.Plugin.ID == oe.Plugin.ID
  62. }
  63. // EventEnable is an event that is emitted when a plugin is disabled
  64. // It maches on the passed in plugin's ID only.
  65. type EventEnable struct {
  66. Plugin types.Plugin
  67. }
  68. func (e EventEnable) matches(observed Event) bool {
  69. oe, ok := observed.(EventEnable)
  70. if !ok {
  71. return false
  72. }
  73. return e.Plugin.ID == oe.Plugin.ID
  74. }
  75. // SubscribeEvents provides an event channel to listen for structured events from
  76. // the plugin manager actions, CRUD operations.
  77. // The caller must call the returned `cancel()` function once done with the channel
  78. // or this will leak resources.
  79. func (pm *Manager) SubscribeEvents(buffer int, watchEvents ...Event) (eventCh <-chan interface{}, cancel func()) {
  80. topic := func(i interface{}) bool {
  81. observed, ok := i.(Event)
  82. if !ok {
  83. panic(fmt.Sprintf("unexpected type passed to event channel: %v", reflect.TypeOf(i)))
  84. }
  85. for _, e := range watchEvents {
  86. if e.matches(observed) {
  87. return true
  88. }
  89. }
  90. // If no specific events are specified always assume a matched event
  91. // If some events were specified and none matched above, then the event
  92. // doesn't match
  93. return watchEvents == nil
  94. }
  95. ch := pm.publisher.SubscribeTopicWithBuffer(topic, buffer)
  96. cancelFunc := func() { pm.publisher.Evict(ch) }
  97. return ch, cancelFunc
  98. }