Unverified Kaydet (Commit) d38c7246 authored tarafından Ian Campbell's avatar Ian Campbell Kaydeden (comit) GitHub

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.
import logging import logging
from six.moves import http_client from six.moves import http_client
from ..constants import DEFAULT_SWARM_ADDR_POOL, DEFAULT_SWARM_SUBNET_SIZE
from .. import errors from .. import errors
from .. import types from .. import types
from .. import utils from .. import utils
...@@ -82,7 +83,8 @@ class SwarmApiMixin(object): ...@@ -82,7 +83,8 @@ class SwarmApiMixin(object):
@utils.minimum_version('1.24') @utils.minimum_version('1.24')
def init_swarm(self, advertise_addr=None, listen_addr='0.0.0.0:2377', def init_swarm(self, advertise_addr=None, listen_addr='0.0.0.0:2377',
force_new_cluster=False, swarm_spec=None): force_new_cluster=False, swarm_spec=None,
default_addr_pool=None, subnet_size=None):
""" """
Initialize a new Swarm using the current connected engine as the first Initialize a new Swarm using the current connected engine as the first
node. node.
...@@ -107,6 +109,12 @@ class SwarmApiMixin(object): ...@@ -107,6 +109,12 @@ class SwarmApiMixin(object):
swarm_spec (dict): Configuration settings of the new Swarm. Use swarm_spec (dict): Configuration settings of the new Swarm. Use
``APIClient.create_swarm_spec`` to generate a valid ``APIClient.create_swarm_spec`` to generate a valid
configuration. Default: None configuration. Default: None
default_addr_pool (list of strings): Default Address Pool specifies
default subnet pools for global scope networks. Each pool
should be specified as a CIDR block, like '10.0.0.0/8'.
Default: None
subnet_size (int): SubnetSize specifies the subnet size of the
networks created from the default subnet pool. Default: None
Returns: Returns:
``True`` if successful. ``True`` if successful.
...@@ -119,9 +127,30 @@ class SwarmApiMixin(object): ...@@ -119,9 +127,30 @@ class SwarmApiMixin(object):
url = self._url('/swarm/init') url = self._url('/swarm/init')
if swarm_spec is not None and not isinstance(swarm_spec, dict): if swarm_spec is not None and not isinstance(swarm_spec, dict):
raise TypeError('swarm_spec must be a dictionary') raise TypeError('swarm_spec must be a dictionary')
if default_addr_pool is not None:
if utils.version_lt(self._version, '1.39'):
raise errors.InvalidVersion(
'Address pool is only available for API version >= 1.39'
)
# subnet_size becomes 0 if not set with default_addr_pool
if subnet_size is None:
subnet_size = DEFAULT_SWARM_SUBNET_SIZE
if subnet_size is not None:
if utils.version_lt(self._version, '1.39'):
raise errors.InvalidVersion(
'Subnet size is only available for API version >= 1.39'
)
# subnet_size is ignored if set without default_addr_pool
if default_addr_pool is None:
default_addr_pool = DEFAULT_SWARM_ADDR_POOL
data = { data = {
'AdvertiseAddr': advertise_addr, 'AdvertiseAddr': advertise_addr,
'ListenAddr': listen_addr, 'ListenAddr': listen_addr,
'DefaultAddrPool': default_addr_pool,
'SubnetSize': subnet_size,
'ForceNewCluster': force_new_cluster, 'ForceNewCluster': force_new_cluster,
'Spec': swarm_spec, 'Spec': swarm_spec,
} }
......
...@@ -25,3 +25,6 @@ DEFAULT_NUM_POOLS = 25 ...@@ -25,3 +25,6 @@ DEFAULT_NUM_POOLS = 25
DEFAULT_NUM_POOLS_SSH = 9 DEFAULT_NUM_POOLS_SSH = 9
DEFAULT_DATA_CHUNK_SIZE = 1024 * 2048 DEFAULT_DATA_CHUNK_SIZE = 1024 * 2048
DEFAULT_SWARM_ADDR_POOL = ['10.0.0.0/8']
DEFAULT_SWARM_SUBNET_SIZE = 24
...@@ -34,7 +34,8 @@ class Swarm(Model): ...@@ -34,7 +34,8 @@ class Swarm(Model):
get_unlock_key.__doc__ = APIClient.get_unlock_key.__doc__ get_unlock_key.__doc__ = APIClient.get_unlock_key.__doc__
def init(self, advertise_addr=None, listen_addr='0.0.0.0:2377', def init(self, advertise_addr=None, listen_addr='0.0.0.0:2377',
force_new_cluster=False, **kwargs): force_new_cluster=False, default_addr_pool=None,
subnet_size=None, **kwargs):
""" """
Initialize a new swarm on this Engine. Initialize a new swarm on this Engine.
...@@ -56,6 +57,12 @@ class Swarm(Model): ...@@ -56,6 +57,12 @@ class Swarm(Model):
is used. Default: ``0.0.0.0:2377`` is used. Default: ``0.0.0.0:2377``
force_new_cluster (bool): Force creating a new Swarm, even if force_new_cluster (bool): Force creating a new Swarm, even if
already part of one. Default: False already part of one. Default: False
default_addr_pool (list of str): Default Address Pool specifies
default subnet pools for global scope networks. Each pool
should be specified as a CIDR block, like '10.0.0.0/8'.
Default: None
subnet_size (int): SubnetSize specifies the subnet size of the
networks created from the default subnet pool. Default: None
task_history_retention_limit (int): Maximum number of tasks task_history_retention_limit (int): Maximum number of tasks
history stored. history stored.
snapshot_interval (int): Number of logs entries between snapshot. snapshot_interval (int): Number of logs entries between snapshot.
...@@ -99,7 +106,8 @@ class Swarm(Model): ...@@ -99,7 +106,8 @@ class Swarm(Model):
>>> client.swarm.init( >>> client.swarm.init(
advertise_addr='eth0', listen_addr='0.0.0.0:5000', advertise_addr='eth0', listen_addr='0.0.0.0:5000',
force_new_cluster=False, snapshot_interval=5000, force_new_cluster=False, default_addr_pool=['10.20.0.0/16],
subnet_size=24, snapshot_interval=5000,
log_entries_for_slow_followers=1200 log_entries_for_slow_followers=1200
) )
...@@ -107,7 +115,9 @@ class Swarm(Model): ...@@ -107,7 +115,9 @@ class Swarm(Model):
init_kwargs = { init_kwargs = {
'advertise_addr': advertise_addr, 'advertise_addr': advertise_addr,
'listen_addr': listen_addr, 'listen_addr': listen_addr,
'force_new_cluster': force_new_cluster 'force_new_cluster': force_new_cluster,
'default_addr_pool': default_addr_pool,
'subnet_size': subnet_size
} }
init_kwargs['swarm_spec'] = self.client.api.create_swarm_spec(**kwargs) init_kwargs['swarm_spec'] = self.client.api.create_swarm_spec(**kwargs)
self.client.api.init_swarm(**init_kwargs) self.client.api.init_swarm(**init_kwargs)
......
...@@ -35,6 +35,35 @@ class SwarmTest(BaseAPIIntegrationTest): ...@@ -35,6 +35,35 @@ class SwarmTest(BaseAPIIntegrationTest):
version_2 = self.client.inspect_swarm()['Version']['Index'] version_2 = self.client.inspect_swarm()['Version']['Index']
assert version_2 != version_1 assert version_2 != version_1
@requires_api_version('1.39')
def test_init_swarm_custom_addr_pool_defaults(self):
assert self.init_swarm()
results = self.client.inspect_swarm()
assert set(results['DefaultAddrPool']) == {'10.0.0.0/8'}
assert results['SubnetSize'] == 24
@requires_api_version('1.39')
def test_init_swarm_custom_addr_pool_only_pool(self):
assert self.init_swarm(default_addr_pool=['2.0.0.0/16'])
results = self.client.inspect_swarm()
assert set(results['DefaultAddrPool']) == {'2.0.0.0/16'}
assert results['SubnetSize'] == 24
@requires_api_version('1.39')
def test_init_swarm_custom_addr_pool_only_subnet_size(self):
assert self.init_swarm(subnet_size=26)
results = self.client.inspect_swarm()
assert set(results['DefaultAddrPool']) == {'10.0.0.0/8'}
assert results['SubnetSize'] == 26
@requires_api_version('1.39')
def test_init_swarm_custom_addr_pool_both_args(self):
assert self.init_swarm(default_addr_pool=['2.0.0.0/16', '3.0.0.0/16'],
subnet_size=28)
results = self.client.inspect_swarm()
assert set(results['DefaultAddrPool']) == {'2.0.0.0/16', '3.0.0.0/16'}
assert results['SubnetSize'] == 28
@requires_api_version('1.24') @requires_api_version('1.24')
def test_init_already_in_cluster(self): def test_init_already_in_cluster(self):
assert self.init_swarm() assert self.init_swarm()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment