mirror of https://github.com/docker/docker-py.git
Merge pull request #2109 from docker/rollback_config
Add support for RollbackConfig
This commit is contained in:
commit
c4a1134e95
|
@ -2,7 +2,8 @@ from .. import auth, errors, utils
|
||||||
from ..types import ServiceMode
|
from ..types import ServiceMode
|
||||||
|
|
||||||
|
|
||||||
def _check_api_features(version, task_template, update_config, endpoint_spec):
|
def _check_api_features(version, task_template, update_config, endpoint_spec,
|
||||||
|
rollback_config):
|
||||||
|
|
||||||
def raise_version_error(param, min_version):
|
def raise_version_error(param, min_version):
|
||||||
raise errors.InvalidVersion(
|
raise errors.InvalidVersion(
|
||||||
|
@ -28,6 +29,14 @@ def _check_api_features(version, task_template, update_config, endpoint_spec):
|
||||||
if 'Order' in update_config:
|
if 'Order' in update_config:
|
||||||
raise_version_error('UpdateConfig.order', '1.29')
|
raise_version_error('UpdateConfig.order', '1.29')
|
||||||
|
|
||||||
|
if rollback_config is not None:
|
||||||
|
if utils.version_lt(version, '1.28'):
|
||||||
|
raise_version_error('rollback_config', '1.28')
|
||||||
|
|
||||||
|
if utils.version_lt(version, '1.29'):
|
||||||
|
if 'Order' in update_config:
|
||||||
|
raise_version_error('RollbackConfig.order', '1.29')
|
||||||
|
|
||||||
if endpoint_spec is not None:
|
if endpoint_spec is not None:
|
||||||
if utils.version_lt(version, '1.32') and 'Ports' in endpoint_spec:
|
if utils.version_lt(version, '1.32') and 'Ports' in endpoint_spec:
|
||||||
if any(p.get('PublishMode') for p in endpoint_spec['Ports']):
|
if any(p.get('PublishMode') for p in endpoint_spec['Ports']):
|
||||||
|
@ -105,7 +114,7 @@ class ServiceApiMixin(object):
|
||||||
def create_service(
|
def create_service(
|
||||||
self, task_template, name=None, labels=None, mode=None,
|
self, task_template, name=None, labels=None, mode=None,
|
||||||
update_config=None, networks=None, endpoint_config=None,
|
update_config=None, networks=None, endpoint_config=None,
|
||||||
endpoint_spec=None
|
endpoint_spec=None, rollback_config=None
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Create a service.
|
Create a service.
|
||||||
|
@ -120,6 +129,8 @@ class ServiceApiMixin(object):
|
||||||
or global). Defaults to replicated.
|
or global). Defaults to replicated.
|
||||||
update_config (UpdateConfig): Specification for the update strategy
|
update_config (UpdateConfig): Specification for the update strategy
|
||||||
of the service. Default: ``None``
|
of the service. Default: ``None``
|
||||||
|
rollback_config (RollbackConfig): Specification for the rollback
|
||||||
|
strategy of the service. Default: ``None``
|
||||||
networks (:py:class:`list`): List of network names or IDs to attach
|
networks (:py:class:`list`): List of network names or IDs to attach
|
||||||
the service to. Default: ``None``.
|
the service to. Default: ``None``.
|
||||||
endpoint_spec (EndpointSpec): Properties that can be configured to
|
endpoint_spec (EndpointSpec): Properties that can be configured to
|
||||||
|
@ -135,7 +146,8 @@ class ServiceApiMixin(object):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_check_api_features(
|
_check_api_features(
|
||||||
self._version, task_template, update_config, endpoint_spec
|
self._version, task_template, update_config, endpoint_spec,
|
||||||
|
rollback_config
|
||||||
)
|
)
|
||||||
|
|
||||||
url = self._url('/services/create')
|
url = self._url('/services/create')
|
||||||
|
@ -166,6 +178,9 @@ class ServiceApiMixin(object):
|
||||||
if update_config is not None:
|
if update_config is not None:
|
||||||
data['UpdateConfig'] = update_config
|
data['UpdateConfig'] = update_config
|
||||||
|
|
||||||
|
if rollback_config is not None:
|
||||||
|
data['RollbackConfig'] = rollback_config
|
||||||
|
|
||||||
return self._result(
|
return self._result(
|
||||||
self._post_json(url, data=data, headers=headers), True
|
self._post_json(url, data=data, headers=headers), True
|
||||||
)
|
)
|
||||||
|
@ -342,7 +357,8 @@ class ServiceApiMixin(object):
|
||||||
def update_service(self, service, version, task_template=None, name=None,
|
def update_service(self, service, version, task_template=None, name=None,
|
||||||
labels=None, mode=None, update_config=None,
|
labels=None, mode=None, update_config=None,
|
||||||
networks=None, endpoint_config=None,
|
networks=None, endpoint_config=None,
|
||||||
endpoint_spec=None, fetch_current_spec=False):
|
endpoint_spec=None, fetch_current_spec=False,
|
||||||
|
rollback_config=None):
|
||||||
"""
|
"""
|
||||||
Update a service.
|
Update a service.
|
||||||
|
|
||||||
|
@ -360,6 +376,8 @@ class ServiceApiMixin(object):
|
||||||
or global). Defaults to replicated.
|
or global). Defaults to replicated.
|
||||||
update_config (UpdateConfig): Specification for the update strategy
|
update_config (UpdateConfig): Specification for the update strategy
|
||||||
of the service. Default: ``None``.
|
of the service. Default: ``None``.
|
||||||
|
rollback_config (RollbackConfig): Specification for the rollback
|
||||||
|
strategy of the service. Default: ``None``
|
||||||
networks (:py:class:`list`): List of network names or IDs to attach
|
networks (:py:class:`list`): List of network names or IDs to attach
|
||||||
the service to. Default: ``None``.
|
the service to. Default: ``None``.
|
||||||
endpoint_spec (EndpointSpec): Properties that can be configured to
|
endpoint_spec (EndpointSpec): Properties that can be configured to
|
||||||
|
@ -376,7 +394,8 @@ class ServiceApiMixin(object):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_check_api_features(
|
_check_api_features(
|
||||||
self._version, task_template, update_config, endpoint_spec
|
self._version, task_template, update_config, endpoint_spec,
|
||||||
|
rollback_config
|
||||||
)
|
)
|
||||||
|
|
||||||
if fetch_current_spec:
|
if fetch_current_spec:
|
||||||
|
@ -422,6 +441,11 @@ class ServiceApiMixin(object):
|
||||||
else:
|
else:
|
||||||
data['UpdateConfig'] = current.get('UpdateConfig')
|
data['UpdateConfig'] = current.get('UpdateConfig')
|
||||||
|
|
||||||
|
if rollback_config is not None:
|
||||||
|
data['RollbackConfig'] = rollback_config
|
||||||
|
else:
|
||||||
|
data['RollbackConfig'] = current.get('RollbackConfig')
|
||||||
|
|
||||||
if networks is not None:
|
if networks is not None:
|
||||||
converted_networks = utils.convert_service_networks(networks)
|
converted_networks = utils.convert_service_networks(networks)
|
||||||
if utils.version_lt(self._version, '1.25'):
|
if utils.version_lt(self._version, '1.25'):
|
||||||
|
|
|
@ -183,6 +183,8 @@ class ServiceCollection(Collection):
|
||||||
containers to terminate before forcefully killing them.
|
containers to terminate before forcefully killing them.
|
||||||
update_config (UpdateConfig): Specification for the update strategy
|
update_config (UpdateConfig): Specification for the update strategy
|
||||||
of the service. Default: ``None``
|
of the service. Default: ``None``
|
||||||
|
rollback_config (RollbackConfig): Specification for the rollback
|
||||||
|
strategy of the service. Default: ``None``
|
||||||
user (str): User to run commands as.
|
user (str): User to run commands as.
|
||||||
workdir (str): Working directory for commands to run.
|
workdir (str): Working directory for commands to run.
|
||||||
tty (boolean): Whether a pseudo-TTY should be allocated.
|
tty (boolean): Whether a pseudo-TTY should be allocated.
|
||||||
|
|
|
@ -5,7 +5,7 @@ from .healthcheck import Healthcheck
|
||||||
from .networks import EndpointConfig, IPAMConfig, IPAMPool, NetworkingConfig
|
from .networks import EndpointConfig, IPAMConfig, IPAMPool, NetworkingConfig
|
||||||
from .services import (
|
from .services import (
|
||||||
ConfigReference, ContainerSpec, DNSConfig, DriverConfig, EndpointSpec,
|
ConfigReference, ContainerSpec, DNSConfig, DriverConfig, EndpointSpec,
|
||||||
Mount, Placement, Privileges, Resources, RestartPolicy, SecretReference,
|
Mount, Placement, Privileges, Resources, RestartPolicy, RollbackConfig,
|
||||||
ServiceMode, TaskTemplate, UpdateConfig
|
SecretReference, ServiceMode, TaskTemplate, UpdateConfig
|
||||||
)
|
)
|
||||||
from .swarm import SwarmSpec, SwarmExternalCA
|
from .swarm import SwarmSpec, SwarmExternalCA
|
||||||
|
|
|
@ -414,6 +414,30 @@ class UpdateConfig(dict):
|
||||||
self['Order'] = order
|
self['Order'] = order
|
||||||
|
|
||||||
|
|
||||||
|
class RollbackConfig(UpdateConfig):
|
||||||
|
"""
|
||||||
|
Used to specify the way containe rollbacks should be performed by a service
|
||||||
|
|
||||||
|
Args:
|
||||||
|
parallelism (int): Maximum number of tasks to be rolled back in one
|
||||||
|
iteration (0 means unlimited parallelism). Default: 0
|
||||||
|
delay (int): Amount of time between rollbacks, in nanoseconds.
|
||||||
|
failure_action (string): Action to take if a rolled back task fails to
|
||||||
|
run, or stops running during the rollback. Acceptable values are
|
||||||
|
``continue``, ``pause`` or ``rollback``.
|
||||||
|
Default: ``continue``
|
||||||
|
monitor (int): Amount of time to monitor each rolled back task for
|
||||||
|
failures, in nanoseconds.
|
||||||
|
max_failure_ratio (float): The fraction of tasks that may fail during
|
||||||
|
a rollback before the failure action is invoked, specified as a
|
||||||
|
floating point number between 0 and 1. Default: 0
|
||||||
|
order (string): Specifies the order of operations when rolling out a
|
||||||
|
rolled back task. Either ``start_first`` or ``stop_first`` are
|
||||||
|
accepted.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class RestartConditionTypesEnum(object):
|
class RestartConditionTypesEnum(object):
|
||||||
_values = (
|
_values = (
|
||||||
'none',
|
'none',
|
||||||
|
|
|
@ -312,6 +312,27 @@ class ServiceTest(BaseAPIIntegrationTest):
|
||||||
assert update_config['Monitor'] == uc['Monitor']
|
assert update_config['Monitor'] == uc['Monitor']
|
||||||
assert update_config['MaxFailureRatio'] == uc['MaxFailureRatio']
|
assert update_config['MaxFailureRatio'] == uc['MaxFailureRatio']
|
||||||
|
|
||||||
|
@requires_api_version('1.28')
|
||||||
|
def test_create_service_with_rollback_config(self):
|
||||||
|
container_spec = docker.types.ContainerSpec(BUSYBOX, ['true'])
|
||||||
|
task_tmpl = docker.types.TaskTemplate(container_spec)
|
||||||
|
rollback_cfg = docker.types.RollbackConfig(
|
||||||
|
parallelism=10, delay=5, failure_action='pause',
|
||||||
|
monitor=300000000, max_failure_ratio=0.4
|
||||||
|
)
|
||||||
|
name = self.get_service_name()
|
||||||
|
svc_id = self.client.create_service(
|
||||||
|
task_tmpl, rollback_config=rollback_cfg, name=name
|
||||||
|
)
|
||||||
|
svc_info = self.client.inspect_service(svc_id)
|
||||||
|
assert 'RollbackConfig' in svc_info['Spec']
|
||||||
|
rc = svc_info['Spec']['RollbackConfig']
|
||||||
|
assert rollback_cfg['Parallelism'] == rc['Parallelism']
|
||||||
|
assert rollback_cfg['Delay'] == rc['Delay']
|
||||||
|
assert rollback_cfg['FailureAction'] == rc['FailureAction']
|
||||||
|
assert rollback_cfg['Monitor'] == rc['Monitor']
|
||||||
|
assert rollback_cfg['MaxFailureRatio'] == rc['MaxFailureRatio']
|
||||||
|
|
||||||
def test_create_service_with_restart_policy(self):
|
def test_create_service_with_restart_policy(self):
|
||||||
container_spec = docker.types.ContainerSpec(BUSYBOX, ['true'])
|
container_spec = docker.types.ContainerSpec(BUSYBOX, ['true'])
|
||||||
policy = docker.types.RestartPolicy(
|
policy = docker.types.RestartPolicy(
|
||||||
|
|
Loading…
Reference in New Issue