Browse code

libnet/ipamutils: no more global state

Prior to this change, cnmallocator would call
`ConfigGlobalScopeDefaultNetworks` right before initializing its
IPAM drivers. This function was mutating some global state used
during drivers init.

This change just remove the global state, and adds an arg to
ipams.Register and defaultipam.Register to pass the global pools
by arguments instead.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>

Albin Kerouanton authored on 2024/04/18 22:53:49
Showing 7 changed files
... ...
@@ -32,14 +32,12 @@ func initIPAMDrivers(r ipamapi.Registerer, netConfig *networkallocator.Config) e
32 32
 		str.WriteString(strconv.Itoa(int(netConfig.SubnetSize)))
33 33
 
34 34
 	}
35
-	if err := ipamutils.ConfigGlobalScopeDefaultNetworks(addressPool); err != nil {
36
-		return err
37
-	}
38
-	if addressPool != nil {
35
+
36
+	if len(addressPool) > 0 {
39 37
 		log.G(context.TODO()).Infof("Swarm initialized global default address pool to: " + str.String())
40 38
 	}
41 39
 
42
-	if err := ipams.Register(r, nil, []*ipamutils.NetworkToSplit(nil)); err != nil {
40
+	if err := ipams.Register(r, nil, nil, addressPool); err != nil {
43 41
 		return err
44 42
 	}
45 43
 
... ...
@@ -133,7 +133,7 @@ func New(cfgOptions ...config.Option) (*Controller, error) {
133 133
 		return nil, err
134 134
 	}
135 135
 
136
-	if err := ipams.Register(&c.ipamRegistry, c.cfg.PluginGetter, c.cfg.DefaultAddressPool); err != nil {
136
+	if err := ipams.Register(&c.ipamRegistry, c.cfg.PluginGetter, c.cfg.DefaultAddressPool, nil); err != nil {
137 137
 		return nil, err
138 138
 	}
139 139
 
... ...
@@ -7,7 +7,6 @@ import (
7 7
 
8 8
 	"github.com/docker/docker/libnetwork/ipamapi"
9 9
 	"github.com/docker/docker/libnetwork/ipams"
10
-	"github.com/docker/docker/libnetwork/ipamutils"
11 10
 	"gotest.tools/v3/assert"
12 11
 	is "gotest.tools/v3/assert/cmp"
13 12
 )
... ...
@@ -15,7 +14,7 @@ import (
15 15
 func getNewIPAMs(t *testing.T) *IPAMs {
16 16
 	r := &IPAMs{}
17 17
 
18
-	assert.Assert(t, ipams.Register(r, nil, []*ipamutils.NetworkToSplit(nil)))
18
+	assert.Assert(t, ipams.Register(r, nil, nil, nil))
19 19
 
20 20
 	return r
21 21
 }
... ...
@@ -21,19 +21,28 @@ const (
21 21
 )
22 22
 
23 23
 // Register registers the default ipam driver with libnetwork. It takes
24
-// an optional addressPools containing the list of user-defined address pools
25
-// used by the local address space (ie. daemon's default-address-pools parameter).
26
-func Register(ic ipamapi.Registerer, addressPools []*ipamutils.NetworkToSplit) error {
24
+// two optional address pools respectively containing the list of user-defined
25
+// address pools for 'local' and 'global' address spaces.
26
+func Register(ic ipamapi.Registerer, lAddrPools, gAddrPools []*ipamutils.NetworkToSplit) error {
27 27
 	localAddressPools := ipamutils.GetLocalScopeDefaultNetworks()
28
-	if len(addressPools) > 0 {
28
+	if len(lAddrPools) > 0 {
29 29
 		var err error
30
-		localAddressPools, err = ipamutils.SplitNetworks(addressPools)
30
+		localAddressPools, err = ipamutils.SplitNetworks(lAddrPools)
31 31
 		if err != nil {
32 32
 			return err
33 33
 		}
34 34
 	}
35 35
 
36
-	a, err := NewAllocator(localAddressPools, ipamutils.GetGlobalScopeDefaultNetworks())
36
+	globalAddressPools := ipamutils.GetGlobalScopeDefaultNetworks()
37
+	if len(gAddrPools) > 0 {
38
+		var err error
39
+		globalAddressPools, err = ipamutils.SplitNetworks(gAddrPools)
40
+		if err != nil {
41
+			return err
42
+		}
43
+	}
44
+
45
+	a, err := NewAllocator(localAddressPools, globalAddressPools)
37 46
 	if err != nil {
38 47
 		return err
39 48
 	}
... ...
@@ -12,8 +12,8 @@ import (
12 12
 
13 13
 // Register registers all the builtin drivers (ie. default, windowsipam, null
14 14
 // and remote). If 'pg' is nil, the remote driver won't be registered.
15
-func Register(r ipamapi.Registerer, pg plugingetter.PluginGetter, addressPools []*ipamutils.NetworkToSplit) error {
16
-	if err := defaultipam.Register(r, addressPools); err != nil {
15
+func Register(r ipamapi.Registerer, pg plugingetter.PluginGetter, lAddrPools, gAddrPools []*ipamutils.NetworkToSplit) error {
16
+	if err := defaultipam.Register(r, lAddrPools, gAddrPools); err != nil {
17 17
 		return err
18 18
 	}
19 19
 	if err := windowsipam.Register(r); err != nil {
... ...
@@ -4,7 +4,6 @@ package ipamutils
4 4
 import (
5 5
 	"fmt"
6 6
 	"net"
7
-	"sync"
8 7
 )
9 8
 
10 9
 var (
... ...
@@ -14,7 +13,6 @@ var (
14 14
 	// predefinedGlobalScopeDefaultNetworks contains a list of 64K IPv4 private networks with host size 8
15 15
 	// (10.x.x.x/24) which do not overlap with the networks in `PredefinedLocalScopeDefaultNetworks`
16 16
 	predefinedGlobalScopeDefaultNetworks []*net.IPNet
17
-	mutex                                sync.Mutex
18 17
 	localScopeDefaultNetworks            = []*NetworkToSplit{
19 18
 		{"172.17.0.0/16", 16},
20 19
 		{"172.18.0.0/16", 16},
... ...
@@ -48,26 +46,8 @@ func init() {
48 48
 	}
49 49
 }
50 50
 
51
-// ConfigGlobalScopeDefaultNetworks configures global default pool.
52
-// Ideally this will be called from SwarmKit as part of swarm init
53
-func ConfigGlobalScopeDefaultNetworks(defaultAddressPool []*NetworkToSplit) error {
54
-	if defaultAddressPool == nil {
55
-		return nil
56
-	}
57
-	mutex.Lock()
58
-	defer mutex.Unlock()
59
-	defaultNetworks, err := SplitNetworks(defaultAddressPool)
60
-	if err != nil {
61
-		return err
62
-	}
63
-	predefinedGlobalScopeDefaultNetworks = defaultNetworks
64
-	return nil
65
-}
66
-
67 51
 // GetGlobalScopeDefaultNetworks returns a copy of the global-sopce network list.
68 52
 func GetGlobalScopeDefaultNetworks() []*net.IPNet {
69
-	mutex.Lock()
70
-	defer mutex.Unlock()
71 53
 	return append([]*net.IPNet(nil), predefinedGlobalScopeDefaultNetworks...)
72 54
 }
73 55
 
... ...
@@ -32,17 +32,6 @@ func initGranularPredefinedNetworks() []*net.IPNet {
32 32
 	return pl
33 33
 }
34 34
 
35
-func initGlobalScopeNetworks() []*net.IPNet {
36
-	pl := make([]*net.IPNet, 0, 256*256)
37
-	mask := []byte{255, 255, 255, 0}
38
-	for i := 0; i < 256; i++ {
39
-		for j := 0; j < 256; j++ {
40
-			pl = append(pl, &net.IPNet{IP: []byte{30, byte(i), byte(j), 0}, Mask: mask})
41
-		}
42
-	}
43
-	return pl
44
-}
45
-
46 35
 func TestDefaultNetwork(t *testing.T) {
47 36
 	for _, nw := range GetGlobalScopeDefaultNetworks() {
48 37
 		if ones, bits := nw.Mask.Size(); bits != 32 || ones != 24 {
... ...
@@ -83,21 +72,3 @@ func TestDefaultNetwork(t *testing.T) {
83 83
 
84 84
 	assert.Check(t, is.Len(m, 0))
85 85
 }
86
-
87
-func TestConfigGlobalScopeDefaultNetworks(t *testing.T) {
88
-	err := ConfigGlobalScopeDefaultNetworks([]*NetworkToSplit{{"30.0.0.0/8", 24}})
89
-	assert.NilError(t, err)
90
-
91
-	originalGlobalScopeNetworks := initGlobalScopeNetworks()
92
-	m := make(map[string]bool)
93
-	for _, v := range originalGlobalScopeNetworks {
94
-		m[v.String()] = true
95
-	}
96
-	for _, nw := range GetGlobalScopeDefaultNetworks() {
97
-		_, ok := m[nw.String()]
98
-		assert.Check(t, ok)
99
-		delete(m, nw.String())
100
-	}
101
-
102
-	assert.Check(t, is.Len(m, 0))
103
-}