Skip to content

Commit 6e5eb2e

Browse files
committed
Update service using previous spec
Signed-off-by: Viktor Adam <[email protected]>
1 parent c7f1b5f commit 6e5eb2e

File tree

2 files changed

+357
-8
lines changed

2 files changed

+357
-8
lines changed

docker/api/service.py

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ def tasks(self, filters=None):
306306
def update_service(self, service, version, task_template=None, name=None,
307307
labels=None, mode=None, update_config=None,
308308
networks=None, endpoint_config=None,
309-
endpoint_spec=None):
309+
endpoint_spec=None, use_current_spec=False):
310310
"""
311311
Update a service.
312312
@@ -328,6 +328,8 @@ def update_service(self, service, version, task_template=None, name=None,
328328
the service to. Default: ``None``.
329329
endpoint_spec (EndpointSpec): Properties that can be configured to
330330
access and load balance a service. Default: ``None``.
331+
use_current_spec (boolean): Use the undefined settings from the
332+
previous specification of the service. Default: ``False``
331333
332334
Returns:
333335
``True`` if successful.
@@ -345,32 +347,66 @@ def update_service(self, service, version, task_template=None, name=None,
345347

346348
_check_api_features(self._version, task_template, update_config)
347349

350+
if use_current_spec:
351+
if utils.version_lt(self._version, '1.29'):
352+
inspect_defaults = None
353+
else:
354+
inspect_defaults = True
355+
current = self.inspect_service(
356+
service, insert_defaults=inspect_defaults
357+
)['Spec']
358+
359+
else:
360+
current = {}
361+
348362
url = self._url('/services/{0}/update', service)
349363
data = {}
350364
headers = {}
351-
if name is not None:
352-
data['Name'] = name
353-
if labels is not None:
354-
data['Labels'] = labels
365+
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')
368+
355369
if mode is not None:
356370
if not isinstance(mode, dict):
357371
mode = ServiceMode(mode)
358372
data['Mode'] = mode
373+
else:
374+
data['Mode'] = current.get('Mode')
375+
376+
merged_task_template = current.get('TaskTemplate', {})
359377
if task_template is not None:
360-
image = task_template.get('ContainerSpec', {}).get('Image', 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)
361387
if image is not None:
362388
registry, repo_name = auth.resolve_repository_name(image)
363389
auth_header = auth.get_config_header(self, registry)
364390
if auth_header:
365391
headers['X-Registry-Auth'] = auth_header
366-
data['TaskTemplate'] = task_template
392+
data['TaskTemplate'] = merged_task_template
393+
367394
if update_config is not None:
368395
data['UpdateConfig'] = update_config
396+
else:
397+
data['UpdateConfig'] = current.get('UpdateConfig')
369398

370399
if networks is not None:
371-
data['Networks'] = utils.convert_service_networks(networks)
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
405+
372406
if endpoint_spec is not None:
373407
data['EndpointSpec'] = endpoint_spec
408+
else:
409+
data['EndpointSpec'] = current.get('EndpointSpec')
374410

375411
resp = self._post_json(
376412
url, data=data, params={'version': version}, headers=headers

0 commit comments

Comments
 (0)