From d7744c4d2869aef93195e74c5ac6731246ad7449 Mon Sep 17 00:00:00 2001 From: Daniil Loktev Date: Thu, 21 May 2026 20:07:57 +0300 Subject: [PATCH 1/6] wip Signed-off-by: Daniil Loktev --- api/core/v1alpha2/vmopcondition/condition.go | 8 +++++++ .../migration/internal/handler/lifecycle.go | 5 +++- .../internal/handler/lifecycle_test.go | 24 +++++++++++++++++++ .../monitoring/metrics/vmop/data_metric.go | 14 ++++++----- 4 files changed, 44 insertions(+), 7 deletions(-) diff --git a/api/core/v1alpha2/vmopcondition/condition.go b/api/core/v1alpha2/vmopcondition/condition.go index 9326c306ec..ee996741d9 100644 --- a/api/core/v1alpha2/vmopcondition/condition.go +++ b/api/core/v1alpha2/vmopcondition/condition.go @@ -98,6 +98,14 @@ const ( // ReasonTargetDiskError indicates that target disk attachment failed. ReasonTargetDiskError ReasonCompleted = "TargetDiskError" + // ReasonTargetHandlerShutdown indicates that virt-handler on the target node + // was shut down during the live migration, breaking the migration proxy channel. + ReasonTargetHandlerShutdown ReasonCompleted = "TargetHandlerShutdown" + + // ReasonSourceHandlerShutdown indicates that virt-handler on the source node + // was shut down during the live migration, breaking the migration proxy channel. + ReasonSourceHandlerShutdown ReasonCompleted = "SourceHandlerShutdown" + // ReasonTargetPreparing indicates that target pod is being prepared. ReasonTargetPreparing ReasonCompleted = "TargetPreparing" 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 9bb21ce859..68e713ecb7 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 @@ -527,6 +527,9 @@ func (h LifecycleHandler) getFailedReason(mig *virtv1.VirtualMachineInstanceMigr if state.AbortRequested || state.AbortStatus == virtv1.MigrationAbortSucceeded { return vmopcondition.ReasonAborted } + if reason := vmopcondition.ReasonCompleted(state.FailureReason); reason == vmopcondition.ReasonTargetHandlerShutdown || reason == vmopcondition.ReasonSourceHandlerShutdown { + return reason + } if strings.Contains(strings.ToLower(state.FailureReason), "converg") || strings.Contains(strings.ToLower(state.FailureReason), "progress") { return vmopcondition.ReasonNotConverging } @@ -548,7 +551,7 @@ func (h LifecycleHandler) getFailedReason(mig *virtv1.VirtualMachineInstanceMigr func (h LifecycleHandler) getFailedMessage(reason vmopcondition.ReasonCompleted, mig *virtv1.VirtualMachineInstanceMigration) string { base := "Migration failed" switch reason { - case vmopcondition.ReasonAborted: + case vmopcondition.ReasonAborted, vmopcondition.ReasonTargetHandlerShutdown, vmopcondition.ReasonSourceHandlerShutdown: base = "Migration aborted" case vmopcondition.ReasonNotConverging: base = "Migration did not converge" 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 e821efab49..3e1b8accac 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 @@ -362,12 +362,36 @@ var _ = Describe("LifecycleHandler", func() { &virtv1.VirtualMachineInstanceMigration{Status: virtv1.VirtualMachineInstanceMigrationStatus{Conditions: []virtv1.VirtualMachineInstanceMigrationCondition{{Type: virtv1.VirtualMachineInstanceMigrationFailed, Reason: "VolumeAttach", Message: "csi volume attach failed"}}}}, vmopcondition.ReasonTargetDiskError, ), + Entry("target virt-handler shutdown from failure reason", + &virtv1.VirtualMachineInstanceMigration{Status: virtv1.VirtualMachineInstanceMigrationStatus{MigrationState: &virtv1.VirtualMachineInstanceMigrationState{FailureReason: vmopcondition.ReasonTargetHandlerShutdown.String()}}}, + vmopcondition.ReasonTargetHandlerShutdown, + ), + Entry("source virt-handler shutdown from failure reason", + &virtv1.VirtualMachineInstanceMigration{Status: virtv1.VirtualMachineInstanceMigrationStatus{MigrationState: &virtv1.VirtualMachineInstanceMigrationState{FailureReason: vmopcondition.ReasonSourceHandlerShutdown.String()}}}, + vmopcondition.ReasonSourceHandlerShutdown, + ), Entry("generic failed reason", &virtv1.VirtualMachineInstanceMigration{}, vmopcondition.ReasonFailed, ), ) + DescribeTable("should render handler-shutdown failure message", func(reason vmopcondition.ReasonCompleted, mig *virtv1.VirtualMachineInstanceMigration, expected string) { + h := LifecycleHandler{} + Expect(h.getFailedMessage(reason, mig)).To(Equal(expected)) + }, + Entry("target shutdown", + vmopcondition.ReasonTargetHandlerShutdown, + &virtv1.VirtualMachineInstanceMigration{Status: virtv1.VirtualMachineInstanceMigrationStatus{MigrationState: &virtv1.VirtualMachineInstanceMigrationState{TargetNode: "worker-1", FailureReason: vmopcondition.ReasonTargetHandlerShutdown.String()}}}, + "Migration aborted: TargetHandlerShutdown", + ), + Entry("source shutdown", + vmopcondition.ReasonSourceHandlerShutdown, + &virtv1.VirtualMachineInstanceMigration{Status: virtv1.VirtualMachineInstanceMigrationStatus{MigrationState: &virtv1.VirtualMachineInstanceMigrationState{SourceNode: "master-0", FailureReason: vmopcondition.ReasonSourceHandlerShutdown.String()}}}, + "Migration aborted: SourceHandlerShutdown", + ), + ) + DescribeTable("should build in-progress reason and message", func( phase virtv1.VirtualMachineInstanceMigrationPhase, state *virtv1.VirtualMachineInstanceMigrationState, diff --git a/images/virtualization-artifact/pkg/monitoring/metrics/vmop/data_metric.go b/images/virtualization-artifact/pkg/monitoring/metrics/vmop/data_metric.go index e9d55dff69..aaccbd65ff 100644 --- a/images/virtualization-artifact/pkg/monitoring/metrics/vmop/data_metric.go +++ b/images/virtualization-artifact/pkg/monitoring/metrics/vmop/data_metric.go @@ -42,12 +42,14 @@ var successfulTerminalReasons = map[string]struct{}{ } var failedTerminalReasons = map[string]struct{}{ - vmopcondition.ReasonOperationFailed.String(): {}, - vmopcondition.ReasonFailed.String(): {}, - vmopcondition.ReasonAborted.String(): {}, - vmopcondition.ReasonNotConverging.String(): {}, - vmopcondition.ReasonTargetUnschedulable.String(): {}, - vmopcondition.ReasonTargetDiskError.String(): {}, + vmopcondition.ReasonOperationFailed.String(): {}, + vmopcondition.ReasonFailed.String(): {}, + vmopcondition.ReasonAborted.String(): {}, + vmopcondition.ReasonNotConverging.String(): {}, + vmopcondition.ReasonTargetUnschedulable.String(): {}, + vmopcondition.ReasonTargetDiskError.String(): {}, + vmopcondition.ReasonTargetHandlerShutdown.String(): {}, + vmopcondition.ReasonSourceHandlerShutdown.String(): {}, } // DO NOT mutate VirtualMachineOperation! From 36f9b8b34cd7f4ca1978d882013d6a91614909ca Mon Sep 17 00:00:00 2001 From: Daniil Loktev Date: Thu, 21 May 2026 20:10:10 +0300 Subject: [PATCH 2/6] change kubevirt ref Signed-off-by: Daniil Loktev --- build/components/versions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/components/versions.yml b/build/components/versions.yml index a22d26fe03..bacef49961 100644 --- a/build/components/versions.yml +++ b/build/components/versions.yml @@ -3,7 +3,7 @@ firmware: libvirt: v10.9.0 edk2: stable202411 core: - 3p-kubevirt: v1.6.2-v12n.34 + 3p-kubevirt: feat/virt-handler/handler-shutdown-migration-reason 3p-containerized-data-importer: v1.60.3-v12n.19 distribution: 2.8.3 package: From a2ff903fba20781a491b5119995271206460b629 Mon Sep 17 00:00:00 2001 From: Daniil Loktev Date: Thu, 21 May 2026 20:35:07 +0300 Subject: [PATCH 3/6] add fromCacheVersion Signed-off-by: Daniil Loktev --- images/virt-artifact/werf.inc.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index 6381ba5eae..9f9795bb88 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -9,6 +9,7 @@ image: {{ .ModuleNamePrefix }}{{ .ImageName }}-src-artifact final: false fromImage: builder/src +fromCacheVersion: 21-05" secrets: - id: SOURCE_REPO value: {{ $.SOURCE_REPO }} @@ -44,6 +45,7 @@ packages: image: {{ .ModuleNamePrefix }}{{ .ImageName }} final: false fromImage: {{ eq $.SVACE_ENABLED "false" | ternary "builder/golang-alt-1.25" "builder/golang-alt-svace-1.25" }} +fromCacheVersion: 21-05" mount: {{- include "mount points for golang builds" . }} secrets: From 06cab3a301792b20e5bfe3d166ed8dcb262044ce Mon Sep 17 00:00:00 2001 From: Daniil Loktev Date: Thu, 21 May 2026 23:06:08 +0300 Subject: [PATCH 4/6] wip Signed-off-by: Daniil Loktev --- images/virt-artifact/werf.inc.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index 9f9795bb88..48a24ef0af 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -9,7 +9,7 @@ image: {{ .ModuleNamePrefix }}{{ .ImageName }}-src-artifact final: false fromImage: builder/src -fromCacheVersion: 21-05" +fromCacheVersion: 21-05-3" secrets: - id: SOURCE_REPO value: {{ $.SOURCE_REPO }} @@ -45,7 +45,7 @@ packages: image: {{ .ModuleNamePrefix }}{{ .ImageName }} final: false fromImage: {{ eq $.SVACE_ENABLED "false" | ternary "builder/golang-alt-1.25" "builder/golang-alt-svace-1.25" }} -fromCacheVersion: 21-05" +fromCacheVersion: 21-05-3" mount: {{- include "mount points for golang builds" . }} secrets: From a9188572b720bbf0833a3e98249531a7e24fff4e Mon Sep 17 00:00:00 2001 From: Daniil Loktev Date: Fri, 22 May 2026 20:03:20 +0300 Subject: [PATCH 5/6] wip Signed-off-by: Daniil Loktev --- images/virt-artifact/werf.inc.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index 48a24ef0af..440ea50723 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -9,7 +9,7 @@ image: {{ .ModuleNamePrefix }}{{ .ImageName }}-src-artifact final: false fromImage: builder/src -fromCacheVersion: 21-05-3" +fromCacheVersion: 21-05-5" secrets: - id: SOURCE_REPO value: {{ $.SOURCE_REPO }} @@ -45,7 +45,7 @@ packages: image: {{ .ModuleNamePrefix }}{{ .ImageName }} final: false fromImage: {{ eq $.SVACE_ENABLED "false" | ternary "builder/golang-alt-1.25" "builder/golang-alt-svace-1.25" }} -fromCacheVersion: 21-05-3" +fromCacheVersion: 21-05-5" mount: {{- include "mount points for golang builds" . }} secrets: From 1864ad2fcf3fc05c6457e74862b241664b569426 Mon Sep 17 00:00:00 2001 From: Daniil Loktev Date: Tue, 26 May 2026 11:11:53 +0300 Subject: [PATCH 6/6] bump cache Signed-off-by: Daniil Loktev --- images/virt-artifact/werf.inc.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index 440ea50723..d27127f5f4 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -9,7 +9,7 @@ image: {{ .ModuleNamePrefix }}{{ .ImageName }}-src-artifact final: false fromImage: builder/src -fromCacheVersion: 21-05-5" +fromCacheVersion: 21-05-6" secrets: - id: SOURCE_REPO value: {{ $.SOURCE_REPO }} @@ -45,7 +45,7 @@ packages: image: {{ .ModuleNamePrefix }}{{ .ImageName }} final: false fromImage: {{ eq $.SVACE_ENABLED "false" | ternary "builder/golang-alt-1.25" "builder/golang-alt-svace-1.25" }} -fromCacheVersion: 21-05-5" +fromCacheVersion: 21-05-6" mount: {{- include "mount points for golang builds" . }} secrets: