Signed-off-by: Nishant Totla <nishanttotla@gmail.com>
| ... | ... |
@@ -24,14 +24,18 @@ func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec, |
| 24 | 24 |
headers["X-Registry-Auth"] = []string{options.EncodedRegistryAuth}
|
| 25 | 25 |
} |
| 26 | 26 |
|
| 27 |
+ // ensure that the image is tagged |
|
| 28 |
+ if taggedImg := imageWithTagString(service.TaskTemplate.ContainerSpec.Image); taggedImg != "" {
|
|
| 29 |
+ service.TaskTemplate.ContainerSpec.Image = taggedImg |
|
| 30 |
+ } |
|
| 31 |
+ |
|
| 27 | 32 |
// Contact the registry to retrieve digest and platform information |
| 28 | 33 |
if options.QueryRegistry {
|
| 29 | 34 |
distributionInspect, err := cli.DistributionInspect(ctx, service.TaskTemplate.ContainerSpec.Image, options.EncodedRegistryAuth) |
| 30 | 35 |
distErr = err |
| 31 | 36 |
if err == nil {
|
| 32 | 37 |
// now pin by digest if the image doesn't already contain a digest |
| 33 |
- img := imageWithDigestString(service.TaskTemplate.ContainerSpec.Image, distributionInspect.Descriptor.Digest) |
|
| 34 |
- if img != "" {
|
|
| 38 |
+ if img := imageWithDigestString(service.TaskTemplate.ContainerSpec.Image, distributionInspect.Descriptor.Digest); img != "" {
|
|
| 35 | 39 |
service.TaskTemplate.ContainerSpec.Image = img |
| 36 | 40 |
} |
| 37 | 41 |
// add platforms that are compatible with the service |
| ... | ... |
@@ -55,22 +59,33 @@ func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec, |
| 55 | 55 |
} |
| 56 | 56 |
|
| 57 | 57 |
// imageWithDigestString takes an image string and a digest, and updates |
| 58 |
-// the image string if it didn't originally contain a digest. It assumes |
|
| 59 |
-// that the image string is not an image ID |
|
| 58 |
+// the image string if it didn't originally contain a digest. It returns |
|
| 59 |
+// an empty string if there are no updates. |
|
| 60 | 60 |
func imageWithDigestString(image string, dgst digest.Digest) string {
|
| 61 |
- ref, err := reference.ParseAnyReference(image) |
|
| 61 |
+ namedRef, err := reference.ParseNormalizedNamed(image) |
|
| 62 | 62 |
if err == nil {
|
| 63 |
- if _, isCanonical := ref.(reference.Canonical); !isCanonical {
|
|
| 64 |
- namedRef, _ := ref.(reference.Named) |
|
| 63 |
+ if _, isCanonical := namedRef.(reference.Canonical); !isCanonical {
|
|
| 64 |
+ // ensure that image gets a default tag if none is provided |
|
| 65 | 65 |
img, err := reference.WithDigest(namedRef, dgst) |
| 66 | 66 |
if err == nil {
|
| 67 |
- return img.String() |
|
| 67 |
+ return reference.FamiliarString(img) |
|
| 68 | 68 |
} |
| 69 | 69 |
} |
| 70 | 70 |
} |
| 71 | 71 |
return "" |
| 72 | 72 |
} |
| 73 | 73 |
|
| 74 |
+// imageWithTagString takes an image string, and returns a tagged image |
|
| 75 |
+// string, adding a 'latest' tag if one was not provided. It returns an |
|
| 76 |
+// emptry string if a canonical reference was provided |
|
| 77 |
+func imageWithTagString(image string) string {
|
|
| 78 |
+ namedRef, err := reference.ParseNormalizedNamed(image) |
|
| 79 |
+ if err == nil {
|
|
| 80 |
+ return reference.FamiliarString(reference.TagNameOnly(namedRef)) |
|
| 81 |
+ } |
|
| 82 |
+ return "" |
|
| 83 |
+} |
|
| 84 |
+ |
|
| 74 | 85 |
// updateServicePlatforms updates the Platforms in swarm.Placement to list |
| 75 | 86 |
// all compatible platforms for the service, as found in distributionInspect |
| 76 | 87 |
// and returns a pointer to the new or updated swarm.Placement struct |
| ... | ... |
@@ -35,6 +35,11 @@ func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version |
| 35 | 35 |
|
| 36 | 36 |
query.Set("version", strconv.FormatUint(version.Index, 10))
|
| 37 | 37 |
|
| 38 |
+ // ensure that the image is tagged |
|
| 39 |
+ if taggedImg := imageWithTagString(service.TaskTemplate.ContainerSpec.Image); taggedImg != "" {
|
|
| 40 |
+ service.TaskTemplate.ContainerSpec.Image = taggedImg |
|
| 41 |
+ } |
|
| 42 |
+ |
|
| 38 | 43 |
// Contact the registry to retrieve digest and platform information |
| 39 | 44 |
// This happens only when the image has changed |
| 40 | 45 |
if options.QueryRegistry {
|
| ... | ... |
@@ -42,8 +47,7 @@ func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version |
| 42 | 42 |
distErr = err |
| 43 | 43 |
if err == nil {
|
| 44 | 44 |
// now pin by digest if the image doesn't already contain a digest |
| 45 |
- img := imageWithDigestString(service.TaskTemplate.ContainerSpec.Image, distributionInspect.Descriptor.Digest) |
|
| 46 |
- if img != "" {
|
|
| 45 |
+ if img := imageWithDigestString(service.TaskTemplate.ContainerSpec.Image, distributionInspect.Descriptor.Digest); img != "" {
|
|
| 47 | 46 |
service.TaskTemplate.ContainerSpec.Image = img |
| 48 | 47 |
} |
| 49 | 48 |
// add platforms that are compatible with the service |