Skip to content

Commit 762e05b

Browse files
idler: delete completed pods (codeready-toolchain#660)
1 parent 5867f2e commit 762e05b

File tree

2 files changed

+28
-12
lines changed

2 files changed

+28
-12
lines changed

controllers/idler/idler_controller.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -244,18 +244,18 @@ func shorterDuration(first, second time.Duration) time.Duration {
244244
// Send notification if the deleted pod was managed by a controller, was a standalone pod that was not completed or was crashlooping
245245
func deletePodsAndCreateNotification(podCtx context.Context, pod corev1.Pod, r *Reconciler, idler *toolchainv1alpha1.Idler) error {
246246
logger := log.FromContext(podCtx)
247-
var podReason string
248-
podCondition := pod.Status.Conditions
249-
for _, podCond := range podCondition {
247+
isCompleted := false
248+
for _, podCond := range pod.Status.Conditions {
250249
if podCond.Type == "Ready" {
251-
podReason = podCond.Reason
250+
isCompleted = podCond.Reason == "PodCompleted"
251+
break
252252
}
253253
}
254254
appType, appName, deletedByController, err := r.scaleControllerToZero(podCtx, pod.ObjectMeta)
255255
if err != nil {
256256
return err
257257
}
258-
if !deletedByController { // Pod not managed by a controller. We can just delete the pod.
258+
if !deletedByController || isCompleted { // Pod not managed by a controller or completed pod. We can just delete the pod.
259259
logger.Info("Deleting pod without controller")
260260
if err := r.AllNamespacesClient.Delete(podCtx, &pod); err != nil {
261261
return err
@@ -267,8 +267,9 @@ func deletePodsAndCreateNotification(podCtx context.Context, pod corev1.Pod, r *
267267
appType = "Pod"
268268
}
269269

270-
// If a build pod is in "PodCompleted" status then it was not running so there's no reason to send an idler notification
271-
if podReason != "PodCompleted" || deletedByController {
270+
// If the pod was in the completed state (it wasn't running) and there was no controller scaled down,
271+
// then there's no reason to send an idler notification
272+
if !isCompleted || deletedByController {
272273
// By now either a pod has been deleted or scaled to zero by controller, idler Triggered notification should be sent
273274
r.notify(podCtx, idler, appName, appType)
274275
}

controllers/idler/idler_controller_test.go

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -360,8 +360,8 @@ func TestEnsureIdling(t *testing.T) {
360360
t.Run("without VM", func(t *testing.T) {
361361
// given
362362
// delete all VM pods
363-
for _, pod := range payloads.controlledPods {
364-
if len(pod.OwnerReferences) > 0 && pod.OwnerReferences[0].Name == payloads.virtualmachineinstance.GetName() {
363+
for _, pod := range payloads.allPods {
364+
if len(pod.OwnerReferences) > 0 && strings.HasPrefix(pod.OwnerReferences[0].Name, payloads.virtualmachineinstance.GetName()) {
365365
require.NoError(t, reconciler.AllNamespacesClient.Delete(context.TODO(), pod))
366366
}
367367
}
@@ -1534,6 +1534,10 @@ func preparePayloadsWithCreateFunc(t *testing.T, clients clientSet, namespace, n
15341534
require.NoError(t, err)
15351535
controlledPods = createPods(t, clients.allNamespacesClient, vmi, &vmstartTime, controlledPods, noRestart()) // vmi controls pod
15361536

1537+
// create completed pods owned by the VM, they should be deleted if timeout is reached
1538+
standalonePods := createPodsWithSuffix(t, "-completed", clients.allNamespacesClient, vmi, &vmstartTime,
1539+
make([]*corev1.Pod, 0, 3), noRestart(), corev1.PodCondition{Type: "Ready", Reason: "PodCompleted"})
1540+
15371541
// Standalone ReplicationController
15381542
standaloneRC := &corev1.ReplicationController{
15391543
ObjectMeta: metav1.ObjectMeta{Name: fmt.Sprintf("%s%s-replicationcontroller", namePrefix, namespace), Namespace: namespace},
@@ -1553,13 +1557,20 @@ func preparePayloadsWithCreateFunc(t *testing.T, clients clientSet, namespace, n
15531557
},
15541558
Spec: toolchainv1alpha1.IdlerSpec{TimeoutSeconds: 30},
15551559
}
1556-
standalonePods := createPods(t, clients.allNamespacesClient, idler, sTime, make([]*corev1.Pod, 0, 3), noRestart())
1560+
standalonePods = slices.Concat(standalonePods, createPods(t, clients.allNamespacesClient, idler, sTime, make([]*corev1.Pod, 0, 3), noRestart()))
15571561

15581562
// Pods with no owner.
15591563
for i := 0; i < 3; i++ {
15601564
pod := &corev1.Pod{
15611565
ObjectMeta: metav1.ObjectMeta{Name: fmt.Sprintf("%s%s-pod-%d", namePrefix, namespace, i), Namespace: namespace},
1562-
Status: corev1.PodStatus{StartTime: sTime},
1566+
Status: corev1.PodStatus{
1567+
StartTime: sTime,
1568+
Conditions: []corev1.PodCondition{{Type: "Ready", Reason: "Running"}},
1569+
},
1570+
}
1571+
// one of them is completed
1572+
if i == 1 {
1573+
pod.Status.Conditions = []corev1.PodCondition{{Type: "Ready", Reason: "PodCompleted"}}
15631574
}
15641575
require.NoError(t, err)
15651576
standalonePods = append(standalonePods, pod)
@@ -1709,9 +1720,13 @@ func restartingUnderThreshold() []corev1.ContainerStatus {
17091720
}
17101721

17111722
func createPods(t *testing.T, allNamespacesClient client.Client, owner metav1.Object, startTime *metav1.Time, podsToTrack []*corev1.Pod, restartStatus []corev1.ContainerStatus, conditions ...corev1.PodCondition) []*corev1.Pod {
1723+
return createPodsWithSuffix(t, "", allNamespacesClient, owner, startTime, podsToTrack, restartStatus, conditions...)
1724+
}
1725+
1726+
func createPodsWithSuffix(t *testing.T, suffix string, allNamespacesClient client.Client, owner metav1.Object, startTime *metav1.Time, podsToTrack []*corev1.Pod, restartStatus []corev1.ContainerStatus, conditions ...corev1.PodCondition) []*corev1.Pod {
17121727
for i := 0; i < 3; i++ {
17131728
pod := &corev1.Pod{
1714-
ObjectMeta: metav1.ObjectMeta{Name: fmt.Sprintf("%s-pod-%d", owner.GetName(), i), Namespace: owner.GetNamespace()},
1729+
ObjectMeta: metav1.ObjectMeta{Name: fmt.Sprintf("%s-pod-%d%s", owner.GetName(), i, suffix), Namespace: owner.GetNamespace()},
17151730
Status: corev1.PodStatus{StartTime: startTime, Conditions: conditions, ContainerStatuses: restartStatus},
17161731
}
17171732
err := controllerutil.SetControllerReference(owner, pod, scheme.Scheme)

0 commit comments

Comments
 (0)