Browse code

libn: refactor platform driver registration

Hide knowledge of the network driver initializer functions from
controller.

Signed-off-by: Cory Snider <csnider@mirantis.com>

Cory Snider authored on 2023/07/05 02:30:54
Showing 15 changed files
... ...
@@ -110,11 +110,6 @@ type Controller struct {
110 110
 	mu               sync.Mutex
111 111
 }
112 112
 
113
-type initializer struct {
114
-	fn    func(driverapi.Registerer, map[string]interface{}) error
115
-	ntype string
116
-}
117
-
118 113
 // New creates a new instance of network controller.
119 114
 func New(cfgOptions ...config.Option) (*Controller, error) {
120 115
 	c := &Controller{
... ...
@@ -141,10 +136,8 @@ func New(cfgOptions ...config.Option) (*Controller, error) {
141 141
 		return nil, err
142 142
 	}
143 143
 
144
-	for _, i := range getInitializers() {
145
-		if err := i.fn(&c.drvRegistry, c.makeDriverConfig(i.ntype)); err != nil {
146
-			return nil, err
147
-		}
144
+	if err := registerNetworkDrivers(&c.drvRegistry, c.makeDriverConfig); err != nil {
145
+		return nil, err
148 146
 	}
149 147
 
150 148
 	if err := initIPAMDrivers(&c.ipamRegistry, c.cfg.PluginGetter, c.cfg.DefaultAddressPool); err != nil {
... ...
@@ -28,7 +28,7 @@ import (
28 28
 )
29 29
 
30 30
 const (
31
-	networkType                = "bridge"
31
+	NetworkType                = "bridge"
32 32
 	vethPrefix                 = "veth"
33 33
 	vethLen                    = len(vethPrefix) + 7
34 34
 	defaultContainerVethPrefix = "eth"
... ...
@@ -174,7 +174,7 @@ func Register(r driverapi.Registerer, config map[string]interface{}) error {
174 174
 	if err := d.configure(config); err != nil {
175 175
 		return err
176 176
 	}
177
-	return r.RegisterDriver(networkType, d, driverapi.Capability{
177
+	return r.RegisterDriver(NetworkType, d, driverapi.Capability{
178 178
 		DataScope:         datastore.LocalScope,
179 179
 		ConnectivityScope: datastore.LocalScope,
180 180
 	})
... ...
@@ -1433,7 +1433,7 @@ func (d *driver) link(network *bridgeNetwork, endpoint *bridgeEndpoint, enable b
1433 1433
 }
1434 1434
 
1435 1435
 func (d *driver) Type() string {
1436
-	return networkType
1436
+	return NetworkType
1437 1437
 }
1438 1438
 
1439 1439
 func (d *driver) IsBuiltIn() bool {
... ...
@@ -9,7 +9,7 @@ import (
9 9
 	"github.com/docker/docker/libnetwork/types"
10 10
 )
11 11
 
12
-const networkType = "host"
12
+const NetworkType = "host"
13 13
 
14 14
 type driver struct {
15 15
 	network string
... ...
@@ -24,7 +24,7 @@ func Init(dc driverapi.DriverCallback, _ map[string]interface{}) error {
24 24
 }
25 25
 
26 26
 func Register(r driverapi.Registerer, _ map[string]interface{}) error {
27
-	return r.RegisterDriver(networkType, &driver{}, driverapi.Capability{
27
+	return r.RegisterDriver(NetworkType, &driver{}, driverapi.Capability{
28 28
 		DataScope:         datastore.LocalScope,
29 29
 		ConnectivityScope: datastore.LocalScope,
30 30
 	})
... ...
@@ -50,7 +50,7 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo d
50 50
 	defer d.Unlock()
51 51
 
52 52
 	if d.network != "" {
53
-		return types.ForbiddenErrorf("only one instance of \"%s\" network is allowed", networkType)
53
+		return types.ForbiddenErrorf("only one instance of \"%s\" network is allowed", NetworkType)
54 54
 	}
55 55
 
56 56
 	d.network = id
... ...
@@ -59,7 +59,7 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo d
59 59
 }
60 60
 
61 61
 func (d *driver) DeleteNetwork(nid string) error {
62
-	return types.ForbiddenErrorf("network of type \"%s\" cannot be deleted", networkType)
62
+	return types.ForbiddenErrorf("network of type \"%s\" cannot be deleted", NetworkType)
63 63
 }
64 64
 
65 65
 func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, epOptions map[string]interface{}) error {
... ...
@@ -93,7 +93,7 @@ func (d *driver) RevokeExternalConnectivity(nid, eid string) error {
93 93
 }
94 94
 
95 95
 func (d *driver) Type() string {
96
-	return networkType
96
+	return NetworkType
97 97
 }
98 98
 
99 99
 func (d *driver) IsBuiltIn() bool {
... ...
@@ -9,7 +9,7 @@ import (
9 9
 func TestDriver(t *testing.T) {
10 10
 	d := &driver{}
11 11
 
12
-	if d.Type() != networkType {
12
+	if d.Type() != NetworkType {
13 13
 		t.Fatal("Unexpected network type returned by driver")
14 14
 	}
15 15
 
... ...
@@ -18,7 +18,7 @@ const (
18 18
 	vethPrefix          = "veth"
19 19
 	vethLen             = len(vethPrefix) + 7
20 20
 
21
-	driverName    = "ipvlan"      // driver type name
21
+	NetworkType   = "ipvlan"      // driver type name
22 22
 	parentOpt     = "parent"      // parent interface -o parent
23 23
 	driverModeOpt = "ipvlan_mode" // mode -o ipvlan_mode
24 24
 	driverFlagOpt = "ipvlan_flag" // flag -o ipvlan_flag
... ...
@@ -70,7 +70,7 @@ func Register(r driverapi.Registerer, config map[string]interface{}) error {
70 70
 	if err := d.initStore(config); err != nil {
71 71
 		return err
72 72
 	}
73
-	return r.RegisterDriver(driverName, d, driverapi.Capability{
73
+	return r.RegisterDriver(NetworkType, d, driverapi.Capability{
74 74
 		DataScope:         datastore.LocalScope,
75 75
 		ConnectivityScope: datastore.GlobalScope,
76 76
 	})
... ...
@@ -89,7 +89,7 @@ func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, erro
89 89
 }
90 90
 
91 91
 func (d *driver) Type() string {
92
-	return driverName
92
+	return NetworkType
93 93
 }
94 94
 
95 95
 func (d *driver) IsBuiltIn() bool {
... ...
@@ -17,7 +17,7 @@ const (
17 17
 	containerVethPrefix = "eth"
18 18
 	vethPrefix          = "veth"
19 19
 	vethLen             = len(vethPrefix) + 7
20
-	driverName          = "macvlan"      // driver type name
20
+	NetworkType         = "macvlan"      // driver type name
21 21
 	modePrivate         = "private"      // macvlan mode private
22 22
 	modeVepa            = "vepa"         // macvlan mode vepa
23 23
 	modeBridge          = "bridge"       // macvlan mode bridge
... ...
@@ -64,7 +64,7 @@ func Register(r driverapi.Registerer, config map[string]interface{}) error {
64 64
 	if err := d.initStore(config); err != nil {
65 65
 		return err
66 66
 	}
67
-	return r.RegisterDriver(driverName, d, driverapi.Capability{
67
+	return r.RegisterDriver(NetworkType, d, driverapi.Capability{
68 68
 		DataScope:         datastore.LocalScope,
69 69
 		ConnectivityScope: datastore.GlobalScope,
70 70
 	})
... ...
@@ -83,7 +83,7 @@ func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, erro
83 83
 }
84 84
 
85 85
 func (d *driver) Type() string {
86
-	return driverName
86
+	return NetworkType
87 87
 }
88 88
 
89 89
 func (d *driver) IsBuiltIn() bool {
... ...
@@ -9,7 +9,7 @@ import (
9 9
 	"github.com/docker/docker/libnetwork/types"
10 10
 )
11 11
 
12
-const networkType = "null"
12
+const NetworkType = "null"
13 13
 
14 14
 type driver struct {
15 15
 	network string
... ...
@@ -18,7 +18,7 @@ type driver struct {
18 18
 
19 19
 // Register registers a new instance of the null driver.
20 20
 func Register(r driverapi.Registerer, _ map[string]interface{}) error {
21
-	return r.RegisterDriver(networkType, &driver{}, driverapi.Capability{
21
+	return r.RegisterDriver(NetworkType, &driver{}, driverapi.Capability{
22 22
 		DataScope: datastore.LocalScope,
23 23
 	})
24 24
 }
... ...
@@ -43,7 +43,7 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo d
43 43
 	defer d.Unlock()
44 44
 
45 45
 	if d.network != "" {
46
-		return types.ForbiddenErrorf("only one instance of \"%s\" network is allowed", networkType)
46
+		return types.ForbiddenErrorf("only one instance of \"%s\" network is allowed", NetworkType)
47 47
 	}
48 48
 
49 49
 	d.network = id
... ...
@@ -52,7 +52,7 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo d
52 52
 }
53 53
 
54 54
 func (d *driver) DeleteNetwork(nid string) error {
55
-	return types.ForbiddenErrorf("network of type \"%s\" cannot be deleted", networkType)
55
+	return types.ForbiddenErrorf("network of type \"%s\" cannot be deleted", NetworkType)
56 56
 }
57 57
 
58 58
 func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, epOptions map[string]interface{}) error {
... ...
@@ -86,7 +86,7 @@ func (d *driver) RevokeExternalConnectivity(nid, eid string) error {
86 86
 }
87 87
 
88 88
 func (d *driver) Type() string {
89
-	return networkType
89
+	return NetworkType
90 90
 }
91 91
 
92 92
 func (d *driver) IsBuiltIn() bool {
... ...
@@ -9,7 +9,7 @@ import (
9 9
 func TestDriver(t *testing.T) {
10 10
 	d := &driver{}
11 11
 
12
-	if d.Type() != networkType {
12
+	if d.Type() != NetworkType {
13 13
 		t.Fatalf("Unexpected network type returned by driver")
14 14
 	}
15 15
 
... ...
@@ -16,7 +16,7 @@ import (
16 16
 )
17 17
 
18 18
 const (
19
-	networkType  = "overlay"
19
+	NetworkType  = "overlay"
20 20
 	vethPrefix   = "veth"
21 21
 	vethLen      = len(vethPrefix) + 7
22 22
 	vxlanEncap   = 50
... ...
@@ -47,7 +47,7 @@ func Register(r driverapi.Registerer, config map[string]interface{}) error {
47 47
 		secMap: &encrMap{nodes: map[string][]*spi{}},
48 48
 		config: config,
49 49
 	}
50
-	return r.RegisterDriver(networkType, d, driverapi.Capability{
50
+	return r.RegisterDriver(NetworkType, d, driverapi.Capability{
51 51
 		DataScope:         datastore.GlobalScope,
52 52
 		ConnectivityScope: datastore.GlobalScope,
53 53
 	})
... ...
@@ -61,7 +61,7 @@ func (d *driver) configure() error {
61 61
 }
62 62
 
63 63
 func (d *driver) Type() string {
64
-	return networkType
64
+	return NetworkType
65 65
 }
66 66
 
67 67
 func (d *driver) IsBuiltIn() bool {
... ...
@@ -17,7 +17,7 @@ import (
17 17
 )
18 18
 
19 19
 const (
20
-	networkType = "overlay"
20
+	NetworkType = "overlay"
21 21
 )
22 22
 
23 23
 type driver struct {
... ...
@@ -33,7 +33,7 @@ func Register(r driverapi.Registerer, _ map[string]interface{}) error {
33 33
 
34 34
 	d.restoreHNSNetworks()
35 35
 
36
-	return r.RegisterDriver(networkType, d, driverapi.Capability{
36
+	return r.RegisterDriver(NetworkType, d, driverapi.Capability{
37 37
 		DataScope:         datastore.GlobalScope,
38 38
 		ConnectivityScope: datastore.GlobalScope,
39 39
 	})
... ...
@@ -48,7 +48,7 @@ func (d *driver) restoreHNSNetworks() error {
48 48
 	}
49 49
 
50 50
 	for _, v := range hnsresponse {
51
-		if v.Type != networkType {
51
+		if v.Type != NetworkType {
52 52
 			continue
53 53
 		}
54 54
 
... ...
@@ -105,7 +105,7 @@ func (d *driver) convertToOverlayNetwork(v *hcsshim.HNSNetwork) *network {
105 105
 }
106 106
 
107 107
 func (d *driver) Type() string {
108
-	return networkType
108
+	return NetworkType
109 109
 }
110 110
 
111 111
 func (d *driver) IsBuiltIn() bool {
... ...
@@ -109,16 +109,20 @@ const (
109 109
 	errNotFound = "HNS failed with error : The object identifier does not represent a valid object. "
110 110
 )
111 111
 
112
+var builtinLocalDrivers = map[string]struct{}{
113
+	"transparent": {},
114
+	"l2bridge":    {},
115
+	"l2tunnel":    {},
116
+	"nat":         {},
117
+	"internal":    {},
118
+	"private":     {},
119
+	"ics":         {},
120
+}
121
+
112 122
 // IsBuiltinLocalDriver validates if network-type is a builtin local-scoped driver
113 123
 func IsBuiltinLocalDriver(networkType string) bool {
114
-	if "l2bridge" == networkType || "l2tunnel" == networkType ||
115
-		"nat" == networkType || "ics" == networkType ||
116
-		"transparent" == networkType || "internal" == networkType ||
117
-		"private" == networkType {
118
-		return true
119
-	}
120
-
121
-	return false
124
+	_, ok := builtinLocalDrivers[networkType]
125
+	return ok
122 126
 }
123 127
 
124 128
 // New constructs a new bridge driver
... ...
@@ -127,24 +131,23 @@ func newDriver(networkType string) *driver {
127 127
 }
128 128
 
129 129
 // GetInit returns an initializer for the given network type
130
-func GetInit(networkType string) func(dc driverapi.Registerer, config map[string]interface{}) error {
131
-	return func(dc driverapi.Registerer, config map[string]interface{}) error {
132
-		if !IsBuiltinLocalDriver(networkType) {
133
-			return types.BadRequestErrorf("Network type not supported: %s", networkType)
134
-		}
135
-
130
+func RegisterBuiltinLocalDrivers(r driverapi.Registerer, driverConfig func(string) map[string]interface{}) error {
131
+	for networkType := range builtinLocalDrivers {
136 132
 		d := newDriver(networkType)
137
-
138
-		err := d.initStore(config)
133
+		err := d.initStore(driverConfig(networkType))
139 134
 		if err != nil {
140
-			return err
135
+			return fmt.Errorf("failed to initialize %q driver: %w", networkType, err)
141 136
 		}
142 137
 
143
-		return dc.RegisterDriver(networkType, d, driverapi.Capability{
138
+		err = r.RegisterDriver(networkType, d, driverapi.Capability{
144 139
 			DataScope:         datastore.LocalScope,
145 140
 			ConnectivityScope: datastore.LocalScope,
146 141
 		})
142
+		if err != nil {
143
+			return fmt.Errorf("failed to register %q driver: %w", networkType, err)
144
+		}
147 145
 	}
146
+	return nil
148 147
 }
149 148
 
150 149
 func (d *driver) getNetwork(id string) (*hnsNetwork, error) {
... ...
@@ -4,8 +4,6 @@ import (
4 4
 	"github.com/docker/docker/libnetwork/drivers/null"
5 5
 )
6 6
 
7
-func getInitializers() []initializer {
8
-	return []initializer{
9
-		{null.Register, "null"},
10
-	}
7
+func registerNetworkDrivers(r driverapi.Registerer, driverConfig func(string) map[string]interface{}) error {
8
+	return null.Register(r, driverConfig(null.NetworkType))
11 9
 }
... ...
@@ -1,6 +1,9 @@
1 1
 package libnetwork
2 2
 
3 3
 import (
4
+	"fmt"
5
+
6
+	"github.com/docker/docker/libnetwork/driverapi"
4 7
 	"github.com/docker/docker/libnetwork/drivers/bridge"
5 8
 	"github.com/docker/docker/libnetwork/drivers/host"
6 9
 	"github.com/docker/docker/libnetwork/drivers/ipvlan"
... ...
@@ -9,14 +12,22 @@ import (
9 9
 	"github.com/docker/docker/libnetwork/drivers/overlay"
10 10
 )
11 11
 
12
-func getInitializers() []initializer {
13
-	in := []initializer{
14
-		{bridge.Register, "bridge"},
15
-		{host.Register, "host"},
16
-		{ipvlan.Register, "ipvlan"},
17
-		{macvlan.Register, "macvlan"},
18
-		{null.Register, "null"},
19
-		{overlay.Register, "overlay"},
12
+func registerNetworkDrivers(r driverapi.Registerer, driverConfig func(string) map[string]interface{}) error {
13
+	for _, nr := range []struct {
14
+		ntype    string
15
+		register func(driverapi.Registerer, map[string]interface{}) error
16
+	}{
17
+		{ntype: bridge.NetworkType, register: bridge.Register},
18
+		{ntype: host.NetworkType, register: host.Register},
19
+		{ntype: ipvlan.NetworkType, register: ipvlan.Register},
20
+		{ntype: macvlan.NetworkType, register: macvlan.Register},
21
+		{ntype: null.NetworkType, register: null.Register},
22
+		{ntype: overlay.NetworkType, register: overlay.Register},
23
+	} {
24
+		if err := nr.register(r, driverConfig(nr.ntype)); err != nil {
25
+			return fmt.Errorf("failed to register %q driver: %w", nr.ntype, err)
26
+		}
20 27
 	}
21
-	return in
28
+
29
+	return nil
22 30
 }
... ...
@@ -2,6 +2,6 @@
2 2
 
3 3
 package libnetwork
4 4
 
5
-func getInitializers() []initializer {
5
+func registerNetworkDrivers(r driverapi.Registerer, driverConfig func(string) map[string]interface{}) error {
6 6
 	return nil
7 7
 }
... ...
@@ -1,21 +1,26 @@
1 1
 package libnetwork
2 2
 
3 3
 import (
4
+	"fmt"
5
+
6
+	"github.com/docker/docker/libnetwork/driverapi"
4 7
 	"github.com/docker/docker/libnetwork/drivers/null"
5 8
 	"github.com/docker/docker/libnetwork/drivers/windows"
6 9
 	"github.com/docker/docker/libnetwork/drivers/windows/overlay"
7 10
 )
8 11
 
9
-func getInitializers() []initializer {
10
-	return []initializer{
11
-		{null.Register, "null"},
12
-		{overlay.Register, "overlay"},
13
-		{windows.GetInit("transparent"), "transparent"},
14
-		{windows.GetInit("l2bridge"), "l2bridge"},
15
-		{windows.GetInit("l2tunnel"), "l2tunnel"},
16
-		{windows.GetInit("nat"), "nat"},
17
-		{windows.GetInit("internal"), "internal"},
18
-		{windows.GetInit("private"), "private"},
19
-		{windows.GetInit("ics"), "ics"},
12
+func registerNetworkDrivers(r driverapi.Registerer, driverConfig func(string) map[string]interface{}) error {
13
+	for _, nr := range []struct {
14
+		ntype    string
15
+		register func(driverapi.Registerer, map[string]interface{}) error
16
+	}{
17
+		{ntype: null.NetworkType, register: null.Register},
18
+		{ntype: overlay.NetworkType, register: overlay.Register},
19
+	} {
20
+		if err := nr.register(r, driverConfig(nr.ntype)); err != nil {
21
+			return fmt.Errorf("failed to register %q driver: %w", nr.ntype, err)
22
+		}
20 23
 	}
24
+
25
+	return windows.RegisterBuiltinLocalDrivers(r, driverConfig)
21 26
 }