service_update.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package client
  2. import (
  3. "encoding/json"
  4. "net/url"
  5. "strconv"
  6. "github.com/docker/docker/api/types"
  7. "github.com/docker/docker/api/types/swarm"
  8. "golang.org/x/net/context"
  9. )
  10. // ServiceUpdate updates a Service.
  11. func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (types.ServiceUpdateResponse, error) {
  12. var (
  13. query = url.Values{}
  14. distErr error
  15. )
  16. headers := map[string][]string{
  17. "version": {cli.version},
  18. }
  19. if options.EncodedRegistryAuth != "" {
  20. headers["X-Registry-Auth"] = []string{options.EncodedRegistryAuth}
  21. }
  22. if options.RegistryAuthFrom != "" {
  23. query.Set("registryAuthFrom", options.RegistryAuthFrom)
  24. }
  25. if options.Rollback != "" {
  26. query.Set("rollback", options.Rollback)
  27. }
  28. query.Set("version", strconv.FormatUint(version.Index, 10))
  29. // ensure that the image is tagged
  30. if taggedImg := imageWithTagString(service.TaskTemplate.ContainerSpec.Image); taggedImg != "" {
  31. service.TaskTemplate.ContainerSpec.Image = taggedImg
  32. }
  33. // Contact the registry to retrieve digest and platform information
  34. // This happens only when the image has changed
  35. if options.QueryRegistry {
  36. distributionInspect, err := cli.DistributionInspect(ctx, service.TaskTemplate.ContainerSpec.Image, options.EncodedRegistryAuth)
  37. distErr = err
  38. if err == nil {
  39. // now pin by digest if the image doesn't already contain a digest
  40. if img := imageWithDigestString(service.TaskTemplate.ContainerSpec.Image, distributionInspect.Descriptor.Digest); img != "" {
  41. service.TaskTemplate.ContainerSpec.Image = img
  42. }
  43. // add platforms that are compatible with the service
  44. service.TaskTemplate.Placement = updateServicePlatforms(service.TaskTemplate.Placement, distributionInspect)
  45. }
  46. }
  47. var response types.ServiceUpdateResponse
  48. resp, err := cli.post(ctx, "/services/"+serviceID+"/update", query, service, headers)
  49. if err != nil {
  50. return response, err
  51. }
  52. err = json.NewDecoder(resp.body).Decode(&response)
  53. if distErr != nil {
  54. response.Warnings = append(response.Warnings, digestWarning(service.TaskTemplate.ContainerSpec.Image))
  55. }
  56. ensureReaderClosed(resp)
  57. return response, err
  58. }