From 182fab8074de9648f522dd3da7a32ea6b64a4e89 Mon Sep 17 00:00:00 2001
From: Liran Rotenberg <lrotenbe@redhat.com>
Date: Wed, 6 Sep 2023 18:22:30 +0300
Subject: [PATCH] Clean importer pods on success

When running with a migration that uses CDI, e.g warm migration, it may
have multiple importer pods. This patch will clean up all of them for
the related VM migrated once the migration completes successfully.

Signed-off-by: Liran Rotenberg <lrotenbe@redhat.com>
---
 pkg/controller/plan/kubevirt.go  | 74 ++++++++++++++++++++++++--------
 pkg/controller/plan/migration.go | 11 ++---
 2 files changed, 63 insertions(+), 22 deletions(-)

diff --git a/pkg/controller/plan/kubevirt.go b/pkg/controller/plan/kubevirt.go
index a2129d994..a0e4cfed1 100644
--- a/pkg/controller/plan/kubevirt.go
+++ b/pkg/controller/plan/kubevirt.go
@@ -219,6 +219,37 @@ func (r *KubeVirt) GetImporterPod(pvc core.PersistentVolumeClaim) (pod *core.Pod
 	return
 }
 
+// Get the importer pods for a PersistentVolumeClaim.
+func (r *KubeVirt) GetImporterPods(pvc core.PersistentVolumeClaim) (pods []core.Pod, found bool, err error) {
+	pods = []core.Pod{}
+	if pvc.Annotations[AnnImporterPodName] == "" {
+		return
+	}
+
+	podList := &core.PodList{}
+
+	err = r.Destination.Client.List(
+		context.TODO(),
+		podList,
+		&client.ListOptions{
+			Namespace:     r.Plan.Spec.TargetNamespace,
+			LabelSelector: labels.SelectorFromSet(map[string]string{"app": "containerized-data-importer"}),
+		},
+	)
+	if err != nil {
+		err = liberr.Wrap(err)
+		return
+	}
+	for _, pod := range podList.Items {
+		if strings.Contains(pod.Name, fmt.Sprintf("importer-%s-%s", r.Plan.Name, pvc.Annotations[kVM])) {
+			pods = append(pods, pod)
+		}
+	}
+
+	found = len(pods) > 0
+	return
+}
+
 // Delete the DataVolumes associated with the VM.
 func (r *KubeVirt) DeleteDataVolumes(vm *plan.VMStatus) (err error) {
 	dvs, err := r.getDVs(vm)
@@ -235,27 +266,36 @@ func (r *KubeVirt) DeleteDataVolumes(vm *plan.VMStatus) (err error) {
 	return
 }
 
-// Delete the importer pod for a PersistentVolumeClaim.
-func (r *KubeVirt) DeleteImporterPod(pvc core.PersistentVolumeClaim) (err error) {
-	var pod *core.Pod
-	var found bool
-	pod, found, err = r.GetImporterPod(pvc)
+// Delete the importer pods for a PersistentVolumeClaim.
+func (r *KubeVirt) DeleteImporterPods(pvc core.PersistentVolumeClaim) (err error) {
+	pods, found, err := r.GetImporterPods(pvc)
 	if err != nil || !found {
 		return
 	}
-	err = r.Destination.Client.Delete(context.TODO(), pod)
-	if err != nil {
-		err = liberr.Wrap(err)
-		return
+	for _, pod := range pods {
+		err = r.Destination.Client.Delete(context.TODO(), &pod)
+		if err != nil {
+			err = liberr.Wrap(err)
+			r.Log.Error(
+				err,
+				"Deleting importer pod failed.",
+				"pod",
+				path.Join(
+					pod.Namespace,
+					pod.Name),
+				"pvc",
+				pvc.Name)
+			continue
+		}
+		r.Log.Info(
+			"Deleted importer pod.",
+			"pod",
+			path.Join(
+				pod.Namespace,
+				pod.Name),
+			"pvc",
+			pvc.Name)
 	}
-	r.Log.Info(
-		"Deleted importer pod.",
-		"pod",
-		path.Join(
-			pod.Namespace,
-			pod.Name),
-		"pvc",
-		pvc.Name)
 	return
 }
 
diff --git a/pkg/controller/plan/migration.go b/pkg/controller/plan/migration.go
index f3f060b1e..7dd96c1e3 100644
--- a/pkg/controller/plan/migration.go
+++ b/pkg/controller/plan/migration.go
@@ -478,7 +478,7 @@ func (r *Migration) deleteImporterPods(vm *plan.VMStatus) (err error) {
 		return
 	}
 	for _, pvc := range pvcs {
-		err = r.kubevirt.DeleteImporterPod(pvc)
+		err = r.kubevirt.DeleteImporterPods(pvc)
 		if err != nil {
 			return
 		}
@@ -748,14 +748,15 @@ func (r *Migration) execute(vm *plan.VMStatus) (err error) {
 		// Removing unnecessary DataVolumes
 		err = r.kubevirt.DeleteDataVolumes(vm)
 		if err != nil {
-			step.AddError(err.Error())
-			err = nil
-			break
+			err = liberr.Wrap(err)
 		}
 		err = r.kubevirt.DeletePVCConsumerPod(vm)
 		if err != nil {
 			err = liberr.Wrap(err)
-			return
+		}
+		err = r.deleteImporterPods(vm)
+		if err != nil {
+			err = liberr.Wrap(err)
 		}
 		step.MarkCompleted()
 		step.Phase = Completed