@@ -306,7 +306,7 @@ def tasks(self, filters=None):
306
306
def update_service (self , service , version , task_template = None , name = None ,
307
307
labels = None , mode = None , update_config = None ,
308
308
networks = None , endpoint_config = None ,
309
- endpoint_spec = None ):
309
+ endpoint_spec = None , use_current_spec = False ):
310
310
"""
311
311
Update a service.
312
312
@@ -328,6 +328,8 @@ def update_service(self, service, version, task_template=None, name=None,
328
328
the service to. Default: ``None``.
329
329
endpoint_spec (EndpointSpec): Properties that can be configured to
330
330
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``
331
333
332
334
Returns:
333
335
``True`` if successful.
@@ -345,32 +347,66 @@ def update_service(self, service, version, task_template=None, name=None,
345
347
346
348
_check_api_features (self ._version , task_template , update_config )
347
349
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
+
348
362
url = self ._url ('/services/{0}/update' , service )
349
363
data = {}
350
364
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
+
355
369
if mode is not None :
356
370
if not isinstance (mode , dict ):
357
371
mode = ServiceMode (mode )
358
372
data ['Mode' ] = mode
373
+ else :
374
+ data ['Mode' ] = current .get ('Mode' )
375
+
376
+ merged_task_template = current .get ('TaskTemplate' , {})
359
377
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 )
361
387
if image is not None :
362
388
registry , repo_name = auth .resolve_repository_name (image )
363
389
auth_header = auth .get_config_header (self , registry )
364
390
if auth_header :
365
391
headers ['X-Registry-Auth' ] = auth_header
366
- data ['TaskTemplate' ] = task_template
392
+ data ['TaskTemplate' ] = merged_task_template
393
+
367
394
if update_config is not None :
368
395
data ['UpdateConfig' ] = update_config
396
+ else :
397
+ data ['UpdateConfig' ] = current .get ('UpdateConfig' )
369
398
370
399
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
+
372
406
if endpoint_spec is not None :
373
407
data ['EndpointSpec' ] = endpoint_spec
408
+ else :
409
+ data ['EndpointSpec' ] = current .get ('EndpointSpec' )
374
410
375
411
resp = self ._post_json (
376
412
url , data = data , params = {'version' : version }, headers = headers
0 commit comments