Skip to content
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
20 changes: 16 additions & 4 deletions pkg/image/controller/scheduled_image_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (

imagev1 "github.com/openshift/api/image/v1"
imagev1lister "github.com/openshift/client-go/image/listers/image/v1"
"github.com/openshift/library-go/pkg/image/imageutil"
imageref "github.com/openshift/library-go/pkg/image/reference"
metrics "github.com/openshift/openshift-controller-manager/pkg/image/metrics/prometheus"
)
Expand Down Expand Up @@ -182,9 +183,10 @@ func resetScheduledTags(stream *imagev1.ImageStream) {
if tagImportable(tagRef) && tagRef.ImportPolicy.Scheduled {
if ref, err := imageref.Parse(tagRef.From.Name); err != nil && len(tagRef.From.Name) > 0 {
continue
} else if len(ref.ID) > 0 && !tagNeedsImport(stream, tagRef, true) {
} else if len(ref.ID) > 0 && tagImported(stream, tagRef) {
// ref.ID is set if this is a canonical, sha/digest ref;
// we allow scheduled import of those, but only until the initially succeed
// we allow scheduled import of those, but only until it succeeds
// at least once.
continue
}
tagRef.Generation = &next
Expand All @@ -193,15 +195,25 @@ func resetScheduledTags(stream *imagev1.ImageStream) {
}
}

// tagImported returns if a tag has been imported and is on the last generation.
func tagImported(stream *imagev1.ImageStream, tag imagev1.TagReference) bool {
tagEvents, hasTag := imageutil.StatusHasTag(stream, tag.Name)
if !hasTag || tag.Generation == nil || len(tagEvents.Items) == 0 {
return false
}
return tagEvents.Items[0].Generation == *tag.Generation
}

// needsScheduling returns true if this image stream has any scheduled tags
func needsScheduling(stream *imagev1.ImageStream) bool {
for _, tagRef := range stream.Spec.Tags {
if tagImportable(tagRef) && tagRef.ImportPolicy.Scheduled {
if ref, err := imageref.Parse(tagRef.From.Name); err != nil && len(tagRef.From.Name) > 0 {
continue
} else if len(ref.ID) > 0 && !tagNeedsImport(stream, tagRef, true) {
} else if len(ref.ID) > 0 && tagImported(stream, tagRef) {
// ref.ID is set if this is a canonical, sha/digest ref;
// we allow scheduled import of those, but only until the initially succeed
// we allow scheduled import of those, but only until it succeeds
// at least once.
continue
}
return true
Expand Down
35 changes: 35 additions & 0 deletions pkg/image/controller/scheduled_image_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,41 @@ func TestSchedulingChecks(t *testing.T) {
},
expectedResult: false,
},
"sha ref that failed will import": {
is: &imagev1.ImageStream{
ObjectMeta: metav1.ObjectMeta{
Name: "test", Namespace: "other", UID: "1", ResourceVersion: "1",
Annotations: map[string]string{imagev1.DockerImageRepositoryCheckAnnotation: "done"},
Generation: 1,
},
Spec: imagev1.ImageStreamSpec{
Tags: []imagev1.TagReference{
{
Name: "default1",
From: &corev1.ObjectReference{Kind: "DockerImage", Name: "abc@sha256:3c87c572822935df60f0f5d3665bd376841a7fcfeb806b5f212de6a00e9a7b25"},
Generation: &one,
ImportPolicy: imagev1.TagImportPolicy{Scheduled: true},
},
},
},
Status: imagev1.ImageStreamStatus{
Tags: []imagev1.NamedTagEventList{
{
Tag: "default1",
Conditions: []imagev1.TagEventCondition{
{
Type: imagev1.ImportSuccess,
Status: corev1.ConditionFalse,
Generation: 1,
Message: "transient error",
},
},
},
},
},
},
expectedResult: true,
},
"sha ref not imported": {
is: &imagev1.ImageStream{
ObjectMeta: metav1.ObjectMeta{
Expand Down