Skip to content

Commit d38c724

Browse files
authored
Merge pull request #2287 from hannseman/swarm-default-addr-pool-redux
Redux added arguments to create a swarm with a custom address pool and subnet size.
2 parents 5abf671 + 68a271c commit d38c724

File tree

4 files changed

+75
-4
lines changed

4 files changed

+75
-4
lines changed

docker/api/swarm.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import logging
22
from six.moves import http_client
3+
from ..constants import DEFAULT_SWARM_ADDR_POOL, DEFAULT_SWARM_SUBNET_SIZE
34
from .. import errors
45
from .. import types
56
from .. import utils
@@ -82,7 +83,8 @@ def get_unlock_key(self):
8283

8384
@utils.minimum_version('1.24')
8485
def init_swarm(self, advertise_addr=None, listen_addr='0.0.0.0:2377',
85-
force_new_cluster=False, swarm_spec=None):
86+
force_new_cluster=False, swarm_spec=None,
87+
default_addr_pool=None, subnet_size=None):
8688
"""
8789
Initialize a new Swarm using the current connected engine as the first
8890
node.
@@ -107,6 +109,12 @@ def init_swarm(self, advertise_addr=None, listen_addr='0.0.0.0:2377',
107109
swarm_spec (dict): Configuration settings of the new Swarm. Use
108110
``APIClient.create_swarm_spec`` to generate a valid
109111
configuration. Default: None
112+
default_addr_pool (list of strings): Default Address Pool specifies
113+
default subnet pools for global scope networks. Each pool
114+
should be specified as a CIDR block, like '10.0.0.0/8'.
115+
Default: None
116+
subnet_size (int): SubnetSize specifies the subnet size of the
117+
networks created from the default subnet pool. Default: None
110118
111119
Returns:
112120
``True`` if successful.
@@ -119,9 +127,30 @@ def init_swarm(self, advertise_addr=None, listen_addr='0.0.0.0:2377',
119127
url = self._url('/swarm/init')
120128
if swarm_spec is not None and not isinstance(swarm_spec, dict):
121129
raise TypeError('swarm_spec must be a dictionary')
130+
131+
if default_addr_pool is not None:
132+
if utils.version_lt(self._version, '1.39'):
133+
raise errors.InvalidVersion(
134+
'Address pool is only available for API version >= 1.39'
135+
)
136+
# subnet_size becomes 0 if not set with default_addr_pool
137+
if subnet_size is None:
138+
subnet_size = DEFAULT_SWARM_SUBNET_SIZE
139+
140+
if subnet_size is not None:
141+
if utils.version_lt(self._version, '1.39'):
142+
raise errors.InvalidVersion(
143+
'Subnet size is only available for API version >= 1.39'
144+
)
145+
# subnet_size is ignored if set without default_addr_pool
146+
if default_addr_pool is None:
147+
default_addr_pool = DEFAULT_SWARM_ADDR_POOL
148+
122149
data = {
123150
'AdvertiseAddr': advertise_addr,
124151
'ListenAddr': listen_addr,
152+
'DefaultAddrPool': default_addr_pool,
153+
'SubnetSize': subnet_size,
125154
'ForceNewCluster': force_new_cluster,
126155
'Spec': swarm_spec,
127156
}

docker/constants.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,6 @@
2525
DEFAULT_NUM_POOLS_SSH = 9
2626

2727
DEFAULT_DATA_CHUNK_SIZE = 1024 * 2048
28+
29+
DEFAULT_SWARM_ADDR_POOL = ['10.0.0.0/8']
30+
DEFAULT_SWARM_SUBNET_SIZE = 24

docker/models/swarm.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ def get_unlock_key(self):
3434
get_unlock_key.__doc__ = APIClient.get_unlock_key.__doc__
3535

3636
def init(self, advertise_addr=None, listen_addr='0.0.0.0:2377',
37-
force_new_cluster=False, **kwargs):
37+
force_new_cluster=False, default_addr_pool=None,
38+
subnet_size=None, **kwargs):
3839
"""
3940
Initialize a new swarm on this Engine.
4041
@@ -56,6 +57,12 @@ def init(self, advertise_addr=None, listen_addr='0.0.0.0:2377',
5657
is used. Default: ``0.0.0.0:2377``
5758
force_new_cluster (bool): Force creating a new Swarm, even if
5859
already part of one. Default: False
60+
default_addr_pool (list of str): Default Address Pool specifies
61+
default subnet pools for global scope networks. Each pool
62+
should be specified as a CIDR block, like '10.0.0.0/8'.
63+
Default: None
64+
subnet_size (int): SubnetSize specifies the subnet size of the
65+
networks created from the default subnet pool. Default: None
5966
task_history_retention_limit (int): Maximum number of tasks
6067
history stored.
6168
snapshot_interval (int): Number of logs entries between snapshot.
@@ -99,15 +106,18 @@ def init(self, advertise_addr=None, listen_addr='0.0.0.0:2377',
99106
100107
>>> client.swarm.init(
101108
advertise_addr='eth0', listen_addr='0.0.0.0:5000',
102-
force_new_cluster=False, snapshot_interval=5000,
109+
force_new_cluster=False, default_addr_pool=['10.20.0.0/16],
110+
subnet_size=24, snapshot_interval=5000,
103111
log_entries_for_slow_followers=1200
104112
)
105113
106114
"""
107115
init_kwargs = {
108116
'advertise_addr': advertise_addr,
109117
'listen_addr': listen_addr,
110-
'force_new_cluster': force_new_cluster
118+
'force_new_cluster': force_new_cluster,
119+
'default_addr_pool': default_addr_pool,
120+
'subnet_size': subnet_size
111121
}
112122
init_kwargs['swarm_spec'] = self.client.api.create_swarm_spec(**kwargs)
113123
self.client.api.init_swarm(**init_kwargs)

tests/integration/api_swarm_test.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,35 @@ def test_init_swarm_force_new_cluster(self):
3535
version_2 = self.client.inspect_swarm()['Version']['Index']
3636
assert version_2 != version_1
3737

38+
@requires_api_version('1.39')
39+
def test_init_swarm_custom_addr_pool_defaults(self):
40+
assert self.init_swarm()
41+
results = self.client.inspect_swarm()
42+
assert set(results['DefaultAddrPool']) == {'10.0.0.0/8'}
43+
assert results['SubnetSize'] == 24
44+
45+
@requires_api_version('1.39')
46+
def test_init_swarm_custom_addr_pool_only_pool(self):
47+
assert self.init_swarm(default_addr_pool=['2.0.0.0/16'])
48+
results = self.client.inspect_swarm()
49+
assert set(results['DefaultAddrPool']) == {'2.0.0.0/16'}
50+
assert results['SubnetSize'] == 24
51+
52+
@requires_api_version('1.39')
53+
def test_init_swarm_custom_addr_pool_only_subnet_size(self):
54+
assert self.init_swarm(subnet_size=26)
55+
results = self.client.inspect_swarm()
56+
assert set(results['DefaultAddrPool']) == {'10.0.0.0/8'}
57+
assert results['SubnetSize'] == 26
58+
59+
@requires_api_version('1.39')
60+
def test_init_swarm_custom_addr_pool_both_args(self):
61+
assert self.init_swarm(default_addr_pool=['2.0.0.0/16', '3.0.0.0/16'],
62+
subnet_size=28)
63+
results = self.client.inspect_swarm()
64+
assert set(results['DefaultAddrPool']) == {'2.0.0.0/16', '3.0.0.0/16'}
65+
assert results['SubnetSize'] == 28
66+
3867
@requires_api_version('1.24')
3968
def test_init_already_in_cluster(self):
4069
assert self.init_swarm()

0 commit comments

Comments
 (0)