Skip to content

Commit b2d08e6

Browse files
committed
Service model update changes
Signed-off-by: Viktor Adam <[email protected]>
1 parent 6e5eb2e commit b2d08e6

File tree

6 files changed

+345
-56
lines changed

6 files changed

+345
-56
lines changed

docker/api/service.py

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -363,8 +363,15 @@ def update_service(self, service, version, task_template=None, name=None,
363363
data = {}
364364
headers = {}
365365

366-
data['Name'] = name if name is not None else current.get('Name')
367-
data['Labels'] = labels if labels is not None else current.get('Labels')
366+
if name is not None:
367+
data['Name'] = name
368+
else:
369+
data['Name'] = current.get('Name')
370+
371+
if labels is not None:
372+
data['Labels'] = labels
373+
else:
374+
data['Labels'] = current.get('Labels')
368375

369376
if mode is not None:
370377
if not isinstance(mode, dict):
@@ -373,35 +380,33 @@ def update_service(self, service, version, task_template=None, name=None,
373380
else:
374381
data['Mode'] = current.get('Mode')
375382

376-
merged_task_template = current.get('TaskTemplate', {})
377-
if task_template is not None:
378-
for task_template_key, task_template_value in task_template.items():
379-
if task_template_key == 'ContainerSpec':
380-
if 'ContainerSpec' not in merged_task_template:
381-
merged_task_template['ContainerSpec'] = {}
382-
for container_spec_key, container_spec_value in task_template['ContainerSpec'].items():
383-
merged_task_template['ContainerSpec'][container_spec_key] = container_spec_value
384-
else:
385-
merged_task_template[task_template_key] = task_template_value
386-
image = merged_task_template.get('ContainerSpec', {}).get('Image', None)
387-
if image is not None:
388-
registry, repo_name = auth.resolve_repository_name(image)
389-
auth_header = auth.get_config_header(self, registry)
390-
if auth_header:
391-
headers['X-Registry-Auth'] = auth_header
392-
data['TaskTemplate'] = merged_task_template
383+
data['TaskTemplate'] = self._merge_task_template(
384+
current.get('TaskTemplate', {}), task_template
385+
)
386+
387+
container_spec = data['TaskTemplate'].get('ContainerSpec', {})
388+
image = container_spec.get('Image', None)
389+
if image is not None:
390+
registry, repo_name = auth.resolve_repository_name(image)
391+
auth_header = auth.get_config_header(self, registry)
392+
if auth_header:
393+
headers['X-Registry-Auth'] = auth_header
393394

394395
if update_config is not None:
395396
data['UpdateConfig'] = update_config
396397
else:
397398
data['UpdateConfig'] = current.get('UpdateConfig')
398399

399400
if networks is not None:
400-
data['TaskTemplate']['Networks'] = utils.convert_service_networks(networks)
401-
else:
402-
existing_networks = current.get('TaskTemplate', {}).get('Networks') or current.get('Networks')
403-
if existing_networks is not None:
404-
data['TaskTemplate']['Networks'] = existing_networks
401+
converted_networks = utils.convert_service_networks(networks)
402+
data['TaskTemplate']['Networks'] = converted_networks
403+
elif data['TaskTemplate'].get('Networks') is None:
404+
current_task_template = current.get('TaskTemplate', {})
405+
current_networks = current_task_template.get('Networks')
406+
if current_networks is None:
407+
current_networks = current.get('Networks')
408+
if current_networks is not None:
409+
data['TaskTemplate']['Networks'] = current_networks
405410

406411
if endpoint_spec is not None:
407412
data['EndpointSpec'] = endpoint_spec
@@ -413,3 +418,17 @@ def update_service(self, service, version, task_template=None, name=None,
413418
)
414419
self._raise_for_status(resp)
415420
return True
421+
422+
@staticmethod
423+
def _merge_task_template(current, override):
424+
merged = current.copy()
425+
if override is not None:
426+
for ts_key, ts_value in override.items():
427+
if ts_key == 'ContainerSpec':
428+
if 'ContainerSpec' not in merged:
429+
merged['ContainerSpec'] = {}
430+
for cs_key, cs_value in override['ContainerSpec'].items():
431+
merged['ContainerSpec'][cs_key] = cs_value
432+
else:
433+
merged[ts_key] = ts_value
434+
return merged

docker/models/services.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ def list(self, **kwargs):
251251

252252
# kwargs to copy straight over to TaskTemplate
253253
TASK_TEMPLATE_KWARGS = [
254+
'networks',
254255
'resources',
255256
'restart_policy',
256257
]
@@ -261,7 +262,6 @@ def list(self, **kwargs):
261262
'labels',
262263
'mode',
263264
'update_config',
264-
'networks',
265265
'endpoint_spec',
266266
]
267267

@@ -295,6 +295,15 @@ def _get_create_service_kwargs(func_name, kwargs):
295295
'Options': kwargs.pop('log_driver_options', {})
296296
}
297297

298+
if func_name == 'update':
299+
if 'force_update' in kwargs:
300+
task_template_kwargs['force_update'] = kwargs.pop('force_update')
301+
302+
# use the current spec by default if updating the service
303+
# through the model
304+
use_current_spec = kwargs.pop('use_current_spec', True)
305+
create_kwargs['use_current_spec'] = use_current_spec
306+
298307
# All kwargs should have been consumed by this point, so raise
299308
# error if any are left
300309
if kwargs:

docker/types/services.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from ..constants import IS_WINDOWS_PLATFORM
55
from ..utils import (
66
check_resource, format_environment, format_extra_hosts, parse_bytes,
7-
split_command,
7+
split_command, convert_service_networks,
88
)
99

1010

@@ -26,11 +26,14 @@ class TaskTemplate(dict):
2626
placement (Placement): Placement instructions for the scheduler.
2727
If a list is passed instead, it is assumed to be a list of
2828
constraints as part of a :py:class:`Placement` object.
29+
networks (:py:class:`list`): List of network names or IDs to attach
30+
the containers to.
2931
force_update (int): A counter that triggers an update even if no
3032
relevant parameters have been changed.
3133
"""
3234
def __init__(self, container_spec, resources=None, restart_policy=None,
33-
placement=None, log_driver=None, force_update=None):
35+
placement=None, log_driver=None, networks=None,
36+
force_update=None):
3437
self['ContainerSpec'] = container_spec
3538
if resources:
3639
self['Resources'] = resources
@@ -42,6 +45,8 @@ def __init__(self, container_spec, resources=None, restart_policy=None,
4245
self['Placement'] = placement
4346
if log_driver:
4447
self['LogDriver'] = log_driver
48+
if networks:
49+
self['Networks'] = convert_service_networks(networks)
4550

4651
if force_update is not None:
4752
if not isinstance(force_update, int):

0 commit comments

Comments
 (0)