diff --git a/README.md b/README.md index 62a0205fc7..46dec9bb79 100644 --- a/README.md +++ b/README.md @@ -17,61 +17,55 @@ There are many networking solutions available to suit a broad range of use-cases ```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 { - 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 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 Code and documentation copyright 2015 Docker, inc. Code released under the Apache 2.0 license. Docs released under Creative commons. - diff --git a/api/api_test.go b/api/api_test.go index 3cf072631d..6477a8d590 100644 --- a/api/api_test.go +++ b/api/api_test.go @@ -93,11 +93,6 @@ func createTestNetwork(t *testing.T, network string) (libnetwork.NetworkControll t.Fatal(err) } - err = c.ConfigureNetworkDriver(bridgeNetType, nil) - if err != nil { - t.Fatal(err) - } - netOption := options.Generic{ netlabel.GenericData: options.Generic{ "BridgeName": network, @@ -184,10 +179,6 @@ func TestCreateDeleteNetwork(t *testing.T) { if err != nil { t.Fatal(err) } - err = c.ConfigureNetworkDriver(bridgeNetType, nil) - if err != nil { - t.Fatal(err) - } badBody, err := json.Marshal("bad body") if err != nil { @@ -262,10 +253,6 @@ func TestGetNetworksAndEndpoints(t *testing.T) { if err != nil { t.Fatal(err) } - err = c.ConfigureNetworkDriver(bridgeNetType, nil) - if err != nil { - t.Fatal(err) - } ops := options.Generic{ netlabel.GenericData: map[string]string{ @@ -536,11 +523,6 @@ func TestProcGetServices(t *testing.T) { t.Fatal(err) } - err = c.ConfigureNetworkDriver(bridgeNetType, nil) - if err != nil { - t.Fatal(err) - } - // Create 2 networks netName1 := "production" netOption := options.Generic{ @@ -1124,10 +1106,6 @@ func TestCreateDeleteEndpoints(t *testing.T) { if err != nil { t.Fatal(err) } - err = c.ConfigureNetworkDriver(bridgeNetType, nil) - if err != nil { - t.Fatal(err) - } nc := networkCreate{Name: "firstNet", NetworkType: bridgeNetType} body, err := json.Marshal(nc) @@ -1250,10 +1228,6 @@ func TestJoinLeave(t *testing.T) { if err != nil { t.Fatal(err) } - err = c.ConfigureNetworkDriver(bridgeNetType, nil) - if err != nil { - t.Fatal(err) - } nb, err := json.Marshal(networkCreate{Name: "network", NetworkType: bridgeNetType}) if err != nil { @@ -1694,11 +1668,6 @@ func TestHttpHandlerUninit(t *testing.T) { t.Fatal(err) } - err = c.ConfigureNetworkDriver(bridgeNetType, nil) - if err != nil { - t.Fatal(err) - } - h := &httpHandler{c: c} h.initRouter() if h.r == nil { @@ -1796,10 +1765,6 @@ func TestEndToEnd(t *testing.T) { if err != nil { t.Fatal(err) } - err = c.ConfigureNetworkDriver(bridgeNetType, nil) - if err != nil { - t.Fatal(err) - } handleRequest := NewHTTPHandler(c) diff --git a/cmd/ovrouter/ovrouter.go b/cmd/ovrouter/ovrouter.go index 0d0dcc9fc9..787320cf48 100644 --- a/cmd/ovrouter/ovrouter.go +++ b/cmd/ovrouter/ovrouter.go @@ -65,12 +65,6 @@ func main() { 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{}) if len(os.Args) > 1 { opt[netlabel.OverlayBindInterface] = os.Args[1] @@ -85,7 +79,11 @@ func main() { 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", map[string]interface{}{}); err != nil { diff --git a/cmd/readme_test/readme.go b/cmd/readme_test/readme.go index 9591aefa5c..5e08525ce6 100644 --- a/cmd/readme_test/readme.go +++ b/cmd/readme_test/readme.go @@ -4,25 +4,21 @@ import ( "fmt" "github.com/docker/libnetwork" + "github.com/docker/libnetwork/config" "github.com/docker/libnetwork/netlabel" "github.com/docker/libnetwork/options" "github.com/docker/libnetwork/types" ) func main() { - // Create a new controller instance - controller, err := libnetwork.New() - if err != nil { - return - } - // 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 - err = controller.ConfigureNetworkDriver(networkType, genericOption) + controller, err := libnetwork.New(config.OptionDriverConfig(networkType, genericOption)) if err != nil { return } diff --git a/cmd/test/libnetwork.toml b/cmd/test/libnetwork.toml deleted file mode 100644 index 4e22516d13..0000000000 --- a/cmd/test/libnetwork.toml +++ /dev/null @@ -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" diff --git a/cmd/test/main.go b/cmd/test/main.go deleted file mode 100644 index 957a0cdab5..0000000000 --- a/cmd/test/main.go +++ /dev/null @@ -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) - } -} diff --git a/config/config.go b/config/config.go index 1935e1657b..504ce21f5f 100644 --- a/config/config.go +++ b/config/config.go @@ -21,6 +21,7 @@ type DaemonCfg struct { DefaultNetwork string DefaultDriver string Labels []string + DriverCfg map[string]interface{} } // 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 func OptionLabels(labels []string) Option { return func(c *Config) { diff --git a/controller.go b/controller.go index 83f30e75f1..ae27ff0a2c 100644 --- a/controller.go +++ b/controller.go @@ -47,7 +47,6 @@ import ( "container/heap" "fmt" "net" - "strings" "sync" log "github.com/Sirupsen/logrus" @@ -57,7 +56,6 @@ import ( "github.com/docker/libnetwork/datastore" "github.com/docker/libnetwork/driverapi" "github.com/docker/libnetwork/hostdiscovery" - "github.com/docker/libnetwork/netlabel" "github.com/docker/libnetwork/osl" "github.com/docker/libnetwork/types" ) @@ -68,9 +66,6 @@ type NetworkController interface { // ID provides an unique identity for the controller 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() config.Config @@ -139,7 +134,11 @@ type controller struct { func New(cfgOptions ...config.Option) (NetworkController, error) { var cfg *config.Config if len(cfgOptions) > 0 { - cfg = &config.Config{} + cfg = &config.Config{ + Daemon: config.DaemonCfg{ + DriverCfg: make(map[string]interface{}), + }, + } cfg.ProcessOptions(cfgOptions...) } c := &controller{ @@ -207,16 +206,6 @@ func (c *controller) Config() config.Config { 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 { if !config.IsValidName(networkType) { return ErrInvalidName(networkType) @@ -228,32 +217,8 @@ func (c *controller) RegisterDriver(networkType string, driver driverapi.Driver, return driverapi.ErrActiveRegistration(networkType) } 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() - if len(opt) != 0 { - if err := driver.Config(opt); err != nil { - return err - } - } - return nil } diff --git a/driverapi/driverapi.go b/driverapi/driverapi.go index bfe44be469..694b0429f6 100644 --- a/driverapi/driverapi.go +++ b/driverapi/driverapi.go @@ -7,9 +7,6 @@ const NetworkPluginEndpointType = "NetworkDriver" // Driver is an interface that every plugin driver needs to implement. 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 // the network id and network specific config. The config mechanism will // eventually be replaced with labels which are yet to be introduced. diff --git a/drivers/bridge/bridge.go b/drivers/bridge/bridge.go index 127fe7ceec..346d8668b1 100644 --- a/drivers/bridge/bridge.go +++ b/drivers/bridge/bridge.go @@ -97,7 +97,6 @@ type bridgeNetwork struct { type driver struct { config *configuration - configured bool network *bridgeNetwork natChain *iptables.ChainInfo filterChain *iptables.ChainInfo @@ -106,13 +105,13 @@ type driver struct { } // New constructs a new bridge driver -func newDriver() driverapi.Driver { +func newDriver() *driver { ipAllocator = ipallocator.New() return &driver{networks: map[string]*bridgeNetwork{}, config: &configuration{}} } // 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 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) @@ -128,10 +127,15 @@ func Init(dc driverapi.DriverCallback) error { 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{ 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. @@ -426,17 +430,13 @@ func (c *networkConfiguration) conflictsWithNetworks(id string, others []*bridge return nil } -func (d *driver) Config(option map[string]interface{}) error { +func (d *driver) configure(option map[string]interface{}) error { var config *configuration var err error d.Lock() defer d.Unlock() - if d.configured { - return &ErrConfigExists{} - } - genericData, ok := option[netlabel.GenericData] if !ok || genericData == nil { return nil @@ -469,7 +469,6 @@ func (d *driver) Config(option map[string]interface{}) error { } } - d.configured = true d.config = config return nil } @@ -567,20 +566,12 @@ func (d *driver) getNetworks() []*bridgeNetwork { // Create a new network using bridge plugin func (d *driver) CreateNetwork(id string, option map[string]interface{}) error { - var ( - err error - configLocked bool - ) + var err error defer osl.InitOSContext()() // Sanity checks d.Lock() - if !d.configured { - configLocked = true - d.configured = true - } - if _, ok := d.networks[id]; ok { d.Unlock() return types.ForbiddenErrorf("network %s exists", id) @@ -619,10 +610,6 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}) error { defer func() { if err != nil { d.Lock() - if configLocked { - d.configured = false - } - delete(d.networks, id) d.Unlock() } diff --git a/drivers/bridge/bridge_test.go b/drivers/bridge/bridge_test.go index f0d849a901..f2604fbc53 100644 --- a/drivers/bridge/bridge_test.go +++ b/drivers/bridge/bridge_test.go @@ -44,7 +44,7 @@ func TestCreateFullOptions(t *testing.T) { genericOption := make(map[string]interface{}) 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) } @@ -86,7 +86,7 @@ func TestCreate(t *testing.T) { defer testutils.SetupTestOSContext(t)() 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) } @@ -119,7 +119,7 @@ func TestCreateFail(t *testing.T) { defer testutils.SetupTestOSContext(t)() 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) } @@ -135,7 +135,6 @@ func TestCreateFail(t *testing.T) { func TestCreateMultipleNetworks(t *testing.T) { defer testutils.SetupTestOSContext(t)() d := newDriver() - dd, _ := d.(*driver) config := &configuration{ EnableIPTables: true, @@ -143,7 +142,7 @@ func TestCreateMultipleNetworks(t *testing.T) { genericOption := make(map[string]interface{}) 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) } @@ -167,7 +166,7 @@ func TestCreateMultipleNetworks(t *testing.T) { } // 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} genericOption[netlabel.GenericData] = config4 @@ -176,19 +175,19 @@ func TestCreateMultipleNetworks(t *testing.T) { } // Now 6 times - verifyV4INCEntries(dd.networks, 6, t) + verifyV4INCEntries(d.networks, 6, t) d.DeleteNetwork("1") - verifyV4INCEntries(dd.networks, 4, t) + verifyV4INCEntries(d.networks, 4, t) d.DeleteNetwork("2") - verifyV4INCEntries(dd.networks, 2, t) + verifyV4INCEntries(d.networks, 2, t) d.DeleteNetwork("3") - verifyV4INCEntries(dd.networks, 0, t) + verifyV4INCEntries(d.networks, 0, t) d.DeleteNetwork("4") - verifyV4INCEntries(dd.networks, 0, t) + verifyV4INCEntries(d.networks, 0, 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) { defer testutils.SetupTestOSContext(t)() d := newDriver() - dd, _ := d.(*driver) config := &configuration{ EnableIPTables: true, @@ -299,7 +297,7 @@ func testQueryEndpointInfo(t *testing.T, ulPxyEnabled bool) { genericOption := make(map[string]interface{}) 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) } @@ -325,7 +323,7 @@ func testQueryEndpointInfo(t *testing.T, ulPxyEnabled bool) { t.Fatalf("Failed to create an endpoint : %s", err.Error()) } - network, ok := dd.networks["net1"] + network, ok := d.networks["net1"] if !ok { t.Fatalf("Cannot find network %s inside driver", "net1") } @@ -362,7 +360,7 @@ func TestCreateLinkWithOptions(t *testing.T) { defer testutils.SetupTestOSContext(t)() 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) } @@ -428,7 +426,7 @@ func TestLinkContainers(t *testing.T) { genericOption := make(map[string]interface{}) 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) } @@ -638,7 +636,7 @@ func TestSetDefaultGw(t *testing.T) { defer testutils.SetupTestOSContext(t)() 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) } diff --git a/drivers/bridge/network_test.go b/drivers/bridge/network_test.go index 769cb8bf17..8112dd6dea 100644 --- a/drivers/bridge/network_test.go +++ b/drivers/bridge/network_test.go @@ -12,9 +12,8 @@ import ( func TestLinkCreate(t *testing.T) { defer testutils.SetupTestOSContext(t)() 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) } @@ -79,7 +78,7 @@ func TestLinkCreate(t *testing.T) { 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 { t.Fatalf("Cannot find network %s inside driver", "dummy") } @@ -108,7 +107,7 @@ func TestLinkCreateTwo(t *testing.T) { defer testutils.SetupTestOSContext(t)() 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) } @@ -144,7 +143,7 @@ func TestLinkCreateNoEnableIPv6(t *testing.T) { defer testutils.SetupTestOSContext(t)() 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) } @@ -178,7 +177,7 @@ func TestLinkDelete(t *testing.T) { defer testutils.SetupTestOSContext(t)() 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) } diff --git a/drivers/bridge/port_mapping_test.go b/drivers/bridge/port_mapping_test.go index bb005f8f63..9e7fa07445 100644 --- a/drivers/bridge/port_mapping_test.go +++ b/drivers/bridge/port_mapping_test.go @@ -27,7 +27,7 @@ func TestPortMappingConfig(t *testing.T) { genericOption := make(map[string]interface{}) 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) } @@ -55,8 +55,7 @@ func TestPortMappingConfig(t *testing.T) { 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 { t.Fatalf("Cannot find network %s inside driver", "dummy") } diff --git a/drivers/host/host.go b/drivers/host/host.go index 2c9d172d9f..eac1af2055 100644 --- a/drivers/host/host.go +++ b/drivers/host/host.go @@ -15,17 +15,13 @@ type driver struct { } // 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{ Scope: driverapi.LocalScope, } 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 { d.Lock() defer d.Unlock() diff --git a/drivers/null/null.go b/drivers/null/null.go index e0bf6b15ca..4a0e92b958 100644 --- a/drivers/null/null.go +++ b/drivers/null/null.go @@ -15,17 +15,13 @@ type driver struct { } // 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{ Scope: driverapi.LocalScope, } 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 { d.Lock() defer d.Unlock() diff --git a/drivers/overlay/overlay.go b/drivers/overlay/overlay.go index 8f55ad6dca..606e723244 100644 --- a/drivers/overlay/overlay.go +++ b/drivers/overlay/overlay.go @@ -67,19 +67,25 @@ func onceInit() { } // 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) c := driverapi.Capability{ Scope: driverapi.GlobalScope, } - return dc.RegisterDriver(networkType, &driver{ + d := &driver{ networks: networkTable{}, peerDb: peerNetworkMap{ 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 @@ -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 err error + if len(option) == 0 { + return nil + } + d.Do(func() { onceDone = true diff --git a/drivers/overlay/overlay_test.go b/drivers/overlay/overlay_test.go index affc0c4c6f..0d8e98f1ec 100644 --- a/drivers/overlay/overlay_test.go +++ b/drivers/overlay/overlay_test.go @@ -5,24 +5,22 @@ import ( "time" "github.com/docker/libnetwork/driverapi" + "github.com/docker/libnetwork/netlabel" _ "github.com/docker/libnetwork/testutils" ) type driverTester struct { t *testing.T - d driverapi.Driver + d *driver } const testNetworkType = "overlay" func setupDriver(t *testing.T) *driverTester { - dt := &driverTester{t: t} - if err := Init(dt); err != nil { - t.Fatal(err) - } - 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) } @@ -60,14 +58,14 @@ func (dt *driverTester) RegisterDriver(name string, drv driverapi.Driver, } 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) } } func TestOverlayFiniWithoutConfig(t *testing.T) { dt := &driverTester{t: t} - if err := Init(dt); err != nil { + if err := Init(dt, nil); err != nil { t.Fatal(err) } @@ -76,11 +74,11 @@ func TestOverlayFiniWithoutConfig(t *testing.T) { func TestOverlayNilConfig(t *testing.T) { dt := &driverTester{t: t} - if err := Init(dt); err != nil { + if err := Init(dt, nil); err != nil { t.Fatal(err) } - if err := dt.d.Config(nil); err != nil { + if err := dt.d.configure(nil); err != nil { t.Fatal(err) } @@ -92,7 +90,7 @@ func TestOverlayConfig(t *testing.T) { time.Sleep(1 * time.Second) - d := dt.d.(*driver) + d := dt.d if d.notifyCh == nil { t.Fatal("Driver notify channel wasn't initialzed after Config method") } @@ -108,19 +106,9 @@ func TestOverlayConfig(t *testing.T) { 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) { dt := &driverTester{t: t} - if err := Init(dt); err != nil { + if err := Init(dt, nil); err != nil { t.Fatal(err) } diff --git a/drivers/remote/driver.go b/drivers/remote/driver.go index 4d1a134f09..23ca8f98bc 100644 --- a/drivers/remote/driver.go +++ b/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 // 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) { // negotiate driver capability with client d := newDriver(name, client) diff --git a/drivers/windows/windows.go b/drivers/windows/windows.go index 80b5c467c7..efca69a99b 100644 --- a/drivers/windows/windows.go +++ b/drivers/windows/windows.go @@ -9,17 +9,13 @@ const networkType = "windows" type driver struct{} // 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{ Scope: driverapi.LocalScope, } 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 { return nil } diff --git a/drivers_linux.go b/drivers_linux.go index b8294d452e..f5c8ffb5c8 100644 --- a/drivers_linux.go +++ b/drivers_linux.go @@ -1,25 +1,66 @@ package libnetwork import ( + "strings" + "github.com/docker/libnetwork/driverapi" "github.com/docker/libnetwork/drivers/bridge" "github.com/docker/libnetwork/drivers/host" "github.com/docker/libnetwork/drivers/null" o "github.com/docker/libnetwork/drivers/overlay" "github.com/docker/libnetwork/drivers/remote" + "github.com/docker/libnetwork/netlabel" ) -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 { +func initDrivers(c *controller) error { + initializers := []struct { + fn func(driverapi.DriverCallback, map[string]interface{}) error + ntype string + }{ + {bridge.Init, "bridge"}, + {host.Init, "host"}, + {null.Init, "null"}, + {remote.Init, "remote"}, + {o.Init, "overlay"}, + } + + for _, i := range initializers { + 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(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 +} diff --git a/libnetwork_test.go b/libnetwork_test.go index 946fd63f0e..b1245c29ac 100644 --- a/libnetwork_test.go +++ b/libnetwork_test.go @@ -21,6 +21,7 @@ import ( "github.com/docker/docker/pkg/plugins" "github.com/docker/docker/pkg/reexec" "github.com/docker/libnetwork" + "github.com/docker/libnetwork/config" "github.com/docker/libnetwork/datastore" "github.com/docker/libnetwork/driverapi" "github.com/docker/libnetwork/netlabel" @@ -48,17 +49,6 @@ func TestMain(m *testing.M) { if err := createController(); err != nil { 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())) @@ -68,7 +58,14 @@ func TestMain(m *testing.M) { func createController() 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 { return err } diff --git a/sandbox_test.go b/sandbox_test.go index 3a74fa1bce..e573f3511f 100644 --- a/sandbox_test.go +++ b/sandbox_test.go @@ -3,6 +3,7 @@ package libnetwork import ( "testing" + "github.com/docker/libnetwork/config" "github.com/docker/libnetwork/netlabel" "github.com/docker/libnetwork/options" "github.com/docker/libnetwork/osl" @@ -14,21 +15,19 @@ func createEmptyCtrlr() *controller { } func getTestEnv(t *testing.T) (NetworkController, Network, Network) { - c, err := New() - if err != nil { - t.Fatal(err) - } + netType := "bridge" option := options.Generic{ "EnableIPForwarding": true, } genericOption := make(map[string]interface{}) 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) } - netType := "bridge" name1 := "test_nw_1" netOption1 := options.Generic{ netlabel.GenericData: options.Generic{