Skip to content

new-app hidden imagestreams: fix behaviour when no tag is specified #12185

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 18 additions & 8 deletions pkg/generate/app/imagestreamlookup.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,21 +113,31 @@ func (r ImageStreamSearcher) Search(precise bool, terms ...string) (ComponentMat
componentMatches = append(componentMatches, match)
}

// When an image stream contains a tag that references another local tag, and the user has not
// provided a tag themselves (i.e. they asked for mysql and we defaulted to mysql:latest), walk
// the chain of references to the end. This ensures that applications can default to using a "stable"
// branch by giving the control over version to the image stream author.
// When the user has not provided a tag themselves (i.e. they asked for
// mysql and we defaulted to mysql:latest), and "latest" references
// another local tag, and neither tag is hidden, use the referenced tag
// instead of "latest". This ensures that applications can default to
// using a "stable" branch by giving the control over version to the
// image stream author.
finalTag := searchTag
if specTag, ok := stream.Spec.Tags[searchTag]; ok && followTag {
if specTag, ok := stream.Spec.Tags[searchTag]; ok && followTag && !specTag.HasAnnotationTag(imageapi.TagReferenceAnnotationTagHidden) {
if specTag.From != nil && specTag.From.Kind == "ImageStreamTag" && !strings.Contains(specTag.From.Name, ":") {
if imageapi.LatestTaggedImage(stream, specTag.From.Name) != nil {
finalTag = specTag.From.Name
if destSpecTag, ok := stream.Spec.Tags[specTag.From.Name]; ok && !destSpecTag.HasAnnotationTag(imageapi.TagReferenceAnnotationTagHidden) {
if imageapi.LatestTaggedImage(stream, specTag.From.Name) != nil {
finalTag = specTag.From.Name
}
}
}
}

latest := imageapi.LatestTaggedImage(stream, finalTag)
if latest == nil || len(latest.Image) == 0 {

// Special case in addition to the other tag not found cases: if no tag
// was specified, and "latest" is hidden, then behave as if "latest"
// doesn't exist (in this case, to get to "latest", the user must hard
// specify tag "latest").
if specTag, ok := stream.Spec.Tags[searchTag]; (ok && followTag && specTag.HasAnnotationTag(imageapi.TagReferenceAnnotationTagHidden)) ||
latest == nil || len(latest.Image) == 0 {

glog.V(2).Infof("no image recorded for %s/%s:%s", stream.Namespace, stream.Name, finalTag)
if r.AllowMissingTags {
Expand Down
57 changes: 54 additions & 3 deletions pkg/generate/app/imagestreamlookup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,38 @@ func TestImageStreamSearcher(t *testing.T) {
},
},
},
&fakeImageStreamDesc{
name: "nodejs3",
tags: map[string]imageapi.TagReference{
"4": {
Annotations: map[string]string{
"supports": "nodejs3:4,nodejs3",
"tags": "hidden",
},
},
},
latest: "4",
},
&fakeImageStreamDesc{
name: "nodejs4",
tags: map[string]imageapi.TagReference{
"0.10": {
Annotations: map[string]string{
"supports": "nodejs4:0.10,nodejs4:0.1,nodejs4",
},
},
"4": {
Annotations: map[string]string{
"supports": "nodejs4:4,nodejs4",
"tags": "hidden",
},
},
},
latest: "4",
latestannotations: map[string]string{
"tags": "hidden",
},
},
&fakeImageStreamDesc{
name: "ruby20",
tags: map[string]imageapi.TagReference{
Expand Down Expand Up @@ -194,6 +226,16 @@ func TestImageStreamSearcher(t *testing.T) {
value: "nodejs2",
expectMatch: false,
},
{
value: "nodejs3",
expectMatch: true,
expectTag: "latest",
},
{
value: "nodejs4",
expectMatch: true,
expectTag: "0.10",
},
}

for _, test := range tests {
Expand Down Expand Up @@ -358,9 +400,10 @@ func TestAnnotationMatches(t *testing.T) {
}

type fakeImageStreamDesc struct {
name string
tags map[string]imageapi.TagReference
latest string
name string
tags map[string]imageapi.TagReference
latest string
latestannotations map[string]string
}

func fakeImageStreams(descs ...*fakeImageStreamDesc) (*imageapi.ImageStreamList, map[string]*imageapi.ImageStreamImage) {
Expand Down Expand Up @@ -415,6 +458,14 @@ func fakeImageStream(desc *fakeImageStreamDesc) (*imageapi.ImageStream, map[stri
Name: desc.latest,
Namespace: "namespace",
},
Annotations: desc.latestannotations,
}
stream.Status.Tags["latest"] = imageapi.TagEventList{
Items: []imageapi.TagEvent{
{
Image: desc.latest + "-image",
},
},
}
}
return stream, images
Expand Down