Merge pull request #3503 from dimw/3487-set-image-tag-name

Add support for setting new tag while preserving the current name
This commit is contained in:
Donny Xia
2021-01-26 10:32:33 -08:00
committed by GitHub
2 changed files with 219 additions and 3 deletions

View File

@@ -20,7 +20,9 @@ type setImageOptions struct {
imageMap map[string]types.Image
}
var pattern = regexp.MustCompile("^(.*):([a-zA-Z0-9._-]*)$")
var pattern = regexp.MustCompile(`^(.*):([a-zA-Z0-9._-]*|\*)$`)
var preserveSeparator = "*"
// errors
@@ -74,7 +76,8 @@ images:
to the kustomization file if it doesn't exist,
and overwrite the previous ones if the image name exists.
The image tag can only contain alphanumeric, '.', '_' and '-'.
The image tag can only contain alphanumeric, '.', '_' and '-'. Passing * (asterisk) either as the new name,
the new tag, or the digest will preserve the appropriate values from the kustomization file.
`,
RunE: func(cmd *cobra.Command, args []string) error {
err := o.Validate(args)
@@ -125,7 +128,25 @@ func (o *setImageOptions) RunSetImage(fSys filesys.FileSystem) error {
// append only new images from kustomize file
for _, im := range m.Images {
if _, ok := o.imageMap[im.Name]; ok {
if argIm, ok := o.imageMap[im.Name]; ok {
// Reuse the existing new name when asterisk new name is passed
if argIm.NewName == preserveSeparator {
argIm = replaceNewName(argIm, im.NewName)
}
// Reuse the existing new tag when asterisk new tag is passed
if argIm.NewTag == preserveSeparator {
argIm = replaceNewTag(argIm, im.NewTag)
}
// Reuse the existing digest when asterisk disgest is passed
if argIm.Digest == preserveSeparator {
argIm = replaceDigest(argIm, im.Digest)
}
o.imageMap[im.Name] = argIm
continue
}
@@ -134,6 +155,19 @@ func (o *setImageOptions) RunSetImage(fSys filesys.FileSystem) error {
var images []types.Image
for _, v := range o.imageMap {
if v.NewName == preserveSeparator {
v = replaceNewName(v, "")
}
if v.NewTag == preserveSeparator {
v = replaceNewTag(v, "")
}
if v.Digest == preserveSeparator {
v = replaceDigest(v, "")
}
images = append(images, v)
}
@@ -145,6 +179,33 @@ func (o *setImageOptions) RunSetImage(fSys filesys.FileSystem) error {
return mf.Write(m)
}
func replaceNewName(image types.Image, newName string) types.Image {
return types.Image{
Name: image.Name,
NewName: newName,
NewTag: image.NewTag,
Digest: image.Digest,
}
}
func replaceNewTag(image types.Image, newTag string) types.Image {
return types.Image{
Name: image.Name,
NewName: image.NewName,
NewTag: newTag,
Digest: image.Digest,
}
}
func replaceDigest(image types.Image, digest string) types.Image {
return types.Image{
Name: image.Name,
NewName: image.NewName,
NewTag: image.NewTag,
Digest: digest,
}
}
func parse(arg string) (types.Image, error) {
// matches if there is an image name to overwrite

View File

@@ -251,6 +251,161 @@ func TestSetImage(t *testing.T) {
err: errImageInvalidArgs,
},
},
{
description: "override new tag but keep new name",
given: given{
args: []string{"image1=*:v1"},
infileImages: []string{
"images:",
"- name: image1",
" newName: foo.bar.foo:8800/foo/image1",
" newTag: my-tag",
},
},
expected: expected{
fileOutput: []string{
"images:",
"- name: image1",
" newName: foo.bar.foo:8800/foo/image1",
" newTag: v1",
}},
},
{
description: "override new name but keep new tag",
given: given{
args: []string{"image1=my-image1:*"},
infileImages: []string{
"images:",
"- name: image1",
" newName: foo.bar.foo:8800/foo/image1",
" newTag: my-tag",
},
},
expected: expected{
fileOutput: []string{
"images:",
"- name: image1",
" newName: my-image1",
" newTag: my-tag",
}},
},
{
description: "keep new name and new tag (rare case)",
given: given{
args: []string{"image1=*:*"},
infileImages: []string{
"images:",
"- name: image1",
" newName: my-image1",
" newTag: my-tag",
},
},
expected: expected{
fileOutput: []string{
"images:",
"- name: image1",
" newName: my-image1",
" newTag: my-tag",
}},
},
{
description: "do not set asterisk as new name for existing image",
given: given{
args: []string{"image1=*:v1"},
infileImages: []string{
"images:",
"- name: image1",
" newTag: my-tag",
},
},
expected: expected{
fileOutput: []string{
"images:",
"- name: image1",
" newTag: v1",
}},
},
{
description: "do not set asterisk as new name",
given: given{
args: []string{"image1=*:v1"},
},
expected: expected{
fileOutput: []string{
"images:",
"- name: image1",
" newTag: v1",
}},
},
{
description: "do not set asterisk as new tag",
given: given{
args: []string{"image1=my-image1:*"},
},
expected: expected{
fileOutput: []string{
"images:",
"- name: image1",
" newName: my-image1",
}},
},
{
description: "keep new name and update digest",
given: given{
args: []string{"image2=*@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3"},
infileImages: []string{
"images:",
"- name: image2",
" newName: my-image2",
" digest: sha256:abcdef12345",
},
},
expected: expected{
fileOutput: []string{
"images:",
"- digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3",
" name: image2",
" newName: my-image2",
}},
},
{
description: "keep new name, remove tag, and set digest",
given: given{
args: []string{"image2=*@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3"},
infileImages: []string{
"images:",
"- name: image2",
" newName: my-image2",
" newTag: my-tag",
},
},
expected: expected{
fileOutput: []string{
"images:",
"- digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3",
" name: image2",
" newName: my-image2",
}},
},
{
description: "update new name and keep the digest",
given: given{
args: []string{"image2=my-image2@*"},
infileImages: []string{
"images:",
"- digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3",
" name: image2",
" newName: foo.bar.foo:8800/foo/image1",
},
},
expected: expected{
fileOutput: []string{
"images:",
"- digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3",
" name: image2",
" newName: my-image2",
}},
},
}
for _, tc := range testCases {