github.com/docker/docker@v299999999.0.0-20200612211812-aaf470eca7b5+incompatible/client/service_update.go (about)

     1  package client // import "github.com/docker/docker/client"
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"net/url"
     7  	"strconv"
     8  
     9  	"github.com/docker/docker/api/types"
    10  	"github.com/docker/docker/api/types/swarm"
    11  )
    12  
    13  // ServiceUpdate updates a Service. The version number is required to avoid conflicting writes.
    14  // It should be the value as set *before* the update. You can find this value in the Meta field
    15  // of swarm.Service, which can be found using ServiceInspectWithRaw.
    16  func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (types.ServiceUpdateResponse, error) {
    17  	var (
    18  		query   = url.Values{}
    19  		distErr error
    20  	)
    21  
    22  	headers := map[string][]string{
    23  		"version": {cli.version},
    24  	}
    25  
    26  	if options.EncodedRegistryAuth != "" {
    27  		headers["X-Registry-Auth"] = []string{options.EncodedRegistryAuth}
    28  	}
    29  
    30  	if options.RegistryAuthFrom != "" {
    31  		query.Set("registryAuthFrom", options.RegistryAuthFrom)
    32  	}
    33  
    34  	if options.Rollback != "" {
    35  		query.Set("rollback", options.Rollback)
    36  	}
    37  
    38  	query.Set("version", strconv.FormatUint(version.Index, 10))
    39  
    40  	if err := validateServiceSpec(service); err != nil {
    41  		return types.ServiceUpdateResponse{}, err
    42  	}
    43  
    44  	var imgPlatforms []swarm.Platform
    45  	// ensure that the image is tagged
    46  	if service.TaskTemplate.ContainerSpec != nil {
    47  		if taggedImg := imageWithTagString(service.TaskTemplate.ContainerSpec.Image); taggedImg != "" {
    48  			service.TaskTemplate.ContainerSpec.Image = taggedImg
    49  		}
    50  		if options.QueryRegistry {
    51  			var img string
    52  			img, imgPlatforms, distErr = imageDigestAndPlatforms(ctx, cli, service.TaskTemplate.ContainerSpec.Image, options.EncodedRegistryAuth)
    53  			if img != "" {
    54  				service.TaskTemplate.ContainerSpec.Image = img
    55  			}
    56  		}
    57  	}
    58  
    59  	// ensure that the image is tagged
    60  	if service.TaskTemplate.PluginSpec != nil {
    61  		if taggedImg := imageWithTagString(service.TaskTemplate.PluginSpec.Remote); taggedImg != "" {
    62  			service.TaskTemplate.PluginSpec.Remote = taggedImg
    63  		}
    64  		if options.QueryRegistry {
    65  			var img string
    66  			img, imgPlatforms, distErr = imageDigestAndPlatforms(ctx, cli, service.TaskTemplate.PluginSpec.Remote, options.EncodedRegistryAuth)
    67  			if img != "" {
    68  				service.TaskTemplate.PluginSpec.Remote = img
    69  			}
    70  		}
    71  	}
    72  
    73  	if service.TaskTemplate.Placement == nil && len(imgPlatforms) > 0 {
    74  		service.TaskTemplate.Placement = &swarm.Placement{}
    75  	}
    76  	if len(imgPlatforms) > 0 {
    77  		service.TaskTemplate.Placement.Platforms = imgPlatforms
    78  	}
    79  
    80  	var response types.ServiceUpdateResponse
    81  	resp, err := cli.post(ctx, "/services/"+serviceID+"/update", query, service, headers)
    82  	defer ensureReaderClosed(resp)
    83  	if err != nil {
    84  		return response, err
    85  	}
    86  
    87  	err = json.NewDecoder(resp.body).Decode(&response)
    88  
    89  	if distErr != nil {
    90  		response.Warnings = append(response.Warnings, digestWarning(service.TaskTemplate.ContainerSpec.Image))
    91  	}
    92  
    93  	return response, err
    94  }