ServiceCreate creates a new service.
(ctx context.Context, options ServiceCreateOptions)
| 42 | |
| 43 | // ServiceCreate creates a new service. |
| 44 | func (cli *Client) ServiceCreate(ctx context.Context, options ServiceCreateOptions) (ServiceCreateResult, error) { |
| 45 | // Make sure containerSpec is not nil when no runtime is set or the runtime is set to container |
| 46 | if options.Spec.TaskTemplate.ContainerSpec == nil && (options.Spec.TaskTemplate.Runtime == "" || options.Spec.TaskTemplate.Runtime == swarm.RuntimeContainer) { |
| 47 | options.Spec.TaskTemplate.ContainerSpec = &swarm.ContainerSpec{} |
| 48 | } |
| 49 | |
| 50 | if err := validateServiceSpec(options.Spec); err != nil { |
| 51 | return ServiceCreateResult{}, err |
| 52 | } |
| 53 | |
| 54 | // ensure that the image is tagged |
| 55 | var warnings []string |
| 56 | switch { |
| 57 | case options.Spec.TaskTemplate.ContainerSpec != nil: |
| 58 | if taggedImg := imageWithTagString(options.Spec.TaskTemplate.ContainerSpec.Image); taggedImg != "" { |
| 59 | options.Spec.TaskTemplate.ContainerSpec.Image = taggedImg |
| 60 | } |
| 61 | if options.QueryRegistry { |
| 62 | if warning := resolveContainerSpecImage(ctx, cli, &options.Spec.TaskTemplate, options.EncodedRegistryAuth); warning != "" { |
| 63 | warnings = append(warnings, warning) |
| 64 | } |
| 65 | } |
| 66 | case options.Spec.TaskTemplate.PluginSpec != nil: |
| 67 | if taggedImg := imageWithTagString(options.Spec.TaskTemplate.PluginSpec.Remote); taggedImg != "" { |
| 68 | options.Spec.TaskTemplate.PluginSpec.Remote = taggedImg |
| 69 | } |
| 70 | if options.QueryRegistry { |
| 71 | if warning := resolvePluginSpecRemote(ctx, cli, &options.Spec.TaskTemplate, options.EncodedRegistryAuth); warning != "" { |
| 72 | warnings = append(warnings, warning) |
| 73 | } |
| 74 | } |
| 75 | } |
| 76 | |
| 77 | headers := http.Header{} |
| 78 | if options.EncodedRegistryAuth != "" { |
| 79 | headers[registry.AuthHeader] = []string{options.EncodedRegistryAuth} |
| 80 | } |
| 81 | resp, err := cli.post(ctx, "/services/create", nil, options.Spec, headers) |
| 82 | defer ensureReaderClosed(resp) |
| 83 | if err != nil { |
| 84 | return ServiceCreateResult{}, err |
| 85 | } |
| 86 | |
| 87 | var response swarm.ServiceCreateResponse |
| 88 | err = json.NewDecoder(resp.Body).Decode(&response) |
| 89 | warnings = append(warnings, response.Warnings...) |
| 90 | |
| 91 | return ServiceCreateResult{ |
| 92 | ID: response.ID, |
| 93 | Warnings: warnings, |
| 94 | }, err |
| 95 | } |
| 96 | |
| 97 | func resolveContainerSpecImage(ctx context.Context, cli DistributionAPIClient, taskSpec *swarm.TaskSpec, encodedAuth string) string { |
| 98 | img, imgPlatforms, err := imageDigestAndPlatforms(ctx, cli, taskSpec.ContainerSpec.Image, encodedAuth) |
nothing calls this directly
no test coverage detected