mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #40826 from thaJeztah/cleanup_service
ServiceCreate/ServiceUpdate: refactor and fix potential NPE
This commit is contained in:
commit
ca689bfd8d
2 changed files with 55 additions and 62 deletions
|
@ -15,8 +15,7 @@ import (
|
||||||
|
|
||||||
// ServiceCreate creates a new Service.
|
// ServiceCreate creates a new Service.
|
||||||
func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec, options types.ServiceCreateOptions) (types.ServiceCreateResponse, error) {
|
func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec, options types.ServiceCreateOptions) (types.ServiceCreateResponse, error) {
|
||||||
var distErr error
|
var response types.ServiceCreateResponse
|
||||||
|
|
||||||
headers := map[string][]string{
|
headers := map[string][]string{
|
||||||
"version": {cli.version},
|
"version": {cli.version},
|
||||||
}
|
}
|
||||||
|
@ -31,46 +30,28 @@ func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := validateServiceSpec(service); err != nil {
|
if err := validateServiceSpec(service); err != nil {
|
||||||
return types.ServiceCreateResponse{}, err
|
return response, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensure that the image is tagged
|
// ensure that the image is tagged
|
||||||
var imgPlatforms []swarm.Platform
|
var resolveWarning string
|
||||||
if service.TaskTemplate.ContainerSpec != nil {
|
switch {
|
||||||
|
case service.TaskTemplate.ContainerSpec != nil:
|
||||||
if taggedImg := imageWithTagString(service.TaskTemplate.ContainerSpec.Image); taggedImg != "" {
|
if taggedImg := imageWithTagString(service.TaskTemplate.ContainerSpec.Image); taggedImg != "" {
|
||||||
service.TaskTemplate.ContainerSpec.Image = taggedImg
|
service.TaskTemplate.ContainerSpec.Image = taggedImg
|
||||||
}
|
}
|
||||||
if options.QueryRegistry {
|
if options.QueryRegistry {
|
||||||
var img string
|
resolveWarning = resolveContainerSpecImage(ctx, cli, &service.TaskTemplate, options.EncodedRegistryAuth)
|
||||||
img, imgPlatforms, distErr = imageDigestAndPlatforms(ctx, cli, service.TaskTemplate.ContainerSpec.Image, options.EncodedRegistryAuth)
|
|
||||||
if img != "" {
|
|
||||||
service.TaskTemplate.ContainerSpec.Image = img
|
|
||||||
}
|
}
|
||||||
}
|
case service.TaskTemplate.PluginSpec != nil:
|
||||||
}
|
|
||||||
|
|
||||||
// ensure that the image is tagged
|
|
||||||
if service.TaskTemplate.PluginSpec != nil {
|
|
||||||
if taggedImg := imageWithTagString(service.TaskTemplate.PluginSpec.Remote); taggedImg != "" {
|
if taggedImg := imageWithTagString(service.TaskTemplate.PluginSpec.Remote); taggedImg != "" {
|
||||||
service.TaskTemplate.PluginSpec.Remote = taggedImg
|
service.TaskTemplate.PluginSpec.Remote = taggedImg
|
||||||
}
|
}
|
||||||
if options.QueryRegistry {
|
if options.QueryRegistry {
|
||||||
var img string
|
resolveWarning = resolvePluginSpecRemote(ctx, cli, &service.TaskTemplate, options.EncodedRegistryAuth)
|
||||||
img, imgPlatforms, distErr = imageDigestAndPlatforms(ctx, cli, service.TaskTemplate.PluginSpec.Remote, options.EncodedRegistryAuth)
|
|
||||||
if img != "" {
|
|
||||||
service.TaskTemplate.PluginSpec.Remote = img
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if service.TaskTemplate.Placement == nil && len(imgPlatforms) > 0 {
|
|
||||||
service.TaskTemplate.Placement = &swarm.Placement{}
|
|
||||||
}
|
|
||||||
if len(imgPlatforms) > 0 {
|
|
||||||
service.TaskTemplate.Placement.Platforms = imgPlatforms
|
|
||||||
}
|
|
||||||
|
|
||||||
var response types.ServiceCreateResponse
|
|
||||||
resp, err := cli.post(ctx, "/services/create", nil, service, headers)
|
resp, err := cli.post(ctx, "/services/create", nil, service, headers)
|
||||||
defer ensureReaderClosed(resp)
|
defer ensureReaderClosed(resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -78,14 +59,45 @@ func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec,
|
||||||
}
|
}
|
||||||
|
|
||||||
err = json.NewDecoder(resp.body).Decode(&response)
|
err = json.NewDecoder(resp.body).Decode(&response)
|
||||||
|
if resolveWarning != "" {
|
||||||
if distErr != nil {
|
response.Warnings = append(response.Warnings, resolveWarning)
|
||||||
response.Warnings = append(response.Warnings, digestWarning(service.TaskTemplate.ContainerSpec.Image))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return response, err
|
return response, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func resolveContainerSpecImage(ctx context.Context, cli DistributionAPIClient, taskSpec *swarm.TaskSpec, encodedAuth string) string {
|
||||||
|
var warning string
|
||||||
|
if img, imgPlatforms, err := imageDigestAndPlatforms(ctx, cli, taskSpec.ContainerSpec.Image, encodedAuth); err != nil {
|
||||||
|
warning = digestWarning(taskSpec.ContainerSpec.Image)
|
||||||
|
} else {
|
||||||
|
taskSpec.ContainerSpec.Image = img
|
||||||
|
if len(imgPlatforms) > 0 {
|
||||||
|
if taskSpec.Placement == nil {
|
||||||
|
taskSpec.Placement = &swarm.Placement{}
|
||||||
|
}
|
||||||
|
taskSpec.Placement.Platforms = imgPlatforms
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return warning
|
||||||
|
}
|
||||||
|
|
||||||
|
func resolvePluginSpecRemote(ctx context.Context, cli DistributionAPIClient, taskSpec *swarm.TaskSpec, encodedAuth string) string {
|
||||||
|
var warning string
|
||||||
|
if img, imgPlatforms, err := imageDigestAndPlatforms(ctx, cli, taskSpec.PluginSpec.Remote, encodedAuth); err != nil {
|
||||||
|
warning = digestWarning(taskSpec.PluginSpec.Remote)
|
||||||
|
} else {
|
||||||
|
taskSpec.PluginSpec.Remote = img
|
||||||
|
if len(imgPlatforms) > 0 {
|
||||||
|
if taskSpec.Placement == nil {
|
||||||
|
taskSpec.Placement = &swarm.Placement{}
|
||||||
|
}
|
||||||
|
taskSpec.Placement.Platforms = imgPlatforms
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return warning
|
||||||
|
}
|
||||||
|
|
||||||
func imageDigestAndPlatforms(ctx context.Context, cli DistributionAPIClient, image, encodedAuth string) (string, []swarm.Platform, error) {
|
func imageDigestAndPlatforms(ctx context.Context, cli DistributionAPIClient, image, encodedAuth string) (string, []swarm.Platform, error) {
|
||||||
distributionInspect, err := cli.DistributionInspect(ctx, image, encodedAuth)
|
distributionInspect, err := cli.DistributionInspect(ctx, image, encodedAuth)
|
||||||
var platforms []swarm.Platform
|
var platforms []swarm.Platform
|
||||||
|
@ -119,7 +131,7 @@ func imageDigestAndPlatforms(ctx context.Context, cli DistributionAPIClient, ima
|
||||||
|
|
||||||
// imageWithDigestString takes an image string and a digest, and updates
|
// imageWithDigestString takes an image string and a digest, and updates
|
||||||
// the image string if it didn't originally contain a digest. It returns
|
// the image string if it didn't originally contain a digest. It returns
|
||||||
// an empty string if there are no updates.
|
// image unmodified in other situations.
|
||||||
func imageWithDigestString(image string, dgst digest.Digest) string {
|
func imageWithDigestString(image string, dgst digest.Digest) string {
|
||||||
namedRef, err := reference.ParseNormalizedNamed(image)
|
namedRef, err := reference.ParseNormalizedNamed(image)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -131,7 +143,7 @@ func imageWithDigestString(image string, dgst digest.Digest) string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ""
|
return image
|
||||||
}
|
}
|
||||||
|
|
||||||
// imageWithTagString takes an image string, and returns a tagged image
|
// imageWithTagString takes an image string, and returns a tagged image
|
||||||
|
|
|
@ -16,7 +16,7 @@ import (
|
||||||
func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (types.ServiceUpdateResponse, error) {
|
func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (types.ServiceUpdateResponse, error) {
|
||||||
var (
|
var (
|
||||||
query = url.Values{}
|
query = url.Values{}
|
||||||
distErr error
|
response = types.ServiceUpdateResponse{}
|
||||||
)
|
)
|
||||||
|
|
||||||
headers := map[string][]string{
|
headers := map[string][]string{
|
||||||
|
@ -38,46 +38,28 @@ func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version
|
||||||
query.Set("version", strconv.FormatUint(version.Index, 10))
|
query.Set("version", strconv.FormatUint(version.Index, 10))
|
||||||
|
|
||||||
if err := validateServiceSpec(service); err != nil {
|
if err := validateServiceSpec(service); err != nil {
|
||||||
return types.ServiceUpdateResponse{}, err
|
return response, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var imgPlatforms []swarm.Platform
|
|
||||||
// ensure that the image is tagged
|
// ensure that the image is tagged
|
||||||
if service.TaskTemplate.ContainerSpec != nil {
|
var resolveWarning string
|
||||||
|
switch {
|
||||||
|
case service.TaskTemplate.ContainerSpec != nil:
|
||||||
if taggedImg := imageWithTagString(service.TaskTemplate.ContainerSpec.Image); taggedImg != "" {
|
if taggedImg := imageWithTagString(service.TaskTemplate.ContainerSpec.Image); taggedImg != "" {
|
||||||
service.TaskTemplate.ContainerSpec.Image = taggedImg
|
service.TaskTemplate.ContainerSpec.Image = taggedImg
|
||||||
}
|
}
|
||||||
if options.QueryRegistry {
|
if options.QueryRegistry {
|
||||||
var img string
|
resolveWarning = resolveContainerSpecImage(ctx, cli, &service.TaskTemplate, options.EncodedRegistryAuth)
|
||||||
img, imgPlatforms, distErr = imageDigestAndPlatforms(ctx, cli, service.TaskTemplate.ContainerSpec.Image, options.EncodedRegistryAuth)
|
|
||||||
if img != "" {
|
|
||||||
service.TaskTemplate.ContainerSpec.Image = img
|
|
||||||
}
|
}
|
||||||
}
|
case service.TaskTemplate.PluginSpec != nil:
|
||||||
}
|
|
||||||
|
|
||||||
// ensure that the image is tagged
|
|
||||||
if service.TaskTemplate.PluginSpec != nil {
|
|
||||||
if taggedImg := imageWithTagString(service.TaskTemplate.PluginSpec.Remote); taggedImg != "" {
|
if taggedImg := imageWithTagString(service.TaskTemplate.PluginSpec.Remote); taggedImg != "" {
|
||||||
service.TaskTemplate.PluginSpec.Remote = taggedImg
|
service.TaskTemplate.PluginSpec.Remote = taggedImg
|
||||||
}
|
}
|
||||||
if options.QueryRegistry {
|
if options.QueryRegistry {
|
||||||
var img string
|
resolveWarning = resolvePluginSpecRemote(ctx, cli, &service.TaskTemplate, options.EncodedRegistryAuth)
|
||||||
img, imgPlatforms, distErr = imageDigestAndPlatforms(ctx, cli, service.TaskTemplate.PluginSpec.Remote, options.EncodedRegistryAuth)
|
|
||||||
if img != "" {
|
|
||||||
service.TaskTemplate.PluginSpec.Remote = img
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if service.TaskTemplate.Placement == nil && len(imgPlatforms) > 0 {
|
|
||||||
service.TaskTemplate.Placement = &swarm.Placement{}
|
|
||||||
}
|
|
||||||
if len(imgPlatforms) > 0 {
|
|
||||||
service.TaskTemplate.Placement.Platforms = imgPlatforms
|
|
||||||
}
|
|
||||||
|
|
||||||
var response types.ServiceUpdateResponse
|
|
||||||
resp, err := cli.post(ctx, "/services/"+serviceID+"/update", query, service, headers)
|
resp, err := cli.post(ctx, "/services/"+serviceID+"/update", query, service, headers)
|
||||||
defer ensureReaderClosed(resp)
|
defer ensureReaderClosed(resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -85,9 +67,8 @@ func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version
|
||||||
}
|
}
|
||||||
|
|
||||||
err = json.NewDecoder(resp.body).Decode(&response)
|
err = json.NewDecoder(resp.body).Decode(&response)
|
||||||
|
if resolveWarning != "" {
|
||||||
if distErr != nil {
|
response.Warnings = append(response.Warnings, resolveWarning)
|
||||||
response.Warnings = append(response.Warnings, digestWarning(service.TaskTemplate.ContainerSpec.Image))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return response, err
|
return response, err
|
||||||
|
|
Loading…
Reference in a new issue