diff --git a/docker/models/services.py b/docker/models/services.py index 612f3454..7fbd1651 100644 --- a/docker/models/services.py +++ b/docker/models/services.py @@ -1,6 +1,6 @@ import copy from docker.errors import create_unexpected_kwargs_error, InvalidArgument -from docker.types import TaskTemplate, ContainerSpec, ServiceMode +from docker.types import TaskTemplate, ContainerSpec, Placement, ServiceMode from .resource import Model, Collection @@ -153,6 +153,9 @@ class ServiceCollection(Collection): command (list of str or str): Command to run. args (list of str): Arguments to the command. constraints (list of str): Placement constraints. + preferences (list of str): Placement preferences. + platforms (list of tuple): A list of platforms constraints + expressed as ``(arch, os)`` tuples container_labels (dict): Labels to apply to the container. endpoint_spec (EndpointSpec): Properties that can be configured to access and load balance a service. Default: ``None``. @@ -302,6 +305,12 @@ CREATE_SERVICE_KWARGS = [ 'endpoint_spec', ] +PLACEMENT_KWARGS = [ + 'constraints', + 'preferences', + 'platforms', +] + def _get_create_service_kwargs(func_name, kwargs): # Copy over things which can be copied directly @@ -322,13 +331,10 @@ def _get_create_service_kwargs(func_name, kwargs): container_spec_kwargs['labels'] = kwargs.pop('container_labels') placement = {} - - if 'constraints' in kwargs: - placement['Constraints'] = kwargs.pop('constraints') - - if 'preferences' in kwargs: - placement['Preferences'] = kwargs.pop('preferences') - + for key in copy.copy(kwargs): + if key in PLACEMENT_KWARGS: + placement[key] = kwargs.pop(key) + placement = Placement(**placement) task_template_kwargs['placement'] = placement if 'log_driver' in kwargs: diff --git a/tests/unit/models_services_test.py b/tests/unit/models_services_test.py index 247bb4a4..a4ac50c3 100644 --- a/tests/unit/models_services_test.py +++ b/tests/unit/models_services_test.py @@ -26,6 +26,8 @@ class CreateServiceKwargsTest(unittest.TestCase): 'mounts': [{'some': 'mounts'}], 'stop_grace_period': 5, 'constraints': ['foo=bar'], + 'preferences': ['bar=baz'], + 'platforms': [('x86_64', 'linux')], }) task_template = kwargs.pop('task_template') @@ -41,7 +43,11 @@ class CreateServiceKwargsTest(unittest.TestCase): 'ContainerSpec', 'Resources', 'RestartPolicy', 'Placement', 'LogDriver', 'Networks' ]) - assert task_template['Placement'] == {'Constraints': ['foo=bar']} + assert task_template['Placement'] == { + 'Constraints': ['foo=bar'], + 'Preferences': ['bar=baz'], + 'Platforms': [{'Architecture': 'x86_64', 'OS': 'linux'}], + } assert task_template['LogDriver'] == { 'Name': 'logdriver', 'Options': {'foo': 'bar'}