From f1152618894113374aaf2562324d23223fad965a Mon Sep 17 00:00:00 2001 From: Po Han Huang Date: Wed, 17 Jun 2026 11:10:43 +0800 Subject: [PATCH] feat: improve clone status (#928) * feat: improve clone status Signed-off-by: pohanhuang * fix: pr comments Signed-off-by: pohanhuang --------- Signed-off-by: pohanhuang --- .../models/kubevirt.io.virtualmachine.js | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/pkg/harvester/models/kubevirt.io.virtualmachine.js b/pkg/harvester/models/kubevirt.io.virtualmachine.js index fd56d43a..db44dffc 100644 --- a/pkg/harvester/models/kubevirt.io.virtualmachine.js +++ b/pkg/harvester/models/kubevirt.io.virtualmachine.js @@ -123,7 +123,12 @@ const IgnoreMessages = ['pod has unbound immediate PersistentVolumeClaims']; export default class VirtVm extends HarvesterResource { get availableActions() { - const out = super._availableActions; + let out = super._availableActions; + + if (this.isCloneBackendStorageCloning || this.isCloneBackendStorageFailed) { + out = out.filter(({ action }) => action !== 'goToClone'); + } + const clone = out.find((action) => action.action === 'goToClone'); if (clone) { @@ -770,6 +775,18 @@ export default class VirtVm extends HarvesterResource { return this.volumes.filter((volume) => volume?.isLonghornV2); } + get cloneBackendStorageStatus() { + return this.metadata?.annotations?.[HCI_ANNOTATIONS.CLONE_BACKEND_STORAGE_STATUS]?.toLowerCase() || ''; + } + + get isCloneBackendStorageCloning() { + return this.cloneBackendStorageStatus === 'cloning'; + } + + get isCloneBackendStorageFailed() { + return this.cloneBackendStorageStatus === 'failed'; + } + get encryptedVolumeType() { if (!this.volumes || this.volumes.length === 0) { return 'none'; @@ -825,13 +842,21 @@ export default class VirtVm extends HarvesterResource { !this.isVMExpectedRunning && this.isVMCreated && this.vmi?.status?.phase === VMIPhase.Pending - ) || (this.metadata?.annotations?.[HCI_ANNOTATIONS.CLONE_BACKEND_STORAGE_STATUS] === 'cloning')) { + ) || this.isCloneBackendStorageCloning) { return { status: VMIPhase.Pending }; } return null; } + get isCloneFailed() { + if (this.isCloneBackendStorageFailed) { + return { status: VMIPhase.Failed }; + } + + return null; + } + get isStopping() { if (this && !this.isVMExpectedRunning && @@ -988,6 +1013,7 @@ export default class VirtVm extends HarvesterResource { this.isUnschedulable?.status || this.isPaused?.status || this.isVMError?.status || + this.isCloneFailed?.status || this.isPending?.status || this.isStopping?.status || this.isOff?.status || @@ -995,7 +1021,7 @@ export default class VirtVm extends HarvesterResource { this.isRunning?.status || this.isNotReady?.status || this.isStarting?.status || - this.isWaitingForVMI?.state || + this.isWaitingForVMI?.status || this.otherState?.status; return state;