Skip to content

Commit ca5ca50

Browse files
committed
fixup! [control-operator] finalizer blocks deletion of task until all pods are gone
1 parent 9b26f2a commit ca5ca50

1 file changed

Lines changed: 50 additions & 38 deletions

File tree

control-operator/internal/controller/task_controller.go

Lines changed: 50 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -270,53 +270,65 @@ func (r *TaskReconciler) consumeGRPCConsumerIfReady(ctx context.Context, t *alie
270270
return ctrl.Result{}
271271
}
272272

273+
// handleFinalizer sets the finalizer, when Task isn't marked for deletion, and when deletion reconcile is triggered
274+
// it then clears the gRPC connection and deletes the underlying POD and doesn't allow Task to be deleted
275+
// until POD is gone.
273276
// Note: if you add finalizer to a task you cannot delete it unless you remove the finalizer, run:
274277
// kubectl patch task --type=json -p='[{"op": "remove", "path": "/metadata/finalizers"}]'
275278
func (r *TaskReconciler) handleFinalizer(ctx context.Context, t *aliecsv1alpha1.Task, log logr.Logger) (ctrl.Result, bool, error) {
276279
if t.DeletionTimestamp.IsZero() {
277-
if !controllerutil.ContainsFinalizer(t, taskFinalizer) {
278-
controllerutil.AddFinalizer(t, taskFinalizer)
279-
if err := r.Update(ctx, t); err != nil {
280-
return ctrl.Result{}, true, err
281-
}
282-
return ctrl.Result{}, true, nil
280+
if controllerutil.AddFinalizer(t, taskFinalizer) {
281+
return ctrl.Result{}, true, r.Update(ctx, t)
283282
}
284-
} else {
285-
if controllerutil.ContainsFinalizer(t, taskFinalizer) {
286-
log.Info("Finalizer found, starting cleanup")
287-
if client, exists := clientsForContainers[t.Name]; exists {
288-
log.Info("Cleaning up gRPC connection before deletion")
289-
if err := client.Close(); err != nil {
290-
log.Error(err, "Failed to close gRPC client during deletion")
291-
}
292-
delete(clientsForContainers, t.Name)
293-
log.Info("gRPC cleaned")
294-
}
283+
return ctrl.Result{}, false, nil
284+
}
295285

296-
pod := &v1.Pod{}
297-
err := r.Get(ctx, types.NamespacedName{Name: podNameFromTask(t.Name), Namespace: t.Namespace}, pod)
298-
if err == nil {
299-
if pod.DeletionTimestamp.IsZero() {
300-
log.Info("Deleting pod before removing finalizer")
301-
if err := r.Delete(ctx, pod); err != nil && !errors.IsNotFound(err) {
302-
return ctrl.Result{}, true, err
303-
}
304-
}
305-
log.Info("Waiting for pod to terminate before removing finalizer")
306-
return ctrl.Result{}, true, nil
307-
} else if !errors.IsNotFound(err) {
308-
return ctrl.Result{}, true, err
309-
}
310-
log.Info("POD cleaned")
286+
if !controllerutil.ContainsFinalizer(t, taskFinalizer) {
287+
return ctrl.Result{}, true, nil
288+
}
311289

312-
controllerutil.RemoveFinalizer(t, taskFinalizer)
313-
if err := r.Update(ctx, t); err != nil {
314-
return ctrl.Result{}, true, err
315-
}
290+
log.Info("Finalizer found, starting cleanup")
291+
r.cleargRPC(t, log)
292+
293+
if podGone, err := r.podDeleted(ctx, t, log); err != nil || !podGone {
294+
return ctrl.Result{}, true, err
295+
}
296+
297+
controllerutil.RemoveFinalizer(t, taskFinalizer)
298+
return ctrl.Result{}, true, r.Update(ctx, t)
299+
}
300+
301+
// podDeleted deletes the Task's Pod if it still exists, and reports whether it is
302+
// fully gone yet so the caller can wait for termination before removing the finalizer.
303+
func (r *TaskReconciler) podDeleted(ctx context.Context, t *aliecsv1alpha1.Task, log logr.Logger) (bool, error) {
304+
pod := &v1.Pod{}
305+
err := r.Get(ctx, types.NamespacedName{Name: podNameFromTask(t.Name), Namespace: t.Namespace}, pod)
306+
if errors.IsNotFound(err) {
307+
log.Info("POD cleaned")
308+
return true, nil
309+
} else if err != nil {
310+
return false, err
311+
}
312+
313+
if pod.DeletionTimestamp.IsZero() {
314+
log.Info("Deleting pod before removing finalizer")
315+
if err := r.Delete(ctx, pod); err != nil && !errors.IsNotFound(err) {
316+
return false, err
316317
}
317-
return ctrl.Result{}, true, nil
318318
}
319-
return ctrl.Result{}, false, nil
319+
log.Info("Waiting for pod to terminate before removing finalizer")
320+
return false, nil
321+
}
322+
323+
func (*TaskReconciler) cleargRPC(t *aliecsv1alpha1.Task, log logr.Logger) {
324+
if client, exists := clientsForContainers[t.Name]; exists {
325+
log.Info("Cleaning up gRPC connection")
326+
if err := client.Close(); err != nil {
327+
log.Error(err, "Failed to close gRPC client during deletion")
328+
}
329+
delete(clientsForContainers, t.Name)
330+
log.Info("gRPC cleaned")
331+
}
320332
}
321333

322334
func podNameFromTask(name string) string {

0 commit comments

Comments
 (0)