diff --git a/pkg/plugins/plugins.go b/pkg/plugins/plugins.go index 87a8eba4be65a..f369053856b66 100644 --- a/pkg/plugins/plugins.go +++ b/pkg/plugins/plugins.go @@ -63,6 +63,9 @@ type Plugin struct { Client *Client `json:"-"` // Manifest of the plugin (see above) Manifest *Manifest `json:"-"` + + activatErr error + activateOnce sync.Once } func newLocalPlugin(name, addr string) *Plugin { @@ -74,6 +77,13 @@ func newLocalPlugin(name, addr string) *Plugin { } func (p *Plugin) activate() error { + p.activateOnce.Do(func() { + p.activatErr = p.activateWithLock() + }) + return p.activatErr +} + +func (p *Plugin) activateWithLock() error { c, err := NewClient(p.Addr, p.TLSConfig) if err != nil { return err @@ -99,32 +109,37 @@ func (p *Plugin) activate() error { } func load(name string) (*Plugin, error) { + storage.Lock() registry := newLocalRegistry() pl, err := registry.Plugin(name) + if err == nil { + storage.plugins[name] = pl + } + storage.Unlock() + if err != nil { return nil, err } - if err := pl.activate(); err != nil { - return nil, err + + err = pl.activate() + + if err != nil { + storage.Lock() + delete(storage.plugins, name) + storage.Unlock() } - return pl, nil + + return pl, err } func get(name string) (*Plugin, error) { storage.Lock() - defer storage.Unlock() pl, ok := storage.plugins[name] + storage.Unlock() if ok { - return pl, nil + return pl, pl.activate() } - pl, err := load(name) - if err != nil { - return nil, err - } - - logrus.Debugf("Plugin: %v", pl) - storage.plugins[name] = pl - return pl, nil + return load(name) } // Get returns the plugin given the specified name and requested implementation. diff --git a/volume/drivers/extpoint.go b/volume/drivers/extpoint.go index 09bb7d433eb71..e9d13b680003d 100644 --- a/volume/drivers/extpoint.go +++ b/volume/drivers/extpoint.go @@ -51,8 +51,8 @@ func Unregister(name string) bool { // there is a VolumeDriver plugin available with the given name. func Lookup(name string) (volume.Driver, error) { drivers.Lock() - defer drivers.Unlock() ext, ok := drivers.extensions[name] + drivers.Unlock() if ok { return ext, nil } @@ -61,6 +61,12 @@ func Lookup(name string) (volume.Driver, error) { return nil, fmt.Errorf("Error looking up volume plugin %s: %v", name, err) } + drivers.Lock() + defer drivers.Unlock() + if ext, ok := drivers.extensions[name]; ok { + return ext, nil + } + d := NewVolumeDriver(name, pl.Client) drivers.extensions[name] = d return d, nil