Browse Source

Ensure service images get default tag and print familiar strings

Signed-off-by: Nishant Totla <nishanttotla@gmail.com>
Nishant Totla 8 years ago
parent
commit
5efcec7717
2 changed files with 29 additions and 10 deletions
  1. 23 8
      client/service_create.go
  2. 6 2
      client/service_update.go

+ 23 - 8
client/service_create.go

@@ -24,14 +24,18 @@ func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec,
 		headers["X-Registry-Auth"] = []string{options.EncodedRegistryAuth}
 	}
 
+	// ensure that the image is tagged
+	if taggedImg := imageWithTagString(service.TaskTemplate.ContainerSpec.Image); taggedImg != "" {
+		service.TaskTemplate.ContainerSpec.Image = taggedImg
+	}
+
 	// Contact the registry to retrieve digest and platform information
 	if options.QueryRegistry {
 		distributionInspect, err := cli.DistributionInspect(ctx, service.TaskTemplate.ContainerSpec.Image, options.EncodedRegistryAuth)
 		distErr = err
 		if err == nil {
 			// now pin by digest if the image doesn't already contain a digest
-			img := imageWithDigestString(service.TaskTemplate.ContainerSpec.Image, distributionInspect.Descriptor.Digest)
-			if img != "" {
+			if img := imageWithDigestString(service.TaskTemplate.ContainerSpec.Image, distributionInspect.Descriptor.Digest); img != "" {
 				service.TaskTemplate.ContainerSpec.Image = img
 			}
 			// add platforms that are compatible with the service
@@ -55,22 +59,33 @@ func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec,
 }
 
 // imageWithDigestString takes an image string and a digest, and updates
-// the image string if it didn't originally contain a digest. It assumes
-// that the image string is not an image ID
+// the image string if it didn't originally contain a digest. It returns
+// an empty string if there are no updates.
 func imageWithDigestString(image string, dgst digest.Digest) string {
-	ref, err := reference.ParseAnyReference(image)
+	namedRef, err := reference.ParseNormalizedNamed(image)
 	if err == nil {
-		if _, isCanonical := ref.(reference.Canonical); !isCanonical {
-			namedRef, _ := ref.(reference.Named)
+		if _, isCanonical := namedRef.(reference.Canonical); !isCanonical {
+			// ensure that image gets a default tag if none is provided
 			img, err := reference.WithDigest(namedRef, dgst)
 			if err == nil {
-				return img.String()
+				return reference.FamiliarString(img)
 			}
 		}
 	}
 	return ""
 }
 
+// imageWithTagString takes an image string, and returns a tagged image
+// string, adding a 'latest' tag if one was not provided. It returns an
+// emptry string if a canonical reference was provided
+func imageWithTagString(image string) string {
+	namedRef, err := reference.ParseNormalizedNamed(image)
+	if err == nil {
+		return reference.FamiliarString(reference.TagNameOnly(namedRef))
+	}
+	return ""
+}
+
 // updateServicePlatforms updates the Platforms in swarm.Placement to list
 // all compatible platforms for the service, as found in distributionInspect
 // and returns a pointer to the new or updated swarm.Placement struct

+ 6 - 2
client/service_update.go

@@ -35,6 +35,11 @@ func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version
 
 	query.Set("version", strconv.FormatUint(version.Index, 10))
 
+	// ensure that the image is tagged
+	if taggedImg := imageWithTagString(service.TaskTemplate.ContainerSpec.Image); taggedImg != "" {
+		service.TaskTemplate.ContainerSpec.Image = taggedImg
+	}
+
 	// Contact the registry to retrieve digest and platform information
 	// This happens only when the image has changed
 	if options.QueryRegistry {
@@ -42,8 +47,7 @@ func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version
 		distErr = err
 		if err == nil {
 			// now pin by digest if the image doesn't already contain a digest
-			img := imageWithDigestString(service.TaskTemplate.ContainerSpec.Image, distributionInspect.Descriptor.Digest)
-			if img != "" {
+			if img := imageWithDigestString(service.TaskTemplate.ContainerSpec.Image, distributionInspect.Descriptor.Digest); img != "" {
 				service.TaskTemplate.ContainerSpec.Image = img
 			}
 			// add platforms that are compatible with the service