diff --git a/libnetwork/cmd/ovrouter/ovrouter.go b/libnetwork/cmd/ovrouter/ovrouter.go index 8e286d0729..538e28aaf4 100644 --- a/libnetwork/cmd/ovrouter/ovrouter.go +++ b/libnetwork/cmd/ovrouter/ovrouter.go @@ -7,6 +7,7 @@ import ( "os/signal" "github.com/docker/docker/pkg/reexec" + "github.com/docker/docker/plugin/getter" "github.com/docker/libnetwork/driverapi" "github.com/docker/libnetwork/drivers/overlay" "github.com/docker/libnetwork/netlabel" @@ -24,6 +25,10 @@ type endpoint struct { name string } +func (r *router) GetPluginGetter() getter.PluginGetter { + return nil +} + func (r *router) RegisterDriver(name string, driver driverapi.Driver, c driverapi.Capability) error { r.d = driver return nil diff --git a/libnetwork/config/config.go b/libnetwork/config/config.go index 832412ec74..0e4780e489 100644 --- a/libnetwork/config/config.go +++ b/libnetwork/config/config.go @@ -6,6 +6,7 @@ import ( "github.com/BurntSushi/toml" log "github.com/Sirupsen/logrus" "github.com/docker/docker/pkg/discovery" + "github.com/docker/docker/plugin/getter" "github.com/docker/go-connections/tlsconfig" "github.com/docker/libkv/store" "github.com/docker/libnetwork/cluster" @@ -20,6 +21,7 @@ type Config struct { Cluster ClusterCfg Scopes map[string]*datastore.ScopeCfg ActiveSandboxes map[string]interface{} + PluginGetter getter.PluginGetter } // DaemonCfg represents libnetwork core configuration @@ -205,6 +207,13 @@ func OptionExecRoot(execRoot string) Option { } } +// OptionPluginGetter returns a plugingetter for remote drivers. +func OptionPluginGetter(pg getter.PluginGetter) Option { + return func(c *Config) { + c.PluginGetter = pg + } +} + // ProcessOptions processes options and stores it in config func (c *Config) ProcessOptions(options ...Option) { for _, opt := range options { diff --git a/libnetwork/controller.go b/libnetwork/controller.go index a1906da322..50ff1195a9 100644 --- a/libnetwork/controller.go +++ b/libnetwork/controller.go @@ -55,6 +55,7 @@ import ( "github.com/docker/docker/pkg/locker" "github.com/docker/docker/pkg/plugins" "github.com/docker/docker/pkg/stringid" + "github.com/docker/docker/plugin/getter" "github.com/docker/libnetwork/cluster" "github.com/docker/libnetwork/config" "github.com/docker/libnetwork/datastore" @@ -178,7 +179,7 @@ func New(cfgOptions ...config.Option) (NetworkController, error) { return nil, err } - drvRegistry, err := drvregistry.New(c.getStore(datastore.LocalScope), c.getStore(datastore.GlobalScope), c.RegisterDriver, nil) + drvRegistry, err := drvregistry.New(c.getStore(datastore.LocalScope), c.getStore(datastore.GlobalScope), c.RegisterDriver, nil, c.cfg.PluginGetter) if err != nil { return nil, err } @@ -601,6 +602,10 @@ func (c *controller) isDistributedControl() bool { return !c.isManager() && !c.isAgent() } +func (c *controller) GetPluginGetter() getter.PluginGetter { + return c.drvRegistry.GetPluginGetter() +} + func (c *controller) RegisterDriver(networkType string, driver driverapi.Driver, capability driverapi.Capability) error { c.Lock() hd := c.discovery @@ -1074,7 +1079,7 @@ func (c *controller) loadDriver(networkType string) error { } func (c *controller) loadIPAMDriver(name string) error { - if _, err := plugins.Get(name, ipamapi.PluginEndpointType); err != nil { + if _, err := c.GetPluginGetter().Get(name, ipamapi.PluginEndpointType, getter.LOOKUP); err != nil { if err == plugins.ErrNotFound { return types.NotFoundErrorf(err.Error()) } diff --git a/libnetwork/driverapi/driverapi.go b/libnetwork/driverapi/driverapi.go index ccb7936e2a..51a43e780b 100644 --- a/libnetwork/driverapi/driverapi.go +++ b/libnetwork/driverapi/driverapi.go @@ -3,6 +3,7 @@ package driverapi import ( "net" + "github.com/docker/docker/plugin/getter" "github.com/docker/libnetwork/discoverapi" ) @@ -139,6 +140,8 @@ type JoinInfo interface { // DriverCallback provides a Callback interface for Drivers into LibNetwork type DriverCallback interface { + // GetPluginGetter returns the pluginv2 getter. + GetPluginGetter() getter.PluginGetter // RegisterDriver provides a way for Remote drivers to dynamically register new NetworkType and associate with a driver instance RegisterDriver(name string, driver Driver, capability Capability) error } diff --git a/libnetwork/drivers/ipvlan/ipvlan_test.go b/libnetwork/drivers/ipvlan/ipvlan_test.go index 6d4ee218fc..b4650f469a 100644 --- a/libnetwork/drivers/ipvlan/ipvlan_test.go +++ b/libnetwork/drivers/ipvlan/ipvlan_test.go @@ -3,6 +3,7 @@ package ipvlan import ( "testing" + "github.com/docker/docker/plugin/getter" "github.com/docker/libnetwork/driverapi" _ "github.com/docker/libnetwork/testutils" ) @@ -14,6 +15,10 @@ type driverTester struct { d *driver } +func (dt *driverTester) GetPluginGetter() getter.PluginGetter { + return nil +} + func (dt *driverTester) RegisterDriver(name string, drv driverapi.Driver, cap driverapi.Capability) error { if name != testNetworkType { diff --git a/libnetwork/drivers/macvlan/macvlan_test.go b/libnetwork/drivers/macvlan/macvlan_test.go index 243df5fc0b..76d73f65f2 100644 --- a/libnetwork/drivers/macvlan/macvlan_test.go +++ b/libnetwork/drivers/macvlan/macvlan_test.go @@ -3,6 +3,7 @@ package macvlan import ( "testing" + "github.com/docker/docker/plugin/getter" "github.com/docker/libnetwork/driverapi" _ "github.com/docker/libnetwork/testutils" ) @@ -14,6 +15,10 @@ type driverTester struct { d *driver } +func (dt *driverTester) GetPluginGetter() getter.PluginGetter { + return nil +} + func (dt *driverTester) RegisterDriver(name string, drv driverapi.Driver, cap driverapi.Capability) error { if name != testNetworkType { diff --git a/libnetwork/drivers/overlay/overlay_test.go b/libnetwork/drivers/overlay/overlay_test.go index 1d6012904f..c15886be7f 100644 --- a/libnetwork/drivers/overlay/overlay_test.go +++ b/libnetwork/drivers/overlay/overlay_test.go @@ -5,6 +5,7 @@ import ( "testing" "time" + "github.com/docker/docker/plugin/getter" "github.com/docker/libkv/store/consul" "github.com/docker/libnetwork/datastore" "github.com/docker/libnetwork/discoverapi" @@ -67,6 +68,10 @@ func cleanupDriver(t *testing.T, dt *driverTester) { } } +func (dt *driverTester) GetPluginGetter() getter.PluginGetter { + return nil +} + func (dt *driverTester) RegisterDriver(name string, drv driverapi.Driver, cap driverapi.Capability) error { if name != testNetworkType { diff --git a/libnetwork/drivers/remote/driver.go b/libnetwork/drivers/remote/driver.go index 9fa253bb29..7794d1964f 100644 --- a/libnetwork/drivers/remote/driver.go +++ b/libnetwork/drivers/remote/driver.go @@ -29,7 +29,12 @@ func newDriver(name string, client *plugins.Client) driverapi.Driver { // Init makes sure a remote driver is registered when a network driver // plugin is activated. func Init(dc driverapi.DriverCallback, config map[string]interface{}) error { - plugins.Handle(driverapi.NetworkPluginEndpointType, func(name string, client *plugins.Client) { + // Unit test code is unaware of a true PluginStore. So we fall back to v1 plugins. + handleFunc := plugins.Handle + if pg := dc.GetPluginGetter(); pg != nil { + handleFunc = pg.Handle + } + handleFunc(driverapi.NetworkPluginEndpointType, func(name string, client *plugins.Client) { // negotiate driver capability with client d := newDriver(name, client) c, err := d.(*driver).getCapabilities() diff --git a/libnetwork/drvregistry/drvregistry.go b/libnetwork/drvregistry/drvregistry.go index d2cf781193..af4dee4264 100644 --- a/libnetwork/drvregistry/drvregistry.go +++ b/libnetwork/drvregistry/drvregistry.go @@ -5,6 +5,7 @@ import ( "strings" "sync" + "github.com/docker/docker/plugin/getter" "github.com/docker/libnetwork/driverapi" "github.com/docker/libnetwork/ipamapi" "github.com/docker/libnetwork/types" @@ -28,10 +29,11 @@ type ipamTable map[string]*ipamData // DrvRegistry holds the registry of all network drivers and IPAM drivers that it knows about. type DrvRegistry struct { sync.Mutex - drivers driverTable - ipamDrivers ipamTable - dfn DriverNotifyFunc - ifn IPAMNotifyFunc + drivers driverTable + ipamDrivers ipamTable + dfn DriverNotifyFunc + ifn IPAMNotifyFunc + pluginGetter getter.PluginGetter } // Functors definition @@ -52,12 +54,13 @@ type IPAMNotifyFunc func(name string, driver ipamapi.Ipam, cap *ipamapi.Capabili type DriverNotifyFunc func(name string, driver driverapi.Driver, capability driverapi.Capability) error // New retruns a new driver registry handle. -func New(lDs, gDs interface{}, dfn DriverNotifyFunc, ifn IPAMNotifyFunc) (*DrvRegistry, error) { +func New(lDs, gDs interface{}, dfn DriverNotifyFunc, ifn IPAMNotifyFunc, pg getter.PluginGetter) (*DrvRegistry, error) { r := &DrvRegistry{ - drivers: make(driverTable), - ipamDrivers: make(ipamTable), - dfn: dfn, - ifn: ifn, + drivers: make(driverTable), + ipamDrivers: make(ipamTable), + dfn: dfn, + ifn: ifn, + pluginGetter: pg, } return r, nil @@ -149,6 +152,11 @@ func (r *DrvRegistry) IPAMDefaultAddressSpaces(name string) (string, string, err return i.defaultLocalAddressSpace, i.defaultGlobalAddressSpace, nil } +// GetPluginGetter returns the plugingetter +func (r *DrvRegistry) GetPluginGetter() getter.PluginGetter { + return r.pluginGetter +} + // RegisterDriver registers the network driver when it gets discovered. func (r *DrvRegistry) RegisterDriver(ntype string, driver driverapi.Driver, capability driverapi.Capability) error { if strings.TrimSpace(ntype) == "" { diff --git a/libnetwork/drvregistry/drvregistry_test.go b/libnetwork/drvregistry/drvregistry_test.go index 0b1f7a6843..e52e28c28b 100644 --- a/libnetwork/drvregistry/drvregistry_test.go +++ b/libnetwork/drvregistry/drvregistry_test.go @@ -88,7 +88,7 @@ func (m *mockDriver) EventNotify(etype driverapi.EventType, nid, tableName, key } func getNew(t *testing.T) *DrvRegistry { - reg, err := New(nil, nil, nil, nil) + reg, err := New(nil, nil, nil, nil, nil) if err != nil { t.Fatal(err) } diff --git a/libnetwork/ipamapi/contract.go b/libnetwork/ipamapi/contract.go index a34d4a5c85..2800282ee0 100644 --- a/libnetwork/ipamapi/contract.go +++ b/libnetwork/ipamapi/contract.go @@ -4,6 +4,7 @@ package ipamapi import ( "net" + "github.com/docker/docker/plugin/getter" "github.com/docker/libnetwork/discoverapi" "github.com/docker/libnetwork/types" ) @@ -25,6 +26,8 @@ const ( // Callback provides a Callback interface for registering an IPAM instance into LibNetwork type Callback interface { + // GetPluginGetter returns the pluginv2 getter. + GetPluginGetter() getter.PluginGetter // RegisterIpamDriver provides a way for Remote drivers to dynamically register with libnetwork RegisterIpamDriver(name string, driver Ipam) error // RegisterIpamDriverWithCapabilities provides a way for Remote drivers to dynamically register with libnetwork and specify capabilities diff --git a/libnetwork/ipams/remote/remote.go b/libnetwork/ipams/remote/remote.go index 4ad3287e66..ab00fc6fe7 100644 --- a/libnetwork/ipams/remote/remote.go +++ b/libnetwork/ipams/remote/remote.go @@ -30,7 +30,13 @@ func newAllocator(name string, client *plugins.Client) ipamapi.Ipam { // Init registers a remote ipam when its plugin is activated func Init(cb ipamapi.Callback, l, g interface{}) error { - plugins.Handle(ipamapi.PluginEndpointType, func(name string, client *plugins.Client) { + + // Unit test code is unaware of a true PluginStore. So we fall back to v1 plugins. + handleFunc := plugins.Handle + if pg := cb.GetPluginGetter(); pg != nil { + handleFunc = pg.Handle + } + handleFunc(ipamapi.PluginEndpointType, func(name string, client *plugins.Client) { a := newAllocator(name, client) if cps, err := a.(*allocator).getCapabilities(); err == nil { if err := cb.RegisterIpamDriverWithCapabilities(name, a, cps); err != nil {