mirror of
https://github.com/actions-runner-controller/actions-runner-controller.git
synced 2026-10-09 22:51:37 +02:00
Make the Outdated phase revision-aware
An EphemeralRunnerSet goes Outdated when a child runner reports that the
Actions service rejected its runner spec, and the AutoscalingRunnerSet
then tears the listener down so the scale set stops taking jobs. Until
now nothing recorded which runner spec a given Outdated report was about,
so a report from a runner that predates a spec update kept the set
switched off even after the user had already fixed the spec.
Runners now carry the EphemeralRunnerSet's actionable revision as an
annotation, and Outdated runners are split into two groups:
- stale outdated: created before the currently applied revision. Their
verdict is about a spec that no longer exists, so they are deleted
and replaced by runners built from the current spec.
- outdated: created at or after the applied revision. Their verdict is
about the current spec, so they hold the set in the Outdated phase.
They are deliberately not delete-and-replaced: a fresh runner at the
same revision would report Outdated again, forever.
patchAppliedActionableRevisionStatus now recomputes the phase in both
directions against the revision being applied, because it returns from
Reconcile without reaching updateStatus. The AutoscalingRunnerSet
teardown guard additionally requires the applied revision to have caught
up with the spec revision, so it does not act on an Outdated verdict for
a spec that has already been replaced.
terminated() now allocates a fresh slice instead of appending into the
finished slice, which could alias its backing array.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
co-authored by
Copilot App
parent
752765e50c
commit
60a6753d3b
@@ -39,6 +39,30 @@ func nextActionableRevision(current *v1alpha1.EphemeralRunnerSet) int64 {
|
||||
return current.Status.AppliedActionableRevision + 1
|
||||
}
|
||||
|
||||
// ephemeralRunnerSetOutdatedForAppliedRevision reports whether the set is
|
||||
// Outdated *because of the runner spec it is currently running*, which is the
|
||||
// only situation in which the AutoscalingRunnerSet should tear the scale set
|
||||
// down.
|
||||
//
|
||||
// The phase alone is not enough. Outdated is deliberately sticky: it survives in
|
||||
// status while the outdated runners are collected, and it is only cleared once a
|
||||
// new revision is applied. So between the moment the AutoscalingRunnerSet patches
|
||||
// a new runner spec onto the set and the moment the EphemeralRunnerSet controller
|
||||
// processes that patch, the set still reports Outdated for a spec that no longer
|
||||
// exists. Tearing down there would discard the fix the user just applied, and the
|
||||
// scale set would stay switched off until something else nudged it.
|
||||
//
|
||||
// Requiring the applied revision to have caught up with the spec revision closes
|
||||
// that window: the verdict counts only once the set is running the current spec.
|
||||
func ephemeralRunnerSetOutdatedForAppliedRevision(ephemeralRunnerSet *v1alpha1.EphemeralRunnerSet) bool {
|
||||
if ephemeralRunnerSet == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return ephemeralRunnerSet.Status.Phase == v1alpha1.EphemeralRunnerSetPhaseOutdated &&
|
||||
ephemeralRunnerSet.Status.AppliedActionableRevision >= ephemeralRunnerSet.Spec.ActionableRevision
|
||||
}
|
||||
|
||||
// listenerPodSpecRequiresRecreation reports whether the live listener pod must be
|
||||
// deleted and rebuilt to match the desired spec.
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user