Просмотр исходного кода

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 <madhu@docker.com>
Madhu Venugopal 8 лет назад
Родитель
Сommit
5e9c78aeaf
4 измененных файлов с 26 добавлено и 11 удалено
  1. 2 3
      daemon/network.go
  2. 15 4
      pkg/plugins/plugins.go
  3. 2 2
      plugin/store/defs.go
  4. 7 2
      plugin/store/store_experimental.go

+ 2 - 3
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()
 

+ 15 - 4
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

+ 2 - 2
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"),
 	}

+ 7 - 2
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())
 		}
 	}