Ver Fonte

Merge pull request #547 from mrjana/config

Push driver config during `Init`
Madhu Venugopal há 9 anos atrás
pai
commit
ba09d91d0e

+ 47 - 54
libnetwork/README.md

@@ -17,61 +17,55 @@ There are many networking solutions available to suit a broad range of use-cases
 
 
 
 
 ```go
 ```go
-        // Create a new controller instance
-        controller, err := libnetwork.New()
-        if err != nil {
-                return
-        }
-
-        // Select and configure the network driver
-        networkType := "bridge"
-
-        driverOptions := options.Generic{}
-        genericOption := make(map[string]interface{})
-        genericOption[netlabel.GenericData] = driverOptions
-        err = controller.ConfigureNetworkDriver(networkType, genericOption)
-        if err != nil {
-                return
-        }
-
-        // Create a network for containers to join.
-        // NewNetwork accepts Variadic optional arguments that libnetwork and Drivers can use.
-        network, err := controller.NewNetwork(networkType, "network1")
-        if err != nil {
-                return
-        }
-
-        // For each new container: allocate IP and interfaces. The returned network
-        // settings will be used for container infos (inspect and such), as well as
-        // iptables rules for port publishing. This info is contained or accessible
-        // from the returned endpoint.
-        ep, err := network.CreateEndpoint("Endpoint1")
-        if err != nil {
-                return
-        }
-
-        // Create the sandbox for the containr.
-        sbx, err := controller.NewSandbox("container1",
-        libnetwork.OptionHostname("test"),
-        libnetwork.OptionDomainname("docker.io"))
-		
-        // A sandbox can join the endpoint via the join api.
-        // Join accepts Variadic arguments which libnetwork and Drivers can use.
-        err = ep.Join(sbx)
-        if err != nil {
-                return
-        }
-
-		// libnetwork client can check the endpoint's operational data via the Info() API
-		epInfo, err := ep.DriverInfo()
-		mapData, ok := epInfo[netlabel.PortMap]
+	// Select and configure the network driver
+	networkType := "bridge"
+
+	// Create a new controller instance
+	driverOptions := options.Generic{}
+	genericOption := make(map[string]interface{})
+	genericOption[netlabel.GenericData] = driverOptions
+	controller, err := libnetwork.New(config.OptionDriverConfig(networkType, genericOption))
+	if err != nil {
+		return
+	}
+
+	// Create a network for containers to join.
+	// NewNetwork accepts Variadic optional arguments that libnetwork and Drivers can use.
+	network, err := controller.NewNetwork(networkType, "network1")
+	if err != nil {
+		return
+	}
+
+	// For each new container: allocate IP and interfaces. The returned network
+	// settings will be used for container infos (inspect and such), as well as
+	// iptables rules for port publishing. This info is contained or accessible
+	// from the returned endpoint.
+	ep, err := network.CreateEndpoint("Endpoint1")
+	if err != nil {
+		return
+	}
+
+	// Create the sandbox for the containr.
+	sbx, err := controller.NewSandbox("container1",
+		libnetwork.OptionHostname("test"),
+		libnetwork.OptionDomainname("docker.io"))
+
+	// A sandbox can join the endpoint via the join api.
+	// Join accepts Variadic arguments which libnetwork and Drivers can use.
+	err = ep.Join(sbx)
+	if err != nil {
+		return
+	}
+
+	// libnetwork client can check the endpoint's operational data via the Info() API
+	epInfo, err := ep.DriverInfo()
+	mapData, ok := epInfo[netlabel.PortMap]
+	if ok {
+		portMapping, ok := mapData.([]types.PortBinding)
 		if ok {
 		if ok {
-			portMapping, ok := mapData.([]types.PortBinding)
-			if ok {
-				fmt.Printf("Current port mapping for endpoint %s: %v", ep.Name(), portMapping)
-			}
+			fmt.Printf("Current port mapping for endpoint %s: %v", ep.Name(), portMapping)
 		}
 		}
-
+	}
 ```
 ```
 #### Current Status
 #### Current Status
 Please watch this space for updates on the progress.
 Please watch this space for updates on the progress.
