From 59df36dda61e9adfb9ec9534aa3ba1dbcd17c434 Mon Sep 17 00:00:00 2001 From: Daniil Antoshin Date: Mon, 13 Apr 2026 14:34:30 +0200 Subject: [PATCH] fix(core): clarify migration timeout failure message Signed-off-by: Daniil Antoshin --- .../migration/internal/handler/lifecycle.go | 10 ++++++- .../internal/handler/lifecycle_test.go | 27 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/images/virtualization-artifact/pkg/controller/vmop/migration/internal/handler/lifecycle.go b/images/virtualization-artifact/pkg/controller/vmop/migration/internal/handler/lifecycle.go index 93a3f5a3db..9bac41519f 100644 --- a/images/virtualization-artifact/pkg/controller/vmop/migration/internal/handler/lifecycle.go +++ b/images/virtualization-artifact/pkg/controller/vmop/migration/internal/handler/lifecycle.go @@ -508,7 +508,7 @@ func getMessageByMigrationFailedReason(mig *virtv1.VirtualMachineInstanceMigrati case virtv1.VirtualMachineInstanceMigrationFailedReasonVMIDoesNotExist, virtv1.VirtualMachineInstanceMigrationFailedReasonVMIIsShutdown: return "VirtualMachine is stopped" default: - return cond.Message + return humanizeMigrationFailedMessage(cond.Message) } } @@ -678,6 +678,14 @@ func (h LifecycleHandler) forgetProgress(vmop *v1alpha2.VirtualMachineOperation) h.progressStrategy.Forget(vmop.UID) } +func humanizeMigrationFailedMessage(message string) string { + if strings.Contains(message, "unschedulable target pod") && strings.Contains(message, "timeout period expiration") { + return "No available nodes were found to place the target VM within the timeout period" + } + + return message +} + func (h LifecycleHandler) getTargetPod(ctx context.Context, mig *virtv1.VirtualMachineInstanceMigration) (*corev1.Pod, error) { selector, err := metav1.LabelSelectorAsSelector(&metav1.LabelSelector{ MatchLabels: map[string]string{ diff --git a/images/virtualization-artifact/pkg/controller/vmop/migration/internal/handler/lifecycle_test.go b/images/virtualization-artifact/pkg/controller/vmop/migration/internal/handler/lifecycle_test.go index daf098910b..62347ecbf1 100644 --- a/images/virtualization-artifact/pkg/controller/vmop/migration/internal/handler/lifecycle_test.go +++ b/images/virtualization-artifact/pkg/controller/vmop/migration/internal/handler/lifecycle_test.go @@ -902,4 +902,31 @@ var _ = Describe("LifecycleHandler", func() { Expect(reason).To(Equal(vmopcondition.ReasonTargetPreparing)) }) }) + + DescribeTable("humanizeMigrationFailedMessage", func(message, expected string) { + Expect(humanizeMigrationFailedMessage(message)).To(Equal(expected)) + }, + Entry( + "should humanize unschedulable target pod timeout message", + "unschedulable target pod \"virt-launcher-bastion-demo-z7hcs\" was deleted due to timeout period expiration", + "No available nodes were found to place the target VM within the timeout period", + ), + Entry( + "should keep other messages as is", + "some other migration failure", + "some other migration failure", + ), + ) + + It("should use humanized message for migration failed condition", func() { + mig := newSimpleMigration("test", name) + mig.Status.Conditions = []virtv1.VirtualMachineInstanceMigrationCondition{{ + Type: virtv1.VirtualMachineInstanceMigrationFailed, + Status: corev1.ConditionTrue, + Reason: "SomeOtherReason", + Message: "unschedulable target pod \"virt-launcher-bastion-demo-z7hcs\" was deleted due to timeout period expiration", + }} + + Expect(getMessageByMigrationFailedReason(mig)).To(Equal("No available nodes were found to place the target VM within the timeout period")) + }) })