Skip to content
Open
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
31 changes: 18 additions & 13 deletions cmd/release-controller-api/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -1716,16 +1716,18 @@ func (c *Controller) httpReleases(w http.ResponseWriter, req *http.Request) {
Tags: releasecontroller.SortedReleaseTags(r),
}
var delays []string
if r.Config.As != releasecontroller.ReleaseConfigModeStable && len(s.Tags) > 0 {
if r.Config.EndOfSupport {
s.Delayed = &ReleaseDelay{Message: "Release has reached end of support"}
} else if r.Config.As != releasecontroller.ReleaseConfigModeStable && len(s.Tags) > 0 {
if ok, _, queueAfter := releasecontroller.IsReleaseDelayedForInterval(r, s.Tags[0]); ok {
delays = append(delays, fmt.Sprintf("waiting for %s", queueAfter.Truncate(time.Second)))
}
if r.Config.MaxUnreadyReleases > 0 && releasecontroller.CountUnreadyReleases(r, s.Tags) >= r.Config.MaxUnreadyReleases {
delays = append(delays, fmt.Sprintf("no more than %d pending", r.Config.MaxUnreadyReleases))
}
}
if len(delays) > 0 {
s.Delayed = &ReleaseDelay{Message: fmt.Sprintf("Next release may not start: %s", strings.Join(delays, ", "))}
if len(delays) > 0 {
s.Delayed = &ReleaseDelay{Message: fmt.Sprintf("Next release may not start: %s", strings.Join(delays, ", "))}
}
}
if r.Config.As != releasecontroller.ReleaseConfigModeStable {
s.Upgrades = calculateReleaseUpgrades(r, s.Tags, c.graph, false)
Expand Down Expand Up @@ -1966,16 +1968,18 @@ func (c *Controller) httpReleaseStreamTable(w http.ResponseWriter, req *http.Req
Tags: releasecontroller.SortedReleaseTags(r),
}
var delays []string
if r.Config.As != releasecontroller.ReleaseConfigModeStable && len(s.Tags) > 0 {
if r.Config.EndOfSupport {
s.Delayed = &ReleaseDelay{Message: "Release has reached end of support"}
} else if r.Config.As != releasecontroller.ReleaseConfigModeStable && len(s.Tags) > 0 {
if ok, _, queueAfter := releasecontroller.IsReleaseDelayedForInterval(r, s.Tags[0]); ok {
delays = append(delays, fmt.Sprintf("waiting for %s", queueAfter.Truncate(time.Second)))
}
if r.Config.MaxUnreadyReleases > 0 && releasecontroller.CountUnreadyReleases(r, s.Tags) >= r.Config.MaxUnreadyReleases {
delays = append(delays, fmt.Sprintf("no more than %d pending", r.Config.MaxUnreadyReleases))
}
}
if len(delays) > 0 {
s.Delayed = &ReleaseDelay{Message: fmt.Sprintf("Next release may not start: %s", strings.Join(delays, ", "))}
if len(delays) > 0 {
s.Delayed = &ReleaseDelay{Message: fmt.Sprintf("Next release may not start: %s", strings.Join(delays, ", "))}
}
}
if r.Config.As != releasecontroller.ReleaseConfigModeStable {
s.Upgrades = calculateReleaseUpgrades(r, s.Tags, c.graph, false)
Expand Down Expand Up @@ -2123,21 +2127,22 @@ func (c *Controller) httpDashboardOverview(w http.ResponseWriter, req *http.Requ
Tags: releasecontroller.SortedReleaseTags(r),
}
var delays []string
if r.Config.As != releasecontroller.ReleaseConfigModeStable && len(s.Tags) > 0 {
if r.Config.EndOfSupport {
s.Delayed = &ReleaseDelay{Message: "Release has reached end of support"}
} else if r.Config.As != releasecontroller.ReleaseConfigModeStable && len(s.Tags) > 0 {
if ok, _, queueAfter := releasecontroller.IsReleaseDelayedForInterval(r, s.Tags[0]); ok {
delays = append(delays, fmt.Sprintf("waiting for %s", queueAfter.Truncate(time.Second)))
}
if r.Config.MaxUnreadyReleases > 0 && releasecontroller.CountUnreadyReleases(r, s.Tags) >= r.Config.MaxUnreadyReleases {
delays = append(delays, fmt.Sprintf("no more than %d pending", r.Config.MaxUnreadyReleases))
}
if len(delays) > 0 {
s.Delayed = &ReleaseDelay{Message: fmt.Sprintf("Next release may not start: %s", strings.Join(delays, ", "))}
}
}
if isReleaseFailing(s.Tags, r.Config.MaxUnreadyReleases) {
s.Failing = true
}

if len(delays) > 0 {
s.Delayed = &ReleaseDelay{Message: fmt.Sprintf("Next release may not start: %s", strings.Join(delays, ", "))}
}
if r.Config.As != releasecontroller.ReleaseConfigModeStable {
s.Upgrades = calculateReleaseUpgrades(r, s.Tags, c.graph, true)
}
Expand Down
4 changes: 4 additions & 0 deletions cmd/release-controller/periodic.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ func (c *Controller) syncPeriodicJobs(prowInformers cache.SharedIndexInformer, s
klog.V(6).Infof("release %s has reached the end of life", r.Config.Name)
continue
}
if r.Config.EndOfSupport {
klog.V(6).Infof("release %s has reached end of support, skipping periodic jobs", r.Config.Name)
continue
}
for name, releasePeriodic := range r.Config.Periodic {
periodicConfig, ok := hasProwJob(cfg, releasePeriodic.ProwJob.Name)
if !ok {
Expand Down
6 changes: 5 additions & 1 deletion cmd/release-controller/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,11 @@ func calculateSyncActions(release *releasecontroller.Release, now time.Time) (ad
inputImageHash = ""
removeTags = nil
default:
// gate creating new releases when we already are at max unready or in the cooldown interval
// gate creating new releases when end of support, at max unready, or in the cooldown interval
if release.Config.EndOfSupport {
klog.V(2).Infof("Release %s has reached end of support, will not launch new tags", release.Config.Name)
hasNewImages = false
}
if release.Config.MaxUnreadyReleases > 0 && unreadyTagCount >= release.Config.MaxUnreadyReleases {
klog.V(2).Infof("Release %s at max %d unready releases, will not launch new tags", release.Config.Name, release.Config.MaxUnreadyReleases)
hasNewImages = false
Expand Down
5 changes: 5 additions & 0 deletions pkg/release-controller/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ type ReleaseConfig struct {
// displayed by the release-controller
EndOfLife bool `json:"endOfLife"`

// EndOfSupport indicates this release stream is no longer supported and should
// stop creating new releases, but remain visible on the status pages without
// showing a countdown timer.
EndOfSupport bool `json:"endOfSupport"`

// As defines what this image stream provides. The default value is "Integration"
// and the images in the image stream will be used to build payloads. An optional
// mode is "Stable" and tags are assumed to be release payloads that should be promoted
Expand Down