Kaydet (Commit) 07563cfe authored tarafından Joffrey F's avatar Joffrey F

Update swarm methods to include newly added parameters

Rename swarm methods to be more explicit
Utility methods / types to create swarm spec objects

Integration tests
Signed-off-by: 's avatarJoffrey F <joffrey@docker.com>
üst 9fdc8d47
......@@ -4,38 +4,49 @@ log = logging.getLogger(__name__)
class SwarmApiMixin(object):
@utils.minimum_version('1.24')
def swarm(self):
url = self._url('/swarm')
return self._result(self._get(url), True)
def create_swarm_spec(self, *args, **kwargs):
return utils.SwarmSpec(*args, **kwargs)
@utils.minimum_version('1.24')
def swarm_init(self, listen_addr, force_new_cluster=False,
swarm_opts=None):
def init_swarm(self, advertise_addr, listen_addr='0.0.0.0:2377',
force_new_cluster=False, swarm_spec=None):
url = self._url('/swarm/init')
if swarm_opts is not None and not isinstance(swarm_opts, dict):
raise TypeError('swarm_opts must be a dictionary')
if swarm_spec is not None and not isinstance(swarm_spec, dict):
raise TypeError('swarm_spec must be a dictionary')
data = {
'AdvertiseAddr': advertise_addr,
'ListenAddr': listen_addr,
'ForceNewCluster': force_new_cluster,
'Spec': swarm_opts
'Spec': swarm_spec,
}
return self._result(self._post_json(url, data=data), True)
response = self._post_json(url, data=data)
self._raise_for_status(response)
return True
@utils.minimum_version('1.24')
def inspect_swarm(self):
url = self._url('/swarm')
return self._result(self._get(url), True)
@utils.minimum_version('1.24')
def swarm_join(self, remote_address, listen_address=None,
def join_swarm(self, remote_addresses, listen_address=None,
secret=None, ca_cert_hash=None, manager=False):
data = {
"RemoteAddr": remote_address,
"RemoteAddrs": remote_addresses,
"ListenAddr": listen_address,
"Secret": secret,
"CACertHash": ca_cert_hash,
"Manager": manager
}
url = self._url('/swarm/join', )
return self._result(self._post_json(url, data=data), True)
url = self._url('/swarm/join')
response = self._post_json(url, data=data)
self._raise_for_status(response)
return True
@utils.minimum_version('1.24')
def swarm_leave(self):
def leave_swarm(self, force=False):
url = self._url('/swarm/leave')
return self._result(self._post(url))
response = self._post(url, params={'force': force})
self._raise_for_status(response)
return True
import sys
from .version import version
DEFAULT_DOCKER_API_VERSION = '1.22'
DEFAULT_DOCKER_API_VERSION = '1.24'
DEFAULT_TIMEOUT_SECONDS = 60
STREAM_HEADER_SIZE_BYTES = 8
CONTAINER_LIMITS_KEYS = [
......
......@@ -8,5 +8,8 @@ from .utils import (
create_ipam_config, create_ipam_pool, parse_devices, normalize_links,
)
from .types import Ulimit, LogConfig
from .types import LogConfig, Ulimit
from .types import (
SwarmAcceptancePolicy, SwarmExternalCA, SwarmSpec,
)
from .decorators import check_resource, minimum_version, update_headers
......@@ -94,3 +94,52 @@ class Ulimit(DictType):
@hard.setter
def hard(self, value):
self['Hard'] = value
class SwarmSpec(DictType):
def __init__(self, policies=None, task_history_retention_limit=None,
snapshot_interval=None, keep_old_snapshots=None,
log_entries_for_slow_followers=None, heartbeat_tick=None,
election_tick=None, dispatcher_heartbeat_period=None,
node_cert_expiry=None, external_ca=None):
if policies is not None:
self['AcceptancePolicy'] = {'Policies': policies}
if task_history_retention_limit is not None:
self['Orchestration'] = {
'TaskHistoryRetentionLimit': task_history_retention_limit
}
if any(snapshot_interval, keep_old_snapshots,
log_entries_for_slow_followers, heartbeat_tick, election_tick):
self['Raft'] = {
'SnapshotInterval': snapshot_interval,
'KeepOldSnapshots': keep_old_snapshots,
'LogEntriesForSlowFollowers': log_entries_for_slow_followers,
'HeartbeatTick': heartbeat_tick,
'ElectionTick': election_tick
}
if dispatcher_heartbeat_period:
self['Dispatcher'] = {
'HeartbeatPeriod': dispatcher_heartbeat_period
}
if node_cert_expiry or external_ca:
self['CAConfig'] = {
'NodeCertExpiry': node_cert_expiry,
'ExternalCA': external_ca
}
class SwarmAcceptancePolicy(DictType):
def __init__(self, role, auto_accept=False, secret=None):
self['Role'] = role.upper()
self['Autoaccept'] = auto_accept
if secret is not None:
self['Secret'] = secret
class SwarmExternalCA(DictType):
def __init__(self, url, protocol=None, options=None):
self['URL'] = url
self['Protocol'] = protocol
self['Options'] = options
import docker
import pytest
from ..base import requires_api_version
from .. import helpers
BUSYBOX = helpers.BUSYBOX
class SwarmTest(helpers.BaseTestCase):
def setUp(self):
super(SwarmTest, self).setUp()
try:
self.client.leave_swarm(force=True)
except docker.errors.APIError:
pass
def tearDown(self):
super(SwarmTest, self).tearDown()
try:
self.client.leave_swarm(force=True)
except docker.errors.APIError:
pass
@requires_api_version('1.24')
def test_init_swarm_simple(self):
assert self.client.init_swarm('eth0')
@requires_api_version('1.24')
def test_init_swarm_force_new_cluster(self):
pytest.skip('Test stalls the engine on 1.12')
assert self.client.init_swarm('eth0')
version_1 = self.client.inspect_swarm()['Version']['Index']
assert self.client.init_swarm('eth0', force_new_cluster=True)
version_2 = self.client.inspect_swarm()['Version']['Index']
assert version_2 != version_1
@requires_api_version('1.24')
def test_init_already_in_cluster(self):
assert self.client.init_swarm('eth0')
with pytest.raises(docker.errors.APIError):
self.client.init_swarm('eth0')
@requires_api_version('1.24')
def test_leave_swarm(self):
assert self.client.init_swarm('eth0')
with pytest.raises(docker.errors.APIError) as exc_info:
self.client.leave_swarm()
exc_info.value.response.status_code == 500
assert self.client.leave_swarm(force=True)
with pytest.raises(docker.errors.APIError) as exc_info:
self.client.inspect_swarm()
exc_info.value.response.status_code == 406
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