Adding pluginv2 support for libnetwork (part 1)

Legacy plugins (aka pluginv1) calls in libnetwork are replaced with
calls using the new plugin model (aka pluginv2). pkg/plugins is still
used for managing the http client connections to the plugin.

This commit makes the necessary changes in docker/docker. Part 2 will
will take care of the libnetwork changes.

Signed-off-by: Anusha Ragunathan <anusha@docker.com>
This commit is contained in:
Anusha Ragunathan 2016-09-06 14:30:55 -07:00
parent bdae52a23d
commit 17b8aba1d9
4 changed files with 35 additions and 29 deletions

View file

@ -623,11 +623,12 @@ func NewDaemon(config *Config, registryService registry.Service, containerdRemot
return nil, err
}
if err := d.restore(); err != nil {
// Plugin system initialization should happen before restore. Dont change order.
if err := pluginInit(d, config, containerdRemote); err != nil {
return nil, err
}
if err := pluginInit(d, config, containerdRemote); err != nil {
if err := d.restore(); err != nil {
return nil, err
}

View file

@ -4,16 +4,13 @@ package plugin
import (
"encoding/json"
"fmt"
"io"
"os"
"path/filepath"
"strings"
"sync"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/libcontainerd"
"github.com/docker/docker/pkg/plugins"
"github.com/docker/docker/plugin/store"
"github.com/docker/docker/plugin/v2"
"github.com/docker/docker/registry"
@ -21,12 +18,6 @@ import (
var (
manager *Manager
/* allowV1PluginsFallback determines daemon's support for V1 plugins.
* When the time comes to remove support for V1 plugins, flipping
* this bool is all that will be needed.
*/
allowV1PluginsFallback = true
)
func (pm *Manager) restorePlugin(p *v2.Plugin) error {
@ -45,7 +36,6 @@ type Manager struct {
libRoot string
runRoot string
pluginStore *store.PluginStore
handlers map[string]func(string, *plugins.Client)
containerdClient libcontainerd.Client
registryService registry.Service
liveRestore bool
@ -70,7 +60,6 @@ func Init(root string, remote libcontainerd.Remote, rs registry.Service, liveRes
libRoot: root,
runRoot: "/run/docker",
pluginStore: store.NewPluginStore(root),
handlers: make(map[string]func(string, *plugins.Client)),
registryService: rs,
liveRestore: liveRestore,
pluginEventLogger: evL,
@ -88,16 +77,6 @@ func Init(root string, remote libcontainerd.Remote, rs registry.Service, liveRes
return nil
}
// Handle sets a callback for a given capability. The callback will be called for every plugin with a given capability.
// TODO: append instead of set?
func Handle(capability string, callback func(string, *plugins.Client)) {
pluginType := fmt.Sprintf("docker.%s/1", strings.ToLower(capability))
manager.handlers[pluginType] = callback
if allowV1PluginsFallback {
plugins.Handle(capability, callback)
}
}
// StateChanged updates plugin internals using libcontainerd events.
func (pm *Manager) StateChanged(id string, e libcontainerd.StateInfo) error {
logrus.Debugf("plugin state changed %s %#v", id, e)

View file

@ -43,11 +43,7 @@ func (pm *Manager) enable(p *v2.Plugin, force bool) error {
}
pm.pluginStore.SetState(p, true)
for _, typ := range p.GetTypes() {
if handler := pm.handlers[typ.String()]; handler != nil {
handler(p.Name(), p.Client())
}
}
pm.pluginStore.CallHandler(p)
return nil
}

View file

@ -6,6 +6,7 @@ import (
"encoding/json"
"fmt"
"path/filepath"
"strings"
"sync"
"github.com/Sirupsen/logrus"
@ -32,7 +33,11 @@ func (name ErrNotFound) Error() string { return fmt.Sprintf("plugin %q not found
// PluginStore manages the plugin inventory in memory and on-disk
type PluginStore struct {
sync.RWMutex
plugins map[string]*v2.Plugin
plugins map[string]*v2.Plugin
/* 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)
nameToID map[string]string
plugindb string
}
@ -41,6 +46,7 @@ type PluginStore struct {
func NewPluginStore(libRoot string) *PluginStore {
store = &PluginStore{
plugins: make(map[string]*v2.Plugin),
handlers: make(map[string]func(string, *plugins.Client)),
nameToID: make(map[string]string),
plugindb: filepath.Join(libRoot, "plugins.json"),
}
@ -222,3 +228,27 @@ func FindWithCapability(capability string) ([]CompatPlugin, error) {
}
return result, nil
}
// Handle sets a callback for a given capability. It is only used by network
// and ipam drivers during plugin registration. The callback registers the
// driver with the subsystem (network, ipam).
func Handle(capability string, callback func(string, *plugins.Client)) {
pluginType := fmt.Sprintf("docker.%s/1", strings.ToLower(capability))
// Register callback with new plugin model.
store.handlers[pluginType] = callback
// Register callback with legacy plugin model.
if allowV1PluginsFallback {
plugins.Handle(capability, callback)
}
}
// CallHandler calls the registered callback. It is invoked during plugin enable.
func (ps *PluginStore) CallHandler(p *v2.Plugin) {
for _, typ := range p.GetTypes() {
if handler := ps.handlers[typ.String()]; handler != nil {
handler(p.Name(), p.Client())
}
}
}