@@ -87,4 +81,3 @@ Want to hack on libnetwork? [Docker's contributions guidelines](https://github.c
 
 
 ## Copyright and license
 ## Copyright and license
 Code and documentation copyright 2015 Docker, inc. Code released under the Apache 2.0 license. Docs released under Creative commons.
 Code and documentation copyright 2015 Docker, inc. Code released under the Apache 2.0 license. Docs released under Creative commons.
-

+ 0 - 35
libnetwork/api/api_test.go

@@ -93,11 +93,6 @@ func createTestNetwork(t *testing.T, network string) (libnetwork.NetworkControll
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
-	err = c.ConfigureNetworkDriver(bridgeNetType, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
 	netOption := options.Generic{
 	netOption := options.Generic{
 		netlabel.GenericData: options.Generic{
 		netlabel.GenericData: options.Generic{
 			"BridgeName":            network,
 			"BridgeName":            network,
@@ -184,10 +179,6 @@ func TestCreateDeleteNetwork(t *testing.T) {
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
-	err = c.ConfigureNetworkDriver(bridgeNetType, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
 
 
 	badBody, err := json.Marshal("bad body")
 	badBody, err := json.Marshal("bad body")
 	if err != nil {
 	if err != nil {
@@ -262,10 +253,6 @@ func TestGetNetworksAndEndpoints(t *testing.T) {
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
-	err = c.ConfigureNetworkDriver(bridgeNetType, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
 
 
 	ops := options.Generic{
 	ops := options.Generic{
 		netlabel.GenericData: map[string]string{
 		netlabel.GenericData: map[string]string{
@@ -536,11 +523,6 @@ func TestProcGetServices(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
-	err = c.ConfigureNetworkDriver(bridgeNetType, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
 	// Create 2 networks
 	// Create 2 networks
 	netName1 := "production"
 	netName1 := "production"
 	netOption := options.Generic{
 	netOption := options.Generic{
@@ -1124,10 +1106,6 @@ func TestCreateDeleteEndpoints(t *testing.T) {
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
-	err = c.ConfigureNetworkDriver(bridgeNetType, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
 
 
 	nc := networkCreate{Name: "firstNet", NetworkType: bridgeNetType}
 	nc := networkCreate{Name: "firstNet", NetworkType: bridgeNetType}
 	body, err := json.Marshal(nc)
 	body, err := json.Marshal(nc)
@@ -1250,10 +1228,6 @@ func TestJoinLeave(t *testing.T) {
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
-	err = c.ConfigureNetworkDriver(bridgeNetType, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
 
 
 	nb, err := json.Marshal(networkCreate{Name: "network", NetworkType: bridgeNetType})
 	nb, err := json.Marshal(networkCreate{Name: "network", NetworkType: bridgeNetType})
 	if err != nil {
 	if err != nil {
@@ -1694,11 +1668,6 @@ func TestHttpHandlerUninit(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
-	err = c.ConfigureNetworkDriver(bridgeNetType, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
 	h := &httpHandler{c: c}
 	h := &httpHandler{c: c}
 	h.initRouter()
 	h.initRouter()
 	if h.r == nil {
 	if h.r == nil {
@@ -1796,10 +1765,6 @@ func TestEndToEnd(t *testing.T) {
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
-	err = c.ConfigureNetworkDriver(bridgeNetType, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
 
 
 	handleRequest := NewHTTPHandler(c)
 	handleRequest := NewHTTPHandler(c)
 
 

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

@@ -65,12 +65,6 @@ func main() {
 		return
 		return
 	}
 	}
 
 
-	r := &router{}
-	if err := overlay.Init(r); err != nil {
-		fmt.Printf("Failed to initialize overlay driver: %v\n", err)
-		os.Exit(1)
-	}
-
 	opt := make(map[string]interface{})
 	opt := make(map[string]interface{})
 	if len(os.Args) > 1 {
 	if len(os.Args) > 1 {
 		opt[netlabel.OverlayBindInterface] = os.Args[1]
 		opt[netlabel.OverlayBindInterface] = os.Args[1]
@@ -85,7 +79,11 @@ func main() {
 		opt[netlabel.KVProviderURL] = os.Args[4]
 		opt[netlabel.KVProviderURL] = os.Args[4]
 	}
 	}
 
 
-	r.d.Config(opt)
+	r := &router{}
+	if err := overlay.Init(r, opt); err != nil {
+		fmt.Printf("Failed to initialize overlay driver: %v\n", err)
+		os.Exit(1)
+	}
 
 
 	if err := r.d.CreateNetwork("testnetwork",
 	if err := r.d.CreateNetwork("testnetwork",
 		map[string]interface{}{}); err != nil {
 		map[string]interface{}{}); err != nil {

+ 3 - 7
libnetwork/cmd/readme_test/readme.go

@@ -4,25 +4,21 @@ import (
 	"fmt"
 	"fmt"
 
 
 	"github.com/docker/libnetwork"
 	"github.com/docker/libnetwork"
+	"github.com/docker/libnetwork/config"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/options"
 	"github.com/docker/libnetwork/options"
 	"github.com/docker/libnetwork/types"
 	"github.com/docker/libnetwork/types"
 )
 )
 
 
 func main() {
 func main() {
-	// Create a new controller instance
-	controller, err := libnetwork.New()
-	if err != nil {
-		return
-	}
-
 	// Select and configure the network driver
 	// Select and configure the network driver
 	networkType := "bridge"
 	networkType := "bridge"
 
 
+	// Create a new controller instance
 	driverOptions := options.Generic{}
 	driverOptions := options.Generic{}
 	genericOption := make(map[string]interface{})
 	genericOption := make(map[string]interface{})
 	genericOption[netlabel.GenericData] = driverOptions
 	genericOption[netlabel.GenericData] = driverOptions
-	err = controller.ConfigureNetworkDriver(networkType, genericOption)
+	controller, err := libnetwork.New(config.OptionDriverConfig(networkType, genericOption))
 	if err != nil {
 	if err != nil {
 		return
 		return
 	}
 	}

+ 0 - 12
libnetwork/cmd/test/libnetwork.toml

@@ -1,12 +0,0 @@
-title = "LibNetwork Configuration file"
-
-[daemon]
-  debug = false
-[cluster]
-  discovery = "token://22aa23948f4f6b31230687689636959e"
-  Address = "1.1.1.1"
-[datastore]
-  embedded = false
-[datastore.client]
-  provider = "consul"
-  Address = "localhost:8500"

+ 0 - 49
libnetwork/cmd/test/main.go

@@ -1,49 +0,0 @@
-package main
-
-import (
-	"fmt"
-	"net"
-	"time"
-
-	log "github.com/Sirupsen/logrus"
-
-	"github.com/docker/libnetwork"
-	"github.com/docker/libnetwork/options"
-)
-
-func main() {
-	log.SetLevel(log.DebugLevel)
-	controller, err := libnetwork.New()
-	if err != nil {
-		log.Fatal(err)
-	}
-
-	netType := "null"
-	ip, net, _ := net.ParseCIDR("192.168.100.1/24")
-	net.IP = ip
-	options := options.Generic{"AddressIPv4": net}
-
-	err = controller.ConfigureNetworkDriver(netType, options)
-	for i := 0; i < 10; i++ {
-		netw, err := controller.NewNetwork(netType, fmt.Sprintf("Gordon-%d", i))
-		if err != nil {
-			if _, ok := err.(libnetwork.NetworkNameError); !ok {
-				log.Fatal(err)
-			}
-		} else {
-			fmt.Println("Network Created Successfully :", netw)
-		}
-		netw, _ = controller.NetworkByName(fmt.Sprintf("Gordon-%d", i))
-		_, err = netw.CreateEndpoint(fmt.Sprintf("Gordon-Ep-%d", i), nil)
-		if err != nil {
-			log.Fatalf("Error creating endpoint 1 %v", err)
-		}
-
-		_, err = netw.CreateEndpoint(fmt.Sprintf("Gordon-Ep2-%d", i), nil)
-		if err != nil {
-			log.Fatalf("Error creating endpoint 2 %v", err)
-		}
-
-		time.Sleep(2 * time.Second)
-	}
-}

+ 8 - 0
libnetwork/config/config.go

@@ -21,6 +21,7 @@ type DaemonCfg struct {
 	DefaultNetwork string
 	DefaultNetwork string
 	DefaultDriver  string
 	DefaultDriver  string
 	Labels         []string
 	Labels         []string
+	DriverCfg      map[string]interface{}
 }
 }
 
 
 // ClusterCfg represents cluster configuration
 // ClusterCfg represents cluster configuration
@@ -71,6 +72,13 @@ func OptionDefaultDriver(dd string) Option {
 	}
 	}
 }
 }
 
 
+// OptionDriverConfig returns an option setter for driver configuration.
+func OptionDriverConfig(networkType string, config map[string]interface{}) Option {
+	return func(c *Config) {
+		c.Daemon.DriverCfg[networkType] = config
+	}
+}
+
 // OptionLabels function returns an option setter for labels
 // OptionLabels function returns an option setter for labels
 func OptionLabels(labels []string) Option {
 func OptionLabels(labels []string) Option {
 	return func(c *Config) {
 	return func(c *Config) {

+ 5 - 40
libnetwork/controller.go

@@ -47,7 +47,6 @@ import (
 	"container/heap"
 	"container/heap"
 	"fmt"
 	"fmt"
 	"net"
 	"net"
-	"strings"
 	"sync"
 	"sync"
 
 
 	log "github.com/Sirupsen/logrus"
 	log "github.com/Sirupsen/logrus"
@@ -57,7 +56,6 @@ import (
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/hostdiscovery"
 	"github.com/docker/libnetwork/hostdiscovery"
-	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/osl"
 	"github.com/docker/libnetwork/osl"
 	"github.com/docker/libnetwork/types"
 	"github.com/docker/libnetwork/types"
 )
 )
@@ -68,9 +66,6 @@ type NetworkController interface {
 	// ID provides an unique identity for the controller
 	// ID provides an unique identity for the controller
 	ID() string
 	ID() string
 
 
-	// ConfigureNetworkDriver applies the passed options to the driver instance for the specified network type
-	ConfigureNetworkDriver(networkType string, options map[string]interface{}) error
-
 	// Config method returns the bootup configuration for the controller
 	// Config method returns the bootup configuration for the controller
 	Config() config.Config
 	Config() config.Config
 
 
@@ -139,7 +134,11 @@ type controller struct {
 func New(cfgOptions ...config.Option) (NetworkController, error) {
 func New(cfgOptions ...config.Option) (NetworkController, error) {
 	var cfg *config.Config
 	var cfg *config.Config
 	if len(cfgOptions) > 0 {
 	if len(cfgOptions) > 0 {
-		cfg = &config.Config{}
+		cfg = &config.Config{
+			Daemon: config.DaemonCfg{
+				DriverCfg: make(map[string]interface{}),
+			},
+		}
 		cfg.ProcessOptions(cfgOptions...)
 		cfg.ProcessOptions(cfgOptions...)
 	}
 	}
 	c := &controller{
 	c := &controller{
@@ -207,16 +206,6 @@ func (c *controller) Config() config.Config {
 	return *c.cfg
 	return *c.cfg
 }
 }
 
 
-func (c *controller) ConfigureNetworkDriver(networkType string, options map[string]interface{}) error {
-	c.Lock()
-	dd, ok := c.drivers[networkType]
-	c.Unlock()
-	if !ok {
-		return NetworkTypeError(networkType)
-	}
-	return dd.driver.Config(options)
-}
-
 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 {
 	if !config.IsValidName(networkType) {
 	if !config.IsValidName(networkType) {
 		return ErrInvalidName(networkType)
 		return ErrInvalidName(networkType)
@@ -228,32 +217,8 @@ func (c *controller) RegisterDriver(networkType string, driver driverapi.Driver,
 		return driverapi.ErrActiveRegistration(networkType)
 		return driverapi.ErrActiveRegistration(networkType)
 	}
 	}
 	c.drivers[networkType] = &driverData{driver, capability}
 	c.drivers[networkType] = &driverData{driver, capability}
-
-	if c.cfg == nil {
-		c.Unlock()
-		return nil
-	}
-
-	opt := make(map[string]interface{})
-	for _, label := range c.cfg.Daemon.Labels {
-		if strings.HasPrefix(label, netlabel.DriverPrefix+"."+networkType) {
-			opt[netlabel.Key(label)] = netlabel.Value(label)
-		}
-	}
-
-	if capability.Scope == driverapi.GlobalScope && c.validateDatastoreConfig() {
-		opt[netlabel.KVProvider] = c.cfg.Datastore.Client.Provider
-		opt[netlabel.KVProviderURL] = c.cfg.Datastore.Client.Address
-	}
-
 	c.Unlock()
 	c.Unlock()
 
 
-	if len(opt) != 0 {
-		if err := driver.Config(opt); err != nil {
-			return err
-		}
-	}
-
 	return nil
 	return nil
 }
 }
 
 

+ 0 - 3
libnetwork/driverapi/driverapi.go

@@ -7,9 +7,6 @@ const NetworkPluginEndpointType = "NetworkDriver"
 
 
 // Driver is an interface that every plugin driver needs to implement.
 // Driver is an interface that every plugin driver needs to implement.
 type Driver interface {
 type Driver interface {
-	// Push driver specific config to the driver
-	Config(options map[string]interface{}) error
-
 	// CreateNetwork invokes the driver method to create a network passing
 	// CreateNetwork invokes the driver method to create a network passing
 	// the network id and network specific config. The config mechanism will
 	// the network id and network specific config. The config mechanism will
 	// eventually be replaced with labels which are yet to be introduced.
 	// eventually be replaced with labels which are yet to be introduced.

+ 55 - 0
libnetwork/drivers.go

@@ -0,0 +1,55 @@
+package libnetwork
+
+import (
+	"strings"
+
+	"github.com/docker/libnetwork/driverapi"
+	"github.com/docker/libnetwork/netlabel"
+)
+
+type initializer struct {
+	fn    func(driverapi.DriverCallback, map[string]interface{}) error
+	ntype string
+}
+
+func initDrivers(c *controller) error {
+	for _, i := range getInitializers() {
+		if err := i.fn(c, makeDriverConfig(c, i.ntype)); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+func makeDriverConfig(c *controller, ntype string) map[string]interface{} {
+	if c.cfg == nil {
+		return nil
+	}
+
+	config := make(map[string]interface{})
+
+	if c.validateDatastoreConfig() {
+		config[netlabel.KVProvider] = c.cfg.Datastore.Client.Provider
+		config[netlabel.KVProviderURL] = c.cfg.Datastore.Client.Address
+	}
+
+	for _, label := range c.cfg.Daemon.Labels {
+		if !strings.HasPrefix(netlabel.Key(label), netlabel.DriverPrefix+"."+ntype) {
+			continue
+		}
+
+		config[netlabel.Key(label)] = netlabel.Value(label)
+	}
+
+	drvCfg, ok := c.cfg.Daemon.DriverCfg[ntype]
+	if !ok {
+		return config
+	}
+
+	for k, v := range drvCfg.(map[string]interface{}) {
+		config[k] = v
+	}
+
+	return config
+}

+ 10 - 23
libnetwork/drivers/bridge/bridge.go

@@ -97,7 +97,6 @@ type bridgeNetwork struct {
 
 
 type driver struct {
 type driver struct {
 	config      *configuration
 	config      *configuration
-	configured  bool
 	network     *bridgeNetwork
 	network     *bridgeNetwork
 	natChain    *iptables.ChainInfo
 	natChain    *iptables.ChainInfo
 	filterChain *iptables.ChainInfo
 	filterChain *iptables.ChainInfo
@@ -106,13 +105,13 @@ type driver struct {
 }
 }
 
 
 // New constructs a new bridge driver
 // New constructs a new bridge driver
-func newDriver() driverapi.Driver {
+func newDriver() *driver {
 	ipAllocator = ipallocator.New()
 	ipAllocator = ipallocator.New()
 	return &driver{networks: map[string]*bridgeNetwork{}, config: &configuration{}}
 	return &driver{networks: map[string]*bridgeNetwork{}, config: &configuration{}}
 }
 }
 
 
 // Init registers a new instance of bridge driver
 // Init registers a new instance of bridge driver
-func Init(dc driverapi.DriverCallback) error {
+func Init(dc driverapi.DriverCallback, config map[string]interface{}) error {
 	if _, err := os.Stat("/proc/sys/net/bridge"); err != nil {
 	if _, err := os.Stat("/proc/sys/net/bridge"); err != nil {
 		if out, err := exec.Command("modprobe", "-va", "bridge", "br_netfilter").CombinedOutput(); err != nil {
 		if out, err := exec.Command("modprobe", "-va", "bridge", "br_netfilter").CombinedOutput(); err != nil {
 			logrus.Warnf("Running modprobe bridge br_netfilter failed with message: %s, error: %v", out, err)
 			logrus.Warnf("Running modprobe bridge br_netfilter failed with message: %s, error: %v", out, err)
@@ -128,10 +127,15 @@ func Init(dc driverapi.DriverCallback) error {
 		logrus.Warnf("Failed to remove existing iptables entries in %s : %v", DockerChain, err)
 		logrus.Warnf("Failed to remove existing iptables entries in %s : %v", DockerChain, err)
 	}
 	}
 
 
+	d := newDriver()
+	if err := d.configure(config); err != nil {
+		return err
+	}
+
 	c := driverapi.Capability{
 	c := driverapi.Capability{
 		Scope: driverapi.LocalScope,
 		Scope: driverapi.LocalScope,
 	}
 	}
-	return dc.RegisterDriver(networkType, newDriver(), c)
+	return dc.RegisterDriver(networkType, d, c)
 }
 }
 
 
 // Validate performs a static validation on the network configuration parameters.
 // Validate performs a static validation on the network configuration parameters.
@@ -426,17 +430,13 @@ func (c *networkConfiguration) conflictsWithNetworks(id string, others []*bridge
 	return nil
 	return nil
 }
 }
 
 
-func (d *driver) Config(option map[string]interface{}) error {
+func (d *driver) configure(option map[string]interface{}) error {
 	var config *configuration
 	var config *configuration
 	var err error
 	var err error
 
 
 	d.Lock()
 	d.Lock()
 	defer d.Unlock()
 	defer d.Unlock()
 
 
-	if d.configured {
-		return &ErrConfigExists{}
-	}
-
 	genericData, ok := option[netlabel.GenericData]
 	genericData, ok := option[netlabel.GenericData]
 	if !ok || genericData == nil {
 	if !ok || genericData == nil {
 		return nil
 		return nil
@@ -469,7 +469,6 @@ func (d *driver) Config(option map[string]interface{}) error {
 		}
 		}
 	}
 	}
 
 
-	d.configured = true
 	d.config = config
 	d.config = config
 	return nil
 	return nil
 }
 }
@@ -567,20 +566,12 @@ func (d *driver) getNetworks() []*bridgeNetwork {
 
 
 // Create a new network using bridge plugin
 // Create a new network using bridge plugin
 func (d *driver) CreateNetwork(id string, option map[string]interface{}) error {
 func (d *driver) CreateNetwork(id string, option map[string]interface{}) error {
-	var (
-		err          error
-		configLocked bool
-	)
+	var err error
 
 
 	defer osl.InitOSContext()()
 	defer osl.InitOSContext()()
 
 
 	// Sanity checks
 	// Sanity checks
 	d.Lock()
 	d.Lock()
-	if !d.configured {
-		configLocked = true
-		d.configured = true
-	}
-
 	if _, ok := d.networks[id]; ok {
 	if _, ok := d.networks[id]; ok {
 		d.Unlock()
 		d.Unlock()
 		return types.ForbiddenErrorf("network %s exists", id)
 		return types.ForbiddenErrorf("network %s exists", id)
@@ -619,10 +610,6 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}) error {
 	defer func() {
 	defer func() {
 		if err != nil {
 		if err != nil {
 			d.Lock()
 			d.Lock()
-			if configLocked {
-				d.configured = false
-			}
-
 			delete(d.networks, id)
 			delete(d.networks, id)
 			d.Unlock()
 			d.Unlock()
 		}
 		}

+ 15 - 17
libnetwork/drivers/bridge/bridge_test.go

@@ -44,7 +44,7 @@ func TestCreateFullOptions(t *testing.T) {
 	genericOption := make(map[string]interface{})
 	genericOption := make(map[string]interface{})
 	genericOption[netlabel.GenericData] = config
 	genericOption[netlabel.GenericData] = config
 
 
-	if err := d.Config(genericOption); err != nil {
+	if err := d.configure(genericOption); err != nil {
 		t.Fatalf("Failed to setup driver config: %v", err)
 		t.Fatalf("Failed to setup driver config: %v", err)
 	}
 	}
 
 
@@ -86,7 +86,7 @@ func TestCreate(t *testing.T) {
 	defer testutils.SetupTestOSContext(t)()
 	defer testutils.SetupTestOSContext(t)()
 	d := newDriver()
 	d := newDriver()
 
 
-	if err := d.Config(nil); err != nil {
+	if err := d.configure(nil); err != nil {
 		t.Fatalf("Failed to setup driver config: %v", err)
 		t.Fatalf("Failed to setup driver config: %v", err)
 	}
 	}
 
 
@@ -119,7 +119,7 @@ func TestCreateFail(t *testing.T) {
 	defer testutils.SetupTestOSContext(t)()
 	defer testutils.SetupTestOSContext(t)()
 	d := newDriver()
 	d := newDriver()
 
 
-	if err := d.Config(nil); err != nil {
+	if err := d.configure(nil); err != nil {
 		t.Fatalf("Failed to setup driver config: %v", err)
 		t.Fatalf("Failed to setup driver config: %v", err)
 	}
 	}
 
 
@@ -135,7 +135,6 @@ func TestCreateFail(t *testing.T) {
 func TestCreateMultipleNetworks(t *testing.T) {
 func TestCreateMultipleNetworks(t *testing.T) {
 	defer testutils.SetupTestOSContext(t)()
 	defer testutils.SetupTestOSContext(t)()
 	d := newDriver()
 	d := newDriver()
-	dd, _ := d.(*driver)
 
 
 	config := &configuration{
 	config := &configuration{
 		EnableIPTables: true,
 		EnableIPTables: true,
@@ -143,7 +142,7 @@ func TestCreateMultipleNetworks(t *testing.T) {
 	genericOption := make(map[string]interface{})
 	genericOption := make(map[string]interface{})
 	genericOption[netlabel.GenericData] = config
 	genericOption[netlabel.GenericData] = config
 
 
-	if err := d.Config(genericOption); err != nil {
+	if err := d.configure(genericOption); err != nil {
 		t.Fatalf("Failed to setup driver config: %v", err)
 		t.Fatalf("Failed to setup driver config: %v", err)
 	}
 	}
 
 
@@ -167,7 +166,7 @@ func TestCreateMultipleNetworks(t *testing.T) {
 	}
 	}
 
 
 	// Verify the network isolation rules are installed, each network subnet should appear 4 times
 	// Verify the network isolation rules are installed, each network subnet should appear 4 times
-	verifyV4INCEntries(dd.networks, 4, t)
+	verifyV4INCEntries(d.networks, 4, t)
 
 
 	config4 := &networkConfiguration{BridgeName: "net_test_4", AllowNonDefaultBridge: true}
 	config4 := &networkConfiguration{BridgeName: "net_test_4", AllowNonDefaultBridge: true}
 	genericOption[netlabel.GenericData] = config4
 	genericOption[netlabel.GenericData] = config4
@@ -176,19 +175,19 @@ func TestCreateMultipleNetworks(t *testing.T) {
 	}
 	}
 
 
 	// Now 6 times
 	// Now 6 times
-	verifyV4INCEntries(dd.networks, 6, t)
+	verifyV4INCEntries(d.networks, 6, t)
 
 
 	d.DeleteNetwork("1")
 	d.DeleteNetwork("1")
-	verifyV4INCEntries(dd.networks, 4, t)
+	verifyV4INCEntries(d.networks, 4, t)
 
 
 	d.DeleteNetwork("2")
 	d.DeleteNetwork("2")
-	verifyV4INCEntries(dd.networks, 2, t)
+	verifyV4INCEntries(d.networks, 2, t)
 
 
 	d.DeleteNetwork("3")
 	d.DeleteNetwork("3")
-	verifyV4INCEntries(dd.networks, 0, t)
+	verifyV4INCEntries(d.networks, 0, t)
 
 
 	d.DeleteNetwork("4")
 	d.DeleteNetwork("4")
-	verifyV4INCEntries(dd.networks, 0, t)
+	verifyV4INCEntries(d.networks, 0, t)
 }
 }
 
 
 func verifyV4INCEntries(networks map[string]*bridgeNetwork, numEntries int, t *testing.T) {
 func verifyV4INCEntries(networks map[string]*bridgeNetwork, numEntries int, t *testing.T) {
@@ -290,7 +289,6 @@ func TestQueryEndpointInfoHairpin(t *testing.T) {
 func testQueryEndpointInfo(t *testing.T, ulPxyEnabled bool) {
 func testQueryEndpointInfo(t *testing.T, ulPxyEnabled bool) {
 	defer testutils.SetupTestOSContext(t)()
 	defer testutils.SetupTestOSContext(t)()
 	d := newDriver()
 	d := newDriver()
-	dd, _ := d.(*driver)
 
 
 	config := &configuration{
 	config := &configuration{
 		EnableIPTables:      true,
 		EnableIPTables:      true,
@@ -299,7 +297,7 @@ func testQueryEndpointInfo(t *testing.T, ulPxyEnabled bool) {
 	genericOption := make(map[string]interface{})
 	genericOption := make(map[string]interface{})
 	genericOption[netlabel.GenericData] = config
 	genericOption[netlabel.GenericData] = config
 
 
-	if err := d.Config(genericOption); err != nil {
+	if err := d.configure(genericOption); err != nil {
 		t.Fatalf("Failed to setup driver config: %v", err)
 		t.Fatalf("Failed to setup driver config: %v", err)
 	}
 	}
 
 
@@ -325,7 +323,7 @@ func testQueryEndpointInfo(t *testing.T, ulPxyEnabled bool) {
 		t.Fatalf("Failed to create an endpoint : %s", err.Error())
 		t.Fatalf("Failed to create an endpoint : %s", err.Error())
 	}
 	}
 
 
-	network, ok := dd.networks["net1"]
+	network, ok := d.networks["net1"]
 	if !ok {
 	if !ok {
 		t.Fatalf("Cannot find network %s inside driver", "net1")
 		t.Fatalf("Cannot find network %s inside driver", "net1")
 	}
 	}
@@ -362,7 +360,7 @@ func TestCreateLinkWithOptions(t *testing.T) {
 	defer testutils.SetupTestOSContext(t)()
 	defer testutils.SetupTestOSContext(t)()
 	d := newDriver()
 	d := newDriver()
 
 
-	if err := d.Config(nil); err != nil {
+	if err := d.configure(nil); err != nil {
 		t.Fatalf("Failed to setup driver config: %v", err)
 		t.Fatalf("Failed to setup driver config: %v", err)
 	}
 	}
 
 
@@ -428,7 +426,7 @@ func TestLinkContainers(t *testing.T) {
 	genericOption := make(map[string]interface{})
 	genericOption := make(map[string]interface{})
 	genericOption[netlabel.GenericData] = config
 	genericOption[netlabel.GenericData] = config
 
 
-	if err := d.Config(genericOption); err != nil {
+	if err := d.configure(genericOption); err != nil {
 		t.Fatalf("Failed to setup driver config: %v", err)
 		t.Fatalf("Failed to setup driver config: %v", err)
 	}
 	}
 
 
@@ -638,7 +636,7 @@ func TestSetDefaultGw(t *testing.T) {
 	defer testutils.SetupTestOSContext(t)()
 	defer testutils.SetupTestOSContext(t)()
 	d := newDriver()
 	d := newDriver()
 
 
-	if err := d.Config(nil); err != nil {
+	if err := d.configure(nil); err != nil {
 		t.Fatalf("Failed to setup driver config: %v", err)
 		t.Fatalf("Failed to setup driver config: %v", err)
 	}
 	}
 
 

+ 5 - 6
libnetwork/drivers/bridge/network_test.go

@@ -12,9 +12,8 @@ import (
 func TestLinkCreate(t *testing.T) {
 func TestLinkCreate(t *testing.T) {
 	defer testutils.SetupTestOSContext(t)()
 	defer testutils.SetupTestOSContext(t)()
 	d := newDriver()
 	d := newDriver()
-	dr := d.(*driver)
 
 
-	if err := d.Config(nil); err != nil {
+	if err := d.configure(nil); err != nil {
 		t.Fatalf("Failed to setup driver config: %v", err)
 		t.Fatalf("Failed to setup driver config: %v", err)
 	}
 	}
 
 
@@ -79,7 +78,7 @@ func TestLinkCreate(t *testing.T) {
 		t.Fatalf("Could not find source link %s: %v", te.iface.srcName, err)
 		t.Fatalf("Could not find source link %s: %v", te.iface.srcName, err)
 	}
 	}
 
 
-	n, ok := dr.networks["dummy"]
+	n, ok := d.networks["dummy"]
 	if !ok {
 	if !ok {
 		t.Fatalf("Cannot find network %s inside driver", "dummy")
 		t.Fatalf("Cannot find network %s inside driver", "dummy")
 	}
 	}
@@ -108,7 +107,7 @@ func TestLinkCreateTwo(t *testing.T) {
 	defer testutils.SetupTestOSContext(t)()
 	defer testutils.SetupTestOSContext(t)()
 	d := newDriver()
 	d := newDriver()
 
 
-	if err := d.Config(nil); err != nil {
+	if err := d.configure(nil); err != nil {
 		t.Fatalf("Failed to setup driver config: %v", err)
 		t.Fatalf("Failed to setup driver config: %v", err)
 	}
 	}
 
 
@@ -144,7 +143,7 @@ func TestLinkCreateNoEnableIPv6(t *testing.T) {
 	defer testutils.SetupTestOSContext(t)()
 	defer testutils.SetupTestOSContext(t)()
 	d := newDriver()
 	d := newDriver()
 
 
-	if err := d.Config(nil); err != nil {
+	if err := d.configure(nil); err != nil {
 		t.Fatalf("Failed to setup driver config: %v", err)
 		t.Fatalf("Failed to setup driver config: %v", err)
 	}
 	}
 
 
@@ -178,7 +177,7 @@ func TestLinkDelete(t *testing.T) {
 	defer testutils.SetupTestOSContext(t)()
 	defer testutils.SetupTestOSContext(t)()
 	d := newDriver()
 	d := newDriver()
 
 
-	if err := d.Config(nil); err != nil {
+	if err := d.configure(nil); err != nil {
 		t.Fatalf("Failed to setup driver config: %v", err)
 		t.Fatalf("Failed to setup driver config: %v", err)
 	}
 	}
 
 

+ 2 - 3
libnetwork/drivers/bridge/port_mapping_test.go

@@ -27,7 +27,7 @@ func TestPortMappingConfig(t *testing.T) {
 	genericOption := make(map[string]interface{})
 	genericOption := make(map[string]interface{})
 	genericOption[netlabel.GenericData] = config
 	genericOption[netlabel.GenericData] = config
 
 
-	if err := d.Config(genericOption); err != nil {
+	if err := d.configure(genericOption); err != nil {
 		t.Fatalf("Failed to setup driver config: %v", err)
 		t.Fatalf("Failed to setup driver config: %v", err)
 	}
 	}
 
 
@@ -55,8 +55,7 @@ func TestPortMappingConfig(t *testing.T) {
 		t.Fatalf("Failed to create the endpoint: %s", err.Error())
 		t.Fatalf("Failed to create the endpoint: %s", err.Error())
 	}
 	}
 
 
-	dd := d.(*driver)
-	network, ok := dd.networks["dummy"]
+	network, ok := d.networks["dummy"]
 	if !ok {
 	if !ok {
 		t.Fatalf("Cannot find network %s inside driver", "dummy")
 		t.Fatalf("Cannot find network %s inside driver", "dummy")
 	}
 	}

+ 1 - 5
libnetwork/drivers/host/host.go

@@ -15,17 +15,13 @@ type driver struct {
 }
 }
 
 
 // Init registers a new instance of host driver
 // Init registers a new instance of host driver
-func Init(dc driverapi.DriverCallback) error {
+func Init(dc driverapi.DriverCallback, config map[string]interface{}) error {
 	c := driverapi.Capability{
 	c := driverapi.Capability{
 		Scope: driverapi.LocalScope,
 		Scope: driverapi.LocalScope,
 	}
 	}
 	return dc.RegisterDriver(networkType, &driver{}, c)
 	return dc.RegisterDriver(networkType, &driver{}, c)
 }
 }
 
 
-func (d *driver) Config(option map[string]interface{}) error {
-	return nil
-}
-
 func (d *driver) CreateNetwork(id string, option map[string]interface{}) error {
 func (d *driver) CreateNetwork(id string, option map[string]interface{}) error {
 	d.Lock()
 	d.Lock()
 	defer d.Unlock()
 	defer d.Unlock()

+ 1 - 5
libnetwork/drivers/null/null.go

@@ -15,17 +15,13 @@ type driver struct {
 }
 }
 
 
 // Init registers a new instance of null driver
 // Init registers a new instance of null driver
-func Init(dc driverapi.DriverCallback) error {
+func Init(dc driverapi.DriverCallback, config map[string]interface{}) error {
 	c := driverapi.Capability{
 	c := driverapi.Capability{
 		Scope: driverapi.LocalScope,
 		Scope: driverapi.LocalScope,
 	}
 	}
 	return dc.RegisterDriver(networkType, &driver{}, c)
 	return dc.RegisterDriver(networkType, &driver{}, c)
 }
 }
 
 
-func (d *driver) Config(option map[string]interface{}) error {
-	return nil
-}
-
 func (d *driver) CreateNetwork(id string, option map[string]interface{}) error {
 func (d *driver) CreateNetwork(id string, option map[string]interface{}) error {
 	d.Lock()
 	d.Lock()
 	defer d.Unlock()
 	defer d.Unlock()

+ 14 - 4
libnetwork/drivers/overlay/overlay.go

@@ -67,19 +67,25 @@ func onceInit() {
 }
 }
 
 
 // Init registers a new instance of overlay driver
 // Init registers a new instance of overlay driver
-func Init(dc driverapi.DriverCallback) error {
+func Init(dc driverapi.DriverCallback, config map[string]interface{}) error {
 	once.Do(onceInit)
 	once.Do(onceInit)
 
 
 	c := driverapi.Capability{
 	c := driverapi.Capability{
 		Scope: driverapi.GlobalScope,
 		Scope: driverapi.GlobalScope,
 	}
 	}
 
 
-	return dc.RegisterDriver(networkType, &driver{
+	d := &driver{
 		networks: networkTable{},
 		networks: networkTable{},
 		peerDb: peerNetworkMap{
 		peerDb: peerNetworkMap{
 			mp: map[string]peerMap{},
 			mp: map[string]peerMap{},
 		},
 		},
-	}, c)
+	}
+
+	if err := d.configure(config); err != nil {
+		return err
+	}
+
+	return dc.RegisterDriver(networkType, d, c)
 }
 }
 
 
 // Fini cleans up the driver resources
 // Fini cleans up the driver resources
@@ -95,10 +101,14 @@ func Fini(drv driverapi.Driver) {
 	}
 	}
 }
 }
 
 
-func (d *driver) Config(option map[string]interface{}) error {
+func (d *driver) configure(option map[string]interface{}) error {
 	var onceDone bool
 	var onceDone bool
 	var err error
 	var err error
 
 
+	if len(option) == 0 {
+		return nil
+	}
+
 	d.Do(func() {
 	d.Do(func() {
 		onceDone = true
 		onceDone = true
 
 

+ 11 - 23
libnetwork/drivers/overlay/overlay_test.go

@@ -5,24 +5,22 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/driverapi"
+	"github.com/docker/libnetwork/netlabel"
 	_ "github.com/docker/libnetwork/testutils"
 	_ "github.com/docker/libnetwork/testutils"
 )
 )
 
 
 type driverTester struct {
 type driverTester struct {
 	t *testing.T
 	t *testing.T
-	d driverapi.Driver
+	d *driver
 }
 }
 
 
 const testNetworkType = "overlay"
 const testNetworkType = "overlay"
 
 
 func setupDriver(t *testing.T) *driverTester {
 func setupDriver(t *testing.T) *driverTester {
-	dt := &driverTester{t: t}
-	if err := Init(dt); err != nil {
-		t.Fatal(err)
-	}
-
 	opt := make(map[string]interface{})
 	opt := make(map[string]interface{})
-	if err := dt.d.Config(opt); err != nil {
+	opt[netlabel.OverlayBindInterface] = "eth0"
+	dt := &driverTester{t: t}
+	if err := Init(dt, opt); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
@@ -60,14 +58,14 @@ func (dt *driverTester) RegisterDriver(name string, drv driverapi.Driver,
 }
 }
 
 
 func TestOverlayInit(t *testing.T) {
 func TestOverlayInit(t *testing.T) {
-	if err := Init(&driverTester{t: t}); err != nil {
+	if err := Init(&driverTester{t: t}, nil); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 }
 }
 
 
 func TestOverlayFiniWithoutConfig(t *testing.T) {
 func TestOverlayFiniWithoutConfig(t *testing.T) {
 	dt := &driverTester{t: t}
 	dt := &driverTester{t: t}
-	if err := Init(dt); err != nil {
+	if err := Init(dt, nil); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
@@ -76,11 +74,11 @@ func TestOverlayFiniWithoutConfig(t *testing.T) {
 
 
 func TestOverlayNilConfig(t *testing.T) {
 func TestOverlayNilConfig(t *testing.T) {
 	dt := &driverTester{t: t}
 	dt := &driverTester{t: t}
-	if err := Init(dt); err != nil {
+	if err := Init(dt, nil); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
-	if err := dt.d.Config(nil); err != nil {
+	if err := dt.d.configure(nil); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
@@ -92,7 +90,7 @@ func TestOverlayConfig(t *testing.T) {
 
 
 	time.Sleep(1 * time.Second)
 	time.Sleep(1 * time.Second)
 
 
-	d := dt.d.(*driver)
+	d := dt.d
 	if d.notifyCh == nil {
 	if d.notifyCh == nil {
 		t.Fatal("Driver notify channel wasn't initialzed after Config method")
 		t.Fatal("Driver notify channel wasn't initialzed after Config method")
 	}
 	}
@@ -108,19 +106,9 @@ func TestOverlayConfig(t *testing.T) {
 	cleanupDriver(t, dt)
 	cleanupDriver(t, dt)
 }
 }
 
 
-func TestOverlayMultipleConfig(t *testing.T) {
-	dt := setupDriver(t)
-
-	if err := dt.d.Config(nil); err == nil {
-		t.Fatal("Expected a failure, instead succeded")
-	}
-
-	cleanupDriver(t, dt)
-}
-
 func TestOverlayType(t *testing.T) {
 func TestOverlayType(t *testing.T) {
 	dt := &driverTester{t: t}
 	dt := &driverTester{t: t}
-	if err := Init(dt); err != nil {
+	if err := Init(dt, nil); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 

+ 1 - 1
libnetwork/drivers/remote/driver.go

@@ -26,7 +26,7 @@ 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) error {
+func Init(dc driverapi.DriverCallback, config map[string]interface{}) error {
 	plugins.Handle(driverapi.NetworkPluginEndpointType, func(name string, client *plugins.Client) {
 	plugins.Handle(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)

+ 1 - 5
libnetwork/drivers/windows/windows.go

@@ -9,17 +9,13 @@ const networkType = "windows"
 type driver struct{}
 type driver struct{}
 
 
 // Init registers a new instance of null driver
 // Init registers a new instance of null driver
-func Init(dc driverapi.DriverCallback) error {
+func Init(dc driverapi.DriverCallback, config map[string]interface{}) error {
 	c := driverapi.Capability{
 	c := driverapi.Capability{
 		Scope: driverapi.LocalScope,
 		Scope: driverapi.LocalScope,
 	}
 	}
 	return dc.RegisterDriver(networkType, &driver{}, c)
 	return dc.RegisterDriver(networkType, &driver{}, c)
 }
 }
 
 
-func (d *driver) Config(option map[string]interface{}) error {
-	return nil
-}
-
 func (d *driver) CreateNetwork(id string, option map[string]interface{}) error {
 func (d *driver) CreateNetwork(id string, option map[string]interface{}) error {
 	return nil
 	return nil
 }
 }

+ 4 - 10
libnetwork/drivers_freebsd.go

@@ -1,19 +1,13 @@
 package libnetwork
 package libnetwork
 
 
 import (
 import (
-	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/drivers/null"
 	"github.com/docker/libnetwork/drivers/null"
 	"github.com/docker/libnetwork/drivers/remote"
 	"github.com/docker/libnetwork/drivers/remote"
 )
 )
 
 
-func initDrivers(dc driverapi.DriverCallback) error {
-	for _, fn := range [](func(driverapi.DriverCallback) error){
-		null.Init,
-		remote.Init,
-	} {
-		if err := fn(dc); err != nil {
-			return err
-		}
+func getInitializers() []initializer {
+	return []initializer{
+		{null.Init, "null"},
+		{remote.Init, "remote"},
 	}
 	}
-	return nil
 }
 }

+ 8 - 14
libnetwork/drivers_linux.go

@@ -1,25 +1,19 @@
 package libnetwork
 package libnetwork
 
 
 import (
 import (
-	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/drivers/bridge"
 	"github.com/docker/libnetwork/drivers/bridge"
 	"github.com/docker/libnetwork/drivers/host"
 	"github.com/docker/libnetwork/drivers/host"
 	"github.com/docker/libnetwork/drivers/null"
 	"github.com/docker/libnetwork/drivers/null"
-	o "github.com/docker/libnetwork/drivers/overlay"
+	"github.com/docker/libnetwork/drivers/overlay"
 	"github.com/docker/libnetwork/drivers/remote"
 	"github.com/docker/libnetwork/drivers/remote"
 )
 )
 
 
-func initDrivers(dc driverapi.DriverCallback) error {
-	for _, fn := range [](func(driverapi.DriverCallback) error){
-		bridge.Init,
-		host.Init,
-		null.Init,
-		remote.Init,
-		o.Init,
-	} {
-		if err := fn(dc); err != nil {
-			return err
-		}
+func getInitializers() []initializer {
+	return []initializer{
+		{bridge.Init, "bridge"},
+		{host.Init, "host"},
+		{null.Init, "null"},
+		{remote.Init, "remote"},
+		{overlay.Init, "overlay"},
 	}
 	}
-	return nil
 }
 }

+ 4 - 12
libnetwork/drivers_windows.go

@@ -1,17 +1,9 @@
 package libnetwork
 package libnetwork
 
 
-import (
-	"github.com/docker/libnetwork/driverapi"
-	"github.com/docker/libnetwork/drivers/windows"
-)
+import "github.com/docker/libnetwork/drivers/windows"
 
 
-func initDrivers(dc driverapi.DriverCallback) error {
-	for _, fn := range [](func(driverapi.DriverCallback) error){
-		windows.Init,
-	} {
-		if err := fn(dc); err != nil {
-			return err
-		}
+func getInitializers() []initializer {
+	return []initializer{
+		{windows.Init, "windows"},
 	}
 	}
-	return nil
 }
 }

+ 9 - 12
libnetwork/libnetwork_test.go

@@ -21,6 +21,7 @@ import (
 	"github.com/docker/docker/pkg/plugins"
 	"github.com/docker/docker/pkg/plugins"
 	"github.com/docker/docker/pkg/reexec"
 	"github.com/docker/docker/pkg/reexec"
 	"github.com/docker/libnetwork"
 	"github.com/docker/libnetwork"
+	"github.com/docker/libnetwork/config"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/netlabel"
@@ -48,17 +49,6 @@ func TestMain(m *testing.M) {
 	if err := createController(); err != nil {
 	if err := createController(); err != nil {
 		os.Exit(1)
 		os.Exit(1)
 	}
 	}
-	option := options.Generic{
-		"EnableIPForwarding": true,
-	}
-
-	genericOption := make(map[string]interface{})
-	genericOption[netlabel.GenericData] = option
-
-	err := controller.ConfigureNetworkDriver(bridgeNetType, genericOption)
-	if err != nil {
-		os.Exit(1)
-	}
 
 
 	libnetwork.SetTestDataStore(controller, datastore.NewCustomDataStore(datastore.NewMockStore()))
 	libnetwork.SetTestDataStore(controller, datastore.NewCustomDataStore(datastore.NewMockStore()))
 
 
@@ -68,7 +58,14 @@ func TestMain(m *testing.M) {
 func createController() error {
 func createController() error {
 	var err error
 	var err error
 
 
-	controller, err = libnetwork.New()
+	option := options.Generic{
+		"EnableIPForwarding": true,
+	}
+
+	genericOption := make(map[string]interface{})
+	genericOption[netlabel.GenericData] = option
+
+	controller, err = libnetwork.New(config.OptionDriverConfig(bridgeNetType, genericOption))
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}

+ 5 - 6
libnetwork/sandbox_test.go

@@ -3,6 +3,7 @@ package libnetwork
 import (
 import (
 	"testing"
 	"testing"
 
 
+	"github.com/docker/libnetwork/config"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/options"
 	"github.com/docker/libnetwork/options"
 	"github.com/docker/libnetwork/osl"
 	"github.com/docker/libnetwork/osl"
@@ -14,21 +15,19 @@ func createEmptyCtrlr() *controller {
 }
 }
 
 
 func getTestEnv(t *testing.T) (NetworkController, Network, Network) {
 func getTestEnv(t *testing.T) (NetworkController, Network, Network) {
-	c, err := New()
-	if err != nil {
-		t.Fatal(err)
-	}
+	netType := "bridge"
 
 
 	option := options.Generic{
 	option := options.Generic{
 		"EnableIPForwarding": true,
 		"EnableIPForwarding": true,
 	}
 	}
 	genericOption := make(map[string]interface{})
 	genericOption := make(map[string]interface{})
 	genericOption[netlabel.GenericData] = option
 	genericOption[netlabel.GenericData] = option
-	if err := c.ConfigureNetworkDriver("bridge", genericOption); err != nil {
+
+	c, err := New(config.OptionDriverConfig(netType, genericOption))
+	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
-	netType := "bridge"
 	name1 := "test_nw_1"
 	name1 := "test_nw_1"
 	netOption1 := options.Generic{
 	netOption1 := options.Generic{
 		netlabel.GenericData: options.Generic{
 		netlabel.GenericData: options.Generic{