Skip to content

Commit 69a00fc

Browse files
committed
fix: repair a drifted pool label when the pool releases a used member
Change-Id: I12ec1a3bb4be216f5884862537716ae328764254 Signed-off-by: Thomas Kosiewski <tk@coder.com>
1 parent 31fd47d commit 69a00fc

2 files changed

Lines changed: 11 additions & 2 deletions

File tree

‎internal/controller/coderworkspacepool_controller.go‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,8 @@ func (r *CoderWorkspacePoolReconciler) deleteFailedMembers(
257257
// unclaimed members that someone used (plan 6.3 step 4, decision D6). A
258258
// used member then never counts as unclaimed again, and neither the pool
259259
// nor its deletion deletes it. It keeps the pool label for
260-
// status.usedReplicas. The update carries the listed resourceVersion, and
260+
// status.usedReplicas, set again if it drifted. The update carries the
261+
// listed resourceVersion, and
261262
// the listed members stay as they were, so the later steps decide on the
262263
// list.
263264
func (r *CoderWorkspacePoolReconciler) releaseUsedMembers(
@@ -272,6 +273,11 @@ func (r *CoderWorkspacePoolReconciler) releaseUsedMembers(
272273
}
273274
released := m.DeepCopy()
274275
released.OwnerReferences = slices.DeleteFunc(released.OwnerReferences, func(o metav1.OwnerReference) bool { return o.UID == pool.UID })
276+
// The label is the only link left, so repair a drifted one.
277+
if released.Labels == nil {
278+
released.Labels = map[string]string{}
279+
}
280+
released.Labels[coderv1alpha1.CoderWorkspacePoolSelectorLabel] = string(pool.UID)
275281
if err := r.Update(ctx, released); err != nil {
276282
return fmt.Errorf("release used pool member %s/%s: %w", m.Namespace, m.Name, err)
277283
}

‎internal/controller/coderworkspacepool_delete_test.go‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,9 @@ func TestPoolReleasesUsedMember(t *testing.T) {
114114
t.Parallel()
115115
e := newPoolMemberEnv(t)
116116
e.editPool(t, func(s *coderv1alpha1.CoderWorkspacePoolSpec) { s.Replicas = new(int32(2)) })
117-
used := e.createMember(t, nil)
117+
// The label drifted: the release sets it again, because it is the only
118+
// link to the pool after the release.
119+
used := e.createMember(t, func(m *coderv1alpha1.CoderWorkspacePoolMember) { m.Labels = nil })
118120
e.setMemberStatus(t, used, withWorkspace(usedStatus))
119121
ready := e.createMember(t, nil)
120122
e.setMemberStatus(t, ready, withWorkspace(readyStatus))
@@ -128,6 +130,7 @@ func TestPoolReleasesUsedMember(t *testing.T) {
128130
require.Equal(t, string(pool.UID), released.Labels[coderv1alpha1.CoderWorkspacePoolSelectorLabel])
129131
require.Equal(t, int32(1), pool.Status.UsedReplicas)
130132
require.Zero(t, pool.Status.Replicas)
133+
require.Equal(t, int32(1), e.reconcilePool(t, 1).Status.UsedReplicas, "found again through the repaired label")
131134

132135
// The member reconciler marks the member used between the list and the
133136
// delete: the resourceVersion precondition refuses the delete.

0 commit comments

Comments
 (0)