mirror of
https://github.com/clearlinux/libnetwork.git
synced 2026-09-05 21:31:37 +00:00
Push driver config during Init
Currently the driver configuration is pushed through a separate api. This makes driver configuration possible at any arbitrary time. This unncessarily complicates the driver implementation. More importantly the driver does not get access to it's configuration before it can do the handshake with libnetwork. This make the internal drivers a little bit different to external plugins which can get their configuration before the handshake with libnetwork. This PR attempts to fix that mismatch between internal drivers and external plugins. Signed-off-by: Jana Radhakrishnan <mrjana@docker.com>
This commit is contained in:
+10
-23
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user