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