Removing tagged images change in behavior

An image name is really just a tag.  When an image has multiple tags, we should be
able to "delete" the one of its tags without harm. In this case, the "delete' is
really a form of Untag (removing the tag from the image).

If an image has multiple tags and the user tries to delete by ID without force, this
should be denied because when you delete by ID there is no distinguishing it like
image tags.

Signed-off-by: baude <bbaude@redhat.com>

Closes: #528
Approved by: mheon
This commit is contained in:
baude
2018-03-21 13:08:32 -05:00
committed by Atomic Bot
parent 2cc51dbb1c
commit d364d41e1b
6 changed files with 167 additions and 25 deletions

View File

@ -685,3 +685,60 @@ func Import(path, reference string, writer io.Writer, signingOptions SigningOpti
}
return runtime.NewFromLocal(reference)
}
// MatchRepoTag takes a string and tries to match it against an
// image's repotags
func (i *Image) MatchRepoTag(input string) (string, error) {
results := make(map[int][]string)
var maxCount int
// first check if we have an exact match with the input
if util.StringInSlice(input, i.Names()) {
return input, nil
}
// next check if we are missing the tag
dcImage, err := decompose(input)
if err != nil {
return "", err
}
for _, repoName := range i.Names() {
count := 0
dcRepoName, err := decompose(repoName)
if err != nil {
return "", err
}
if dcRepoName.registry == dcImage.registry && dcImage.registry != "" {
count++
}
if dcRepoName.name == dcImage.name && dcImage.name != "" {
count++
} else if splitString(dcRepoName.name) == splitString(dcImage.name) {
count++
}
if dcRepoName.tag == dcImage.tag {
count++
}
results[count] = append(results[count], repoName)
if count > maxCount {
maxCount = count
}
}
if maxCount == 0 {
return "", errors.Errorf("unable to match user input to any specific repotag")
}
if len(results[maxCount]) > 1 {
return "", errors.Errorf("user input matched multiple repotags for the image")
}
return results[maxCount][0], nil
}
// splitString splits input string by / and returns the last array item
func splitString(input string) string {
split := strings.Split(input, "/")
return split[len(split)-1]
}
// InputIsID returns a bool if the user input for an image
// is the image's partial or full id
func (i *Image) InputIsID() bool {
return strings.HasPrefix(i.ID(), i.InputName)
}