fix(operator): idle auto-stop couldn't write — patch the spec, and grant the patch
Two stacked blockers behind the frozen auto-stop, both found live after the first two fixes let the timer finally tick: - The stop used a whole-object Update while the same reconcile loop writes status; that risks clobbering a concurrent status write. Switch to the reaper's merge-patch pattern (spec.desiredState only; EmptySince is left for markStopped to clear). - The operator Role never carried minecraftservers:patch, so the call failed closed with 403 (visible in the operator log as 'cannot update resource "minecraftservers"'). Grant patch and pin it in the RBAC scope test. With all three layers fixed, the auto-stop path is: timer persists (schema), wake-up fires (requeue), spec write allowed (RBAC).
This commit is contained in:
3 files changed
+18
-5
No files matched your search
@@ -185,9 +185,14 @@ func (r *Reconciler) reconcileRunning(ctx context.Context, server *v1alpha1.Mine
|
||||
server.Status.EmptySince = &t
|
||||
} else if r.now().Time.Sub(server.Status.EmptySince.Time).Seconds() >=
|
||||
float64(server.Spec.Idle.EmptySecondsBeforeStop) {
|
||||
// Merge patch, not Update: an unrelated reconcile writes status
|
||||
// concurrently, and shipping the whole object back risks
|
||||
// clobbering it (the reaper's Stop uses the same pattern for
|
||||
// the same reason). EmptySince is deliberately left for
|
||||
// markStopped to clear once the scale-down completes.
|
||||
patch := client.MergeFrom(server.DeepCopy())
|
||||
server.Spec.DesiredState = v1alpha1.DesiredStopped
|
||||
server.Status.EmptySince = nil
|
||||
if err := r.Update(ctx, server); err != nil {
|
||||
if err := r.Patch(ctx, server, patch); err != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
return ctrl.Result{}, nil
|
||||
|
||||
Reference in new issue
Block a user