From 5e9c78aeaf1d88000921190b88a1d91d6261208c Mon Sep 17 00:00:00 2001 From: Madhu Venugopal Date: Fri, 14 Oct 2016 22:40:28 -0700 Subject: [PATCH] Allow plugins to have multiple handlers Currently the plugins pkg allows a single handler. This assumption breaks down if there are mutiple listeners to a plugin of a certain Manifest such as NetworkDriver or IpamDriver when swarm-mode is enabled. Signed-off-by: Madhu Venugopal --- daemon/network.go | 5 ++--- pkg/plugins/plugins.go | 19 +++++++++++++++---- plugin/store/defs.go | 4 ++-- plugin/store/store_experimental.go | 9 +++++++-- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/daemon/network.go b/daemon/network.go index dce362d4fd..b75547cd5b 100644 --- a/daemon/network.go +++ b/daemon/network.go @@ -362,9 +362,8 @@ func (daemon *Daemon) GetNetworkDriverList() []string { return nil } - // TODO: Replace this with proper libnetwork API - pluginList := []string{"overlay"} - pluginMap := map[string]bool{"overlay": true} + pluginList := daemon.netController.BuiltinDrivers() + pluginMap := make(map[string]bool) networks := daemon.netController.Networks() diff --git a/pkg/plugins/plugins.go b/pkg/plugins/plugins.go index 9385b9b1bc..5acd3f2fbb 100644 --- a/pkg/plugins/plugins.go +++ b/pkg/plugins/plugins.go @@ -43,7 +43,7 @@ type plugins struct { var ( storage = plugins{plugins: make(map[string]*Plugin)} - extpointHandlers = make(map[string]func(string, *Client)) + extpointHandlers = make(map[string][]func(string, *Client)) ) // Manifest lists what a plugin implements. @@ -129,11 +129,13 @@ func (p *Plugin) activateWithLock() error { p.Manifest = m for _, iface := range m.Implements { - handler, handled := extpointHandlers[iface] + handlers, handled := extpointHandlers[iface] if !handled { continue } - handler(p.name, p.client) + for _, handler := range handlers { + handler(p.name, p.client) + } } return nil } @@ -226,7 +228,16 @@ func Get(name, imp string) (*Plugin, error) { // Handle adds the specified function to the extpointHandlers. func Handle(iface string, fn func(string, *Client)) { - extpointHandlers[iface] = fn + handlers, ok := extpointHandlers[iface] + if !ok { + handlers = []func(string, *Client){} + } + + handlers = append(handlers, fn) + extpointHandlers[iface] = handlers + for _, p := range storage.plugins { + p.activated = false + } } // GetAll returns all the plugins for the specified implementation diff --git a/plugin/store/defs.go b/plugin/store/defs.go index c6c76766a7..ea3b8e3ba8 100644 --- a/plugin/store/defs.go +++ b/plugin/store/defs.go @@ -15,7 +15,7 @@ type Store struct { /* handlers are necessary for transition path of legacy plugins * to the new model. Legacy plugins use Handle() for registering an * activation callback.*/ - handlers map[string]func(string, *plugins.Client) + handlers map[string][]func(string, *plugins.Client) nameToID map[string]string plugindb string } @@ -24,7 +24,7 @@ type Store struct { func NewStore(libRoot string) *Store { return &Store{ plugins: make(map[string]*v2.Plugin), - handlers: make(map[string]func(string, *plugins.Client)), + handlers: make(map[string][]func(string, *plugins.Client)), nameToID: make(map[string]string), plugindb: filepath.Join(libRoot, "plugins", "plugins.json"), } diff --git a/plugin/store/store_experimental.go b/plugin/store/store_experimental.go index 6eb99cc1ca..8c9ed1e302 100644 --- a/plugin/store/store_experimental.go +++ b/plugin/store/store_experimental.go @@ -212,7 +212,12 @@ func (ps *Store) Handle(capability string, callback func(string, *plugins.Client // Register callback with new plugin model. ps.Lock() - ps.handlers[pluginType] = callback + handlers, ok := ps.handlers[pluginType] + if !ok { + handlers = []func(string, *plugins.Client){} + } + handlers = append(handlers, callback) + ps.handlers[pluginType] = handlers ps.Unlock() // Register callback with legacy plugin model. @@ -224,7 +229,7 @@ func (ps *Store) Handle(capability string, callback func(string, *plugins.Client // CallHandler calls the registered callback. It is invoked during plugin enable. func (ps *Store) CallHandler(p *v2.Plugin) { for _, typ := range p.GetTypes() { - if handler := ps.handlers[typ.String()]; handler != nil { + for _, handler := range ps.handlers[typ.String()] { handler(p.Name(), p.Client()) } }