Skip to content

Commit 91e9258

Browse files
committed
Add support for RollbackConfig
Signed-off-by: Joffrey F <[email protected]>
1 parent e4b509e commit 91e9258

File tree

5 files changed

+78
-7
lines changed

5 files changed

+78
-7
lines changed

docker/api/service.py

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
from ..types import ServiceMode
33

44

5-
def _check_api_features(version, task_template, update_config, endpoint_spec):
5+
def _check_api_features(version, task_template, update_config, endpoint_spec,
6+
rollback_config):
67

78
def raise_version_error(param, min_version):
89
raise errors.InvalidVersion(
@@ -28,6 +29,14 @@ def raise_version_error(param, min_version):
2829
if 'Order' in update_config:
2930
raise_version_error('UpdateConfig.order', '1.29')
3031

32+
if rollback_config is not None:
33+
if utils.version_lt(version, '1.28'):
34+
raise_version_error('rollback_config', '1.28')
35+
36+
if utils.version_lt(version, '1.29'):
37+
if 'Order' in update_config:
38+
raise_version_error('RollbackConfig.order', '1.29')
39+
3140
if endpoint_spec is not None:
3241
if utils.version_lt(version, '1.32') and 'Ports' in endpoint_spec:
3342
if any(p.get('PublishMode') for p in endpoint_spec['Ports']):
@@ -105,7 +114,7 @@ class ServiceApiMixin(object):
105114
def create_service(
106115
self, task_template, name=None, labels=None, mode=None,
107116
update_config=None, networks=None, endpoint_config=None,
108-
endpoint_spec=None
117+
endpoint_spec=None, rollback_config=None
109118
):
110119
"""
111120
Create a service.
@@ -120,6 +129,8 @@ def create_service(
120129
or global). Defaults to replicated.
121130
update_config (UpdateConfig): Specification for the update strategy
122131
of the service. Default: ``None``
132+
rollback_config (RollbackConfig): Specification for the rollback
133+
strategy of the service. Default: ``None``
123134
networks (:py:class:`list`): List of network names or IDs to attach
124135
the service to. Default: ``None``.
125136
endpoint_spec (EndpointSpec): Properties that can be configured to
@@ -135,7 +146,8 @@ def create_service(
135146
"""
136147

137148
_check_api_features(
138-
self._version, task_template, update_config, endpoint_spec
149+
self._version, task_template, update_config, endpoint_spec,
150+
rollback_config
139151
)
140152

141153
url = self._url('/services/create')
@@ -166,6 +178,9 @@ def create_service(
166178
if update_config is not None:
167179
data['UpdateConfig'] = update_config
168180

181+
if rollback_config is not None:
182+
data['RollbackConfig'] = rollback_config
183+
169184
return self._result(
170185
self._post_json(url, data=data, headers=headers), True
171186
)
@@ -342,7 +357,8 @@ def tasks(self, filters=None):
342357
def update_service(self, service, version, task_template=None, name=None,
343358
labels=None, mode=None, update_config=None,
344359
networks=None, endpoint_config=None,
345-
endpoint_spec=None, fetch_current_spec=False):
360+
endpoint_spec=None, fetch_current_spec=False,
361+
rollback_config=None):
346362
"""
347363
Update a service.
348364
@@ -360,6 +376,8 @@ def update_service(self, service, version, task_template=None, name=None,
360376
or global). Defaults to replicated.
361377
update_config (UpdateConfig): Specification for the update strategy
362378
of the service. Default: ``None``.
379+
rollback_config (RollbackConfig): Specification for the rollback
380+
strategy of the service. Default: ``None``
363381
networks (:py:class:`list`): List of network names or IDs to attach
364382
the service to. Default: ``None``.
365383
endpoint_spec (EndpointSpec): Properties that can be configured to
@@ -376,7 +394,8 @@ def update_service(self, service, version, task_template=None, name=None,
376394
"""
377395

378396
_check_api_features(
379-
self._version, task_template, update_config, endpoint_spec
397+
self._version, task_template, update_config, endpoint_spec,
398+
rollback_config
380399
)
381400

382401
if fetch_current_spec:
@@ -422,6 +441,11 @@ def update_service(self, service, version, task_template=None, name=None,
422441
else:
423442
data['UpdateConfig'] = current.get('UpdateConfig')
424443

444+
if rollback_config is not None:
445+
data['RollbackConfig'] = rollback_config
446+
else:
447+
data['RollbackConfig'] = current.get('RollbackConfig')
448+
425449
if networks is not None:
426450
converted_networks = utils.convert_service_networks(networks)
427451
if utils.version_lt(self._version, '1.25'):

docker/models/services.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,8 @@ def create(self, image, command=None, **kwargs):
183183
containers to terminate before forcefully killing them.
184184
update_config (UpdateConfig): Specification for the update strategy
185185
of the service. Default: ``None``
186+
rollback_config (RollbackConfig): Specification for the rollback
187+
strategy of the service. Default: ``None``
186188
user (str): User to run commands as.
187189
workdir (str): Working directory for commands to run.
188190
tty (boolean): Whether a pseudo-TTY should be allocated.

docker/types/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from .networks import EndpointConfig, IPAMConfig, IPAMPool, NetworkingConfig
66
from .services import (
77
ConfigReference, ContainerSpec, DNSConfig, DriverConfig, EndpointSpec,
8-
Mount, Placement, Privileges, Resources, RestartPolicy, SecretReference,
9-
ServiceMode, TaskTemplate, UpdateConfig
8+
Mount, Placement, Privileges, Resources, RestartPolicy, RollbackConfig,
9+
SecretReference, ServiceMode, TaskTemplate, UpdateConfig
1010
)
1111
from .swarm import SwarmSpec, SwarmExternalCA

docker/types/services.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,30 @@ def __init__(self, parallelism=0, delay=None, failure_action='continue',
414414
self['Order'] = order
415415

416416

417+
class RollbackConfig(UpdateConfig):
418+
"""
419+
Used to specify the way containe rollbacks should be performed by a service
420+
421+
Args:
422+
parallelism (int): Maximum number of tasks to be rolled back in one
423+
iteration (0 means unlimited parallelism). Default: 0
424+
delay (int): Amount of time between rollbacks, in nanoseconds.
425+
failure_action (string): Action to take if a rolled back task fails to
426+
run, or stops running during the rollback. Acceptable values are
427+
``continue``, ``pause`` or ``rollback``.
428+
Default: ``continue``
429+
monitor (int): Amount of time to monitor each rolled back task for
430+
failures, in nanoseconds.
431+
max_failure_ratio (float): The fraction of tasks that may fail during
432+
a rollback before the failure action is invoked, specified as a
433+
floating point number between 0 and 1. Default: 0
434+
order (string): Specifies the order of operations when rolling out a
435+
rolled back task. Either ``start_first`` or ``stop_first`` are
436+
accepted.
437+
"""
438+
pass
439+
440+
417441
class RestartConditionTypesEnum(object):
418442
_values = (
419443
'none',

tests/integration/api_service_test.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,27 @@ def test_create_service_with_update_config_monitor(self):
312312
assert update_config['Monitor'] == uc['Monitor']
313313
assert update_config['MaxFailureRatio'] == uc['MaxFailureRatio']
314314

315+
@requires_api_version('1.28')
316+
def test_create_service_with_rollback_config(self):
317+
container_spec = docker.types.ContainerSpec(BUSYBOX, ['true'])
318+
task_tmpl = docker.types.TaskTemplate(container_spec)
319+
rollback_cfg = docker.types.RollbackConfig(
320+
parallelism=10, delay=5, failure_action='pause',
321+
monitor=300000000, max_failure_ratio=0.4
322+
)
323+
name = self.get_service_name()
324+
svc_id = self.client.create_service(
325+
task_tmpl, rollback_config=rollback_cfg, name=name
326+
)
327+
svc_info = self.client.inspect_service(svc_id)
328+
assert 'RollbackConfig' in svc_info['Spec']
329+
rc = svc_info['Spec']['RollbackConfig']
330+
assert rollback_cfg['Parallelism'] == rc['Parallelism']
331+
assert rollback_cfg['Delay'] == rc['Delay']
332+
assert rollback_cfg['FailureAction'] == rc['FailureAction']
333+
assert rollback_cfg['Monitor'] == rc['Monitor']
334+
assert rollback_cfg['MaxFailureRatio'] == rc['MaxFailureRatio']
335+
315336
def test_create_service_with_restart_policy(self):
316337
container_spec = docker.types.ContainerSpec(BUSYBOX, ['true'])
317338
policy = docker.types.RestartPolicy(

0 commit comments

Comments
 (0)