Quellcode durchsuchen

Make libnetwork understand pluginv2.

As part of daemon init, network and ipam drivers are passed a
pluginstore object that implements the plugin/getter interface. Use this
interface methods in libnetwork to interact with network plugins. This
interface provides the new and improved pluginv2 functionality and falls
back to pluginv1 (legacy) if necessary.

Signed-off-by: Anusha Ragunathan <anusha@docker.com>
Anusha Ragunathan vor 8 Jahren
Ursprung
Commit
003e04775b

+ 5 - 0
libnetwork/cmd/ovrouter/ovrouter.go

@@ -7,6 +7,7 @@ import (
 	"os/signal"
 	"os/signal"
 
 
 	"github.com/docker/docker/pkg/reexec"
 	"github.com/docker/docker/pkg/reexec"
+	"github.com/docker/docker/plugin/getter"
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/drivers/overlay"
 	"github.com/docker/libnetwork/drivers/overlay"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/netlabel"
@@ -24,6 +25,10 @@ type endpoint struct {
 	name string
 	name string
 }
 }
 
 
+func (r *router) GetPluginGetter() getter.PluginGetter {
+	return nil
+}
+
 func (r *router) RegisterDriver(name string, driver driverapi.Driver, c driverapi.Capability) error {
 func (r *router) RegisterDriver(name string, driver driverapi.Driver, c driverapi.Capability) error {
 	r.d = driver
 	r.d = driver
 	return nil
 	return nil

+ 9 - 0
libnetwork/config/config.go

@@ -6,6 +6,7 @@ import (
 	"github.com/BurntSushi/toml"
 	"github.com/BurntSushi/toml"
 	log "github.com/Sirupsen/logrus"
 	log "github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/discovery"
 	"github.com/docker/docker/pkg/discovery"
+	"github.com/docker/docker/plugin/getter"
 	"github.com/docker/go-connections/tlsconfig"
 	"github.com/docker/go-connections/tlsconfig"
 	"github.com/docker/libkv/store"
 	"github.com/docker/libkv/store"
 	"github.com/docker/libnetwork/cluster"
 	"github.com/docker/libnetwork/cluster"
@@ -20,6 +21,7 @@ type Config struct {
 	Cluster         ClusterCfg
 	Cluster         ClusterCfg
 	Scopes          map[string]*datastore.ScopeCfg
 	Scopes          map[string]*datastore.ScopeCfg
 	ActiveSandboxes map[string]interface{}
 	ActiveSandboxes map[string]interface{}
+	PluginGetter    getter.PluginGetter
 }
 }
 
 
 // DaemonCfg represents libnetwork core configuration
 // 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
 // ProcessOptions processes options and stores it in config
 func (c *Config) ProcessOptions(options ...Option) {
 func (c *Config) ProcessOptions(options ...Option) {
 	for _, opt := range options {
 	for _, opt := range options {

+ 7 - 2
libnetwork/controller.go

@@ -55,6 +55,7 @@ import (
 	"github.com/docker/docker/pkg/locker"
 	"github.com/docker/docker/pkg/locker"
 	"github.com/docker/docker/pkg/plugins"
 	"github.com/docker/docker/pkg/plugins"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/pkg/stringid"
+	"github.com/docker/docker/plugin/getter"
 	"github.com/docker/libnetwork/cluster"
 	"github.com/docker/libnetwork/cluster"
 	"github.com/docker/libnetwork/config"
 	"github.com/docker/libnetwork/config"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/datastore"
@@ -178,7 +179,7 @@ func New(cfgOptions ...config.Option) (NetworkController, error) {
 		return nil, err
 		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 {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -601,6 +602,10 @@ func (c *controller) isDistributedControl() bool {
 	return !c.isManager() && !c.isAgent()
 	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 {
 func (c *controller) RegisterDriver(networkType string, driver driverapi.Driver, capability driverapi.Capability) error {
 	c.Lock()
 	c.Lock()
 	hd := c.discovery
 	hd := c.discovery
@@ -1074,7 +1079,7 @@ func (c *controller) loadDriver(networkType string) error {
 }
 }
 
 
 func (c *controller) loadIPAMDriver(name 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 {
 		if err == plugins.ErrNotFound {
 			return types.NotFoundErrorf(err.Error())
 			return types.NotFoundErrorf(err.Error())
 		}
 		}

+ 3 - 0
libnetwork/driverapi/driverapi.go

@@ -3,6 +3,7 @@ package driverapi
 import (
 import (
 	"net"
 	"net"
 
 
+	"github.com/docker/docker/plugin/getter"
 	"github.com/docker/libnetwork/discoverapi"
 	"github.com/docker/libnetwork/discoverapi"
 )
 )
 
 
@@ -139,6 +140,8 @@ type JoinInfo interface {
 
 
 // DriverCallback provides a Callback interface for Drivers into LibNetwork
 // DriverCallback provides a Callback interface for Drivers into LibNetwork
 type DriverCallback interface {
 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 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
 	RegisterDriver(name string, driver Driver, capability Capability) error
 }
 }

+ 5 - 0
libnetwork/drivers/ipvlan/ipvlan_test.go

@@ -3,6 +3,7 @@ package ipvlan
 import (
 import (
 	"testing"
 	"testing"
 
 
+	"github.com/docker/docker/plugin/getter"
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/driverapi"
 	_ "github.com/docker/libnetwork/testutils"
 	_ "github.com/docker/libnetwork/testutils"
 )
 )
@@ -14,6 +15,10 @@ type driverTester struct {
 	d *driver
 	d *driver
 }
 }
 
 
+func (dt *driverTester) GetPluginGetter() getter.PluginGetter {
+	return nil
+}
+
 func (dt *driverTester) RegisterDriver(name string, drv driverapi.Driver,
 func (dt *driverTester) RegisterDriver(name string, drv driverapi.Driver,
 	cap driverapi.Capability) error {
 	cap driverapi.Capability) error {
 	if name != testNetworkType {
 	if name != testNetworkType {

+ 5 - 0
libnetwork/drivers/macvlan/macvlan_test.go

@@ -3,6 +3,7 @@ package macvlan
 import (
 import (
 	"testing"
 	"testing"
 
 
+	"github.com/docker/docker/plugin/getter"
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/driverapi"
 	_ "github.com/docker/libnetwork/testutils"
 	_ "github.com/docker/libnetwork/testutils"
 )
 )
@@ -14,6 +15,10 @@ type driverTester struct {
 	d *driver
 	d *driver
 }
 }
 
 
+func (dt *driverTester) GetPluginGetter() getter.PluginGetter {
+	return nil
+}
+
 func (dt *driverTester) RegisterDriver(name string, drv driverapi.Driver,
 func (dt *driverTester) RegisterDriver(name string, drv driverapi.Driver,
 	cap driverapi.Capability) error {
 	cap driverapi.Capability) error {
 	if name != testNetworkType {
 	if name != testNetworkType {

+ 5 - 0
libnetwork/drivers/overlay/overlay_test.go

@@ -5,6 +5,7 @@ import (
 	"testing"
 	"testing"
 	"time"
 	"time"
 
 
+	"github.com/docker/docker/plugin/getter"
 	"github.com/docker/libkv/store/consul"
 	"github.com/docker/libkv/store/consul"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/discoverapi"
 	"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,
 func (dt *driverTester) RegisterDriver(name string, drv driverapi.Driver,
 	cap driverapi.Capability) error {
 	cap driverapi.Capability) error {
 	if name != testNetworkType {
 	if name != testNetworkType {

+ 6 - 1
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
 // Init makes sure a remote driver is registered when a network driver
 // plugin is activated.
 // plugin is activated.
 func Init(dc driverapi.DriverCallback, config map[string]interface{}) error {
 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
 		// negotiate driver capability with client
 		d := newDriver(name, client)
 		d := newDriver(name, client)
 		c, err := d.(*driver).getCapabilities()
 		c, err := d.(*driver).getCapabilities()

+ 17 - 9
libnetwork/drvregistry/drvregistry.go

@@ -5,6 +5,7 @@ import (
 	"strings"
 	"strings"
 	"sync"
 	"sync"
 
 
+	"github.com/docker/docker/plugin/getter"
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/ipamapi"
 	"github.com/docker/libnetwork/ipamapi"
 	"github.com/docker/libnetwork/types"
 	"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.
 // DrvRegistry holds the registry of all network drivers and IPAM drivers that it knows about.
 type DrvRegistry struct {
 type DrvRegistry struct {
 	sync.Mutex
 	sync.Mutex
-	drivers     driverTable
-	ipamDrivers ipamTable
-	dfn         DriverNotifyFunc
-	ifn         IPAMNotifyFunc
+	drivers      driverTable
+	ipamDrivers  ipamTable
+	dfn          DriverNotifyFunc
+	ifn          IPAMNotifyFunc
+	pluginGetter getter.PluginGetter
 }
 }
 
 
 // Functors definition
 // 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
 type DriverNotifyFunc func(name string, driver driverapi.Driver, capability driverapi.Capability) error
 
 
 // New retruns a new driver registry handle.
 // 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{
 	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
 	return r, nil
@@ -149,6 +152,11 @@ func (r *DrvRegistry) IPAMDefaultAddressSpaces(name string) (string, string, err
 	return i.defaultLocalAddressSpace, i.defaultGlobalAddressSpace, nil
 	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.
 // RegisterDriver registers the network driver when it gets discovered.
 func (r *DrvRegistry) RegisterDriver(ntype string, driver driverapi.Driver, capability driverapi.Capability) error {
 func (r *DrvRegistry) RegisterDriver(ntype string, driver driverapi.Driver, capability driverapi.Capability) error {
 	if strings.TrimSpace(ntype) == "" {
 	if strings.TrimSpace(ntype) == "" {

+ 1 - 1
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 {
 func getNew(t *testing.T) *DrvRegistry {
-	reg, err := New(nil, nil, nil, nil)
+	reg, err := New(nil, nil, nil, nil, nil)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}

+ 3 - 0
libnetwork/ipamapi/contract.go

@@ -4,6 +4,7 @@ package ipamapi
 import (
 import (
 	"net"
 	"net"
 
 
+	"github.com/docker/docker/plugin/getter"
 	"github.com/docker/libnetwork/discoverapi"
 	"github.com/docker/libnetwork/discoverapi"
 	"github.com/docker/libnetwork/types"
 	"github.com/docker/libnetwork/types"
 )
 )
@@ -25,6 +26,8 @@ const (
 
 
 // Callback provides a Callback interface for registering an IPAM instance into LibNetwork
 // Callback provides a Callback interface for registering an IPAM instance into LibNetwork
 type Callback interface {
 type Callback interface {
+	// GetPluginGetter returns the pluginv2 getter.
+	GetPluginGetter() getter.PluginGetter
 	// RegisterIpamDriver provides a way for Remote drivers to dynamically register with libnetwork
 	// RegisterIpamDriver provides a way for Remote drivers to dynamically register with libnetwork
 	RegisterIpamDriver(name string, driver Ipam) error
 	RegisterIpamDriver(name string, driver Ipam) error
 	// RegisterIpamDriverWithCapabilities provides a way for Remote drivers to dynamically register with libnetwork and specify capabilities
 	// RegisterIpamDriverWithCapabilities provides a way for Remote drivers to dynamically register with libnetwork and specify capabilities

+ 7 - 1
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
 // Init registers a remote ipam when its plugin is activated
 func Init(cb ipamapi.Callback, l, g interface{}) error {
 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)
 		a := newAllocator(name, client)
 		if cps, err := a.(*allocator).getCapabilities(); err == nil {
 		if cps, err := a.(*allocator).getCapabilities(); err == nil {
 			if err := cb.RegisterIpamDriverWithCapabilities(name, a, cps); err != nil {
 			if err := cb.RegisterIpamDriverWithCapabilities(name, a, cps); err != nil {