Repository: kubevirt-ui/kubevirt-plugin
Pull request #2585: CNV-58541: use only MTC migrations
Author: login: upalatucci
Labels: name: lgtm
description: Passed code review, ready for merge
name: approved
description: This issue is something we want to fix
name: jira/valid-reference
Created: 2025-04-16T09:49:15Z | Merged: 2025-05-05T18:15:52Z

<!---
Thanks for creating a Pull Request 💖!

Please read the following before submitting:
- PRs that adds new external dependencies might take a while to review.
- Keep your PR as small as possible.
- Limit your PR to one type (feature, refactoring, ci, or bugfix)
-->

## 📝 Description

The storage migration will be available only if MTC is installed

The old method using `updateVolumesStrategy` is removed

This means that all storageclass can be used and all pvcs can be migrated

the migplan do not support `rollback` and `migrateState` specs together. only one of the two. So rollabcking means to remove the `migrateState` and put the `rollback` state

## 🎥 Demo

IF MTC IS NOT INSTALLED


<img width="1920" alt="Screenshot 2025-05-05 at 13 03 42" src="https://github.com/user-attachments/assets/faa9e559-b668-46a1-8e1e-ccd44596875c" />
<img width="1920" alt="Screenshot 2025-05-05 at 13 03 51" src="https://github.com/user-attachments/assets/8c50e878-3244-4272-9e03-6789c0e06215" />



MTC migration

<img width="1920" alt="Screenshot 2025-05-05 at 12 53 58" src="https://github.com/user-attachments/assets/6ba27eb4-2946-436c-b582-2ba749b5a3b3" />


This should also resolve https://issues.redhat.com/browse/CNV-61006



Diff:
diff --git a/locales/en/plugin__kubevirt-plugin.json b/locales/en/plugin__kubevirt-plugin.json
index cb0d866342..520013045a 100644
--- a/locales/en/plugin__kubevirt-plugin.json
+++ b/locales/en/plugin__kubevirt-plugin.json
@@ -1478,7 +1478,6 @@
   "View and manage available bootable volumes.": "View and manage available bootable volumes.",
   "View diagnostic": "View diagnostic",
   "View events": "View events",
-  "View logs": "View logs",
   "View matching {{matchingNodeText}}": "View matching {{matchingNodeText}}",
   "View matching {{matchingProjectText}}": "View matching {{matchingProjectText}}",
   "View more": "View more",
@@ -1486,6 +1485,7 @@
   "View Persistent Volume Claim details": "View Persistent Volume Claim details",
   "View PersistentVolumeClaim details": "View PersistentVolumeClaim details",
   "View pod logs": "View pod logs",
+  "View storage migrations": "View storage migrations",
   "View virtualization dashboard": "View virtualization dashboard",
   "View YAML & CLI": "View YAML & CLI",
   "Virtctl is disabled for this namespace as it's managed by": "Virtctl is disabled for this namespace as it's managed by",
diff --git a/src/utils/resources/vm/utils/source.ts b/src/utils/resources/vm/utils/source.ts
index b147bb1813..52412979ff 100644
--- a/src/utils/resources/vm/utils/source.ts
+++ b/src/utils/resources/vm/utils/source.ts
@@ -141,3 +141,12 @@ export const vmBootDiskSourceIsRegistry = (vm: V1VirtualMachine) => {
   const rootDataVolumeTemplateSpec = getRootDataVolumeTemplateSpec(vm);
   return Boolean(rootDataVolumeTemplateSpec?.spec?.source?.registry);
 };
+
+export const getVMPVCNames = (vm: V1VirtualMachine) =>
+  getVolumes(vm)?.reduce((acc, volume) => {
+    const pvcName = volume.persistentVolumeClaim?.claimName || volume.dataVolume?.name;
+    if (pvcName) {
+      acc.push(pvcName);
+    }
+    return acc;
+  }, [] as string[]);
diff --git a/src/views/virtualmachines/actions/VirtualMachineActionFactory.tsx b/src/views/virtualmachines/actions/VirtualMachineActionFactory.tsx
index 833754563b..49e8d274aa 100644
--- a/src/views/virtualmachines/actions/VirtualMachineActionFactory.tsx
+++ b/src/views/virtualmachines/actions/VirtualMachineActionFactory.tsx
@@ -13,6 +13,11 @@ import CloneVMModal from '@kubevirt-utils/components/CloneVMModal/CloneVMModal';
 import { ModalComponent } from '@kubevirt-utils/components/ModalProvider/ModalProvider';
 import SnapshotModal from '@kubevirt-utils/components/SnapshotModal/SnapshotModal';
 import { t } from '@kubevirt-utils/hooks/useKubevirtTranslation';
+import {
+  DEFAULT_MIGRATION_NAMESPACE,
+  MigMigration,
+  MigMigrationModel,
+} from '@kubevirt-utils/resources/migrations/constants';
 import { asAccessReview, getNamespace } from '@kubevirt-utils/resources/shared';
 import { getVMSSHSecretName } from '@kubevirt-utils/resources/vm';
 import { isEmpty } from '@kubevirt-utils/utils/utils';
@@ -38,7 +43,6 @@ import {
   migrateVM,
   pauseVM,
   restartVM,
-  rollbackStorageMigration,
   startVM,
   stopVM,
   unpauseVM,
@@ -76,23 +80,23 @@ export const VirtualMachineActionFactory = {
       label: t('Cancel compute migration'),
     };
   },
-  cancelStorageMigration: (
-    vm: V1VirtualMachine,
-    vmim: V1VirtualMachineInstanceMigration,
-    isSingleNodeCluster: boolean,
-  ): Action => {
+  cancelStorageMigration: (currentStorageMigration: MigMigration): Action => {
     return {
       accessReview: {
-        group: VirtualMachineModel.apiGroup,
-        namespace: vm?.metadata?.namespace,
-        resource: VirtualMachineModel.plural,
+        group: MigMigrationModel.apiGroup,
+        namespace: DEFAULT_MIGRATION_NAMESPACE,
+        resource: MigMigrationModel.plural,
         verb: 'patch',
       },
-      cta: () => {
-        cancelMigration(vmim);
-        return rollbackStorageMigration(vm);
-      },
-      disabled: isSingleNodeCluster,
+      cta: () =>
+        k8sPatch({
+          data: [
+            { op: 'replace', path: '/spec/rollback', value: true },
+            { op: 'remove', path: '/spec/migrateState' },
+          ],
+          model: MigMigrationModel,
+          resource: currentStorageMigration,
+        }),
       id: 'vm-action-cancel-storage-migrate',
       label: t('Cancel storage migration'),
     };
diff --git a/src/views/virtualmachines/actions/actions.ts b/src/views/virtualmachines/actions/actions.ts
index a974fd78ae..c1f052862c 100644
--- a/src/views/virtualmachines/actions/actions.ts
+++ b/src/views/virtualmachines/actions/actions.ts
@@ -8,20 +8,14 @@ import {
   V1VirtualMachine,
   V1VirtualMachineInstanceMigration,
 } from '@kubevirt-ui/kubevirt-api/kubevirt';
-import { getNamespace } from '@kubevirt-utils/resources/shared';
-import { getUpdateStrategy } from '@kubevirt-utils/resources/vm';
-import { isEmpty, kubevirtConsole } from '@kubevirt-utils/utils/utils';
+import { kubevirtConsole } from '@kubevirt-utils/utils/utils';
 import {
   consoleFetch,
   k8sCreate,
   k8sDelete,
   K8sModel,
-  k8sPatch,
-  Patch,
 } from '@openshift-console/dynamic-plugin-sdk';
 
-import { createRollbackPatchData, deleteUnusedDataVolumes } from './utils';
-
 const generateRandomString = () => Math.random().toString(36).substring(2, 7);
 
 export enum VMActionType {
@@ -116,22 +110,3 @@ export const deleteVM = async (vm: V1VirtualMachine) => {
     resource: vm,
   });
 };
-
-export const rollbackStorageMigration = async (vm: V1VirtualMachine) => {
-  if (isEmpty(getUpdateStrategy(vm))) return;
-
-  const patchData: Patch[] = createRollbackPatchData(vm);
-
-  patchData.push({
-    op: 'remove',
-    path: '/spec/updateVolumesStrategy',
-  });
-
-  await k8sPatch<V1VirtualMachine>({
-    data: patchData,
-    model: VirtualMachineModel,
-    resource: vm,
-  });
-
-  deleteUnusedDataVolumes(vm, getNamespace(vm));
-};
diff --git a/src/views/virtualmachines/actions/components/VirtualMachineMigration/BulkVirtualMachineMigrationStatus.tsx b/src/views/virtualmachines/actions/components/VirtualMachineMigration/BulkVirtualMachineMigrationStatus.tsx
deleted file mode 100644
index 775f83ba27..0000000000
--- a/src/views/virtualmachines/actions/components/VirtualMachineMigration/BulkVirtualMachineMigrationStatus.tsx
+++ /dev/null
@@ -1,117 +0,0 @@
-import React, { FC, useState } from 'react';
-
-import ErrorAlert from '@kubevirt-utils/components/ErrorAlert/ErrorAlert';
-import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation';
-import { Timestamp } from '@openshift-console/dynamic-plugin-sdk';
-import {
-  ActionList,
-  ActionListItem,
-  Button,
-  ButtonVariant,
-  DescriptionList,
-  DescriptionListDescription,
-  DescriptionListGroup,
-  DescriptionListTerm,
-} from '@patternfly/react-core';
-import { CloseIcon } from '@patternfly/react-icons';
-
-import {
-  MigMigration,
-  MigMigrationStatuses,
-} from '../../../../../utils/resources/migrations/constants';
-
-import useProgressMigration from './hooks/useProgressMigration';
-import { getMigMigrationStatusLabel } from './utils/utils';
-import VirtualMachineMigrationRollback from './VirtualMachineMigrationRollback';
-
-type BulkVirtualMachineMigrationStatusProps = {
-  migMigration: MigMigration;
-  onClose: () => void;
-};
-
-const BulkVirtualMachineMigrationStatus: FC<BulkVirtualMachineMigrationStatusProps> = ({
-  migMigration,
-  onClose,
-}) => {
-  const { t } = useKubevirtTranslation();
-  const [rollbacking, setRollbacking] = useState(false);
-
-  const {
-    completedMigrationTimestamp,
-    creationTimestamp,
-    error: fetchingError,
-    status,
-  } = useProgressMigration(migMigration);
-
-  const migrationCompleted = status === MigMigrationStatuses.Completed;
-
-  if (rollbacking)
-    return (
-      <VirtualMachineMigrationRollback
-        migMigration={migMigration}
-        onClose={onClose}
-        onContinue={() => setRollbacking(false)}
-      />
-    );
-
-  return (
-    <div className="pf-v6-c-wizard migration-status">
-      <div className="pf-v6-c-wizard__header">
-        <div className="pf-v6-c-wizard__close">
-          <Button
-            aria-label={t('Close')}
-            icon={<CloseIcon />}
-            onClick={onClose}
-            variant={ButtonVariant.plain}
-          />
-        </div>
-        <div className="pf-v6-c-wizard__title">
-          <h2 className="pf-v6-c-wizard__title-text">{t('Migrate VirtualMachines storage')}</h2>
-        </div>
-        <div className="pf-v6-c-wizard__description">
-          {t('Migrate VirtualMachine storage to a different StorageClass.')}
-        </div>
-      </div>
-
-      <DescriptionList className="migration-status__body">
-        <DescriptionListGroup>
-          <DescriptionListTerm>{getMigMigrationStatusLabel(status)}</DescriptionListTerm>
-        </DescriptionListGroup>
-
-        <DescriptionListGroup>
-          <DescriptionListTerm>{t('Started on')}</DescriptionListTerm>
-          <DescriptionListDescription>
-            {creationTimestamp ? <Timestamp timestamp={creationTimestamp} /> : t('Not started yet')}
-          </DescriptionListDescription>
-        </DescriptionListGroup>
-
-        <DescriptionListGroup>
-          <DescriptionListTerm>{t('Status')}</DescriptionListTerm>
-          <DescriptionListDescription>
-            {status || t('Requested')}
-
-            {migrationCompleted && (
-              <>
-                {t('Migrated at')} <Timestamp timestamp={completedMigrationTimestamp} />{' '}
-              </>
-            )}
-
-            <ErrorAlert error={fetchingError} />
-          </DescriptionListDescription>
-        </DescriptionListGroup>
-      </DescriptionList>
-
-      <ActionList>
-        <ActionListItem>
-          {!migrationCompleted && (
-            <Button onClick={() => setRollbacking(true)} variant={ButtonVariant.secondary}>
-              {t('Stop')}
-            </Button>
-          )}
-        </ActionListItem>
-      </ActionList>
-    </div>
-  );
-};
-
-export default BulkVirtualMachineMigrationStatus;
diff --git a/src/views/virtualmachines/actions/components/VirtualMachineMigration/VirtualMachineMigrationModal.tsx b/src/views/virtualmachines/actions/components/VirtualMachineMigration/VirtualMachineMigrationModal.tsx
index 1a0b759016..c3dd39bfff 100644
--- a/src/views/virtualmachines/actions/components/VirtualMachineMigration/VirtualMachineMigrationModal.tsx
+++ b/src/views/virtualmachines/actions/components/VirtualMachineMigration/VirtualMachineMigrationModal.tsx
@@ -17,7 +17,6 @@ import VirtualMachineMigrationDestinationTab from './tabs/VirtualMachineMigratio
 import VirtualMachineMigrationDetails from './tabs/VirtualMachineMigrationDetails';
 import VirtualMachineMigrationReviewTab from './tabs/VirtualMachineMigrationReviewTab';
 import { entireVMSelected, getMigratableVMPVCs } from './utils/utils';
-import BulkVirtualMachineMigrationStatus from './BulkVirtualMachineMigrationStatus';
 import VirtualMachineMigrationStatus from './VirtualMachineMigrationStatus';
 
 import './virtual-machine-migration-modal.scss';
@@ -90,15 +89,9 @@ const VirtualMachineMigrateModal: FC<VirtualMachineMigrateModalProps> = ({
     >
       <ModalBody>
         <StateHandler error={loadingError} loaded>
-          {migrationStarted && migMigration && (
-            <BulkVirtualMachineMigrationStatus migMigration={migMigration} onClose={onClose} />
-          )}
-
-          {migrationStarted && isEmpty(migMigration) && (
-            <VirtualMachineMigrationStatus onClose={onClose} vm={vms?.[0]} />
-          )}
-
-          {!migrationStarted && (
+          {migrationStarted ? (
+            <VirtualMachineMigrationStatus migMigration={migMigration} onClose={onClose} />
+          ) : (
             <Wizard
               header={
                 <WizardHeader
diff --git a/src/views/virtualmachines/actions/components/VirtualMachineMigration/VirtualMachineMigrationRollback.tsx b/src/views/virtualmachines/actions/components/VirtualMachineMigration/VirtualMachineMigrationRollback.tsx
index d96e933c5a..01522d8fff 100644
--- a/src/views/virtualmachines/actions/components/VirtualMachineMigration/VirtualMachineMigrationRollback.tsx
+++ b/src/views/virtualmachines/actions/components/VirtualMachineMigration/VirtualMachineMigrationRollback.tsx
@@ -1,7 +1,6 @@
 import React, { FC, useState } from 'react';
 import { Trans } from 'react-i18next';
 
-import { V1VirtualMachine } from '@kubevirt-ui/kubevirt-api/kubevirt';
 import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation';
 import { k8sPatch } from '@openshift-console/dynamic-plugin-sdk';
 import {
@@ -15,7 +14,6 @@ import {
   Title,
 } from '@patternfly/react-core';
 import { CloseIcon, WarningTriangleIcon } from '@patternfly/react-icons';
-import { rollbackStorageMigration } from '@virtualmachines/actions/actions';
 
 import {
   MigMigration,
@@ -26,14 +24,12 @@ type VirtualMachineMigrationRollbackProps = {
   migMigration?: MigMigration;
   onClose: () => void;
   onContinue: () => void;
-  vm?: V1VirtualMachine;
 };
 
 const VirtualMachineMigrationRollback: FC<VirtualMachineMigrationRollbackProps> = ({
   migMigration,
   onClose,
   onContinue,
-  vm,
 }) => {
   const { t } = useKubevirtTranslation();
   const [loadingRollback, setLoadingRollback] = useState(false);
@@ -43,13 +39,14 @@ const VirtualMachineMigrationRollback: FC<VirtualMachineMigrationRollbackProps>
     setLoadingRollback(true);
 
     try {
-      vm
-        ? await rollbackStorageMigration(vm)
-        : await k8sPatch({
-            data: [{ op: 'replace', path: '/spec/rollback', value: 'true' }],
-            model: MigMigrationModel,
-            resource: migMigration,
-          });
+      await k8sPatch({
+        data: [
+          { op: 'replace', path: '/spec/rollback', value: 'true' },
+          { op: 'remove', path: '/spec/migrateState' },
+        ],
+        model: MigMigrationModel,
+        resource: migMigration,
+      });
       onClose();
     } catch (apiError) {
       setErrorRollback(errorRollback);
diff --git a/src/views/virtualmachines/actions/components/VirtualMachineMigration/VirtualMachineMigrationStatus.tsx b/src/views/virtualmachines/actions/components/VirtualMachineMigration/VirtualMachineMigrationStatus.tsx
index 90a050ca17..7297db3047 100644
--- a/src/views/virtualmachines/actions/components/VirtualMachineMigration/VirtualMachineMigrationStatus.tsx
+++ b/src/views/virtualmachines/actions/components/VirtualMachineMigration/VirtualMachineMigrationStatus.tsx
@@ -1,10 +1,8 @@
 import React, { FC, useState } from 'react';
+import { Link } from 'react-router-dom-v5-compat';
 
-import { V1VirtualMachine } from '@kubevirt-ui/kubevirt-api/kubevirt';
-import ExternalLink from '@kubevirt-utils/components/ExternalLink/ExternalLink';
+import ErrorAlert from '@kubevirt-utils/components/ErrorAlert/ErrorAlert';
 import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation';
-import { getMigrationPod } from '@kubevirt-utils/resources/vmim/selectors';
-import { vmimStatuses } from '@kubevirt-utils/resources/vmim/statuses';
 import { Timestamp } from '@openshift-console/dynamic-plugin-sdk';
 import {
   ActionList,
@@ -18,31 +16,42 @@ import {
 } from '@patternfly/react-core';
 import { CloseIcon } from '@patternfly/react-icons';
 
-import useCurrentStorageMigration from './hooks/useCurrentStorageMigration';
-import { getMigrationStatusLabel, getMigrationSuccessTimestamp } from './utils/utils';
+import {
+  MigMigration,
+  MigMigrationStatuses,
+} from '../../../../../utils/resources/migrations/constants';
+
+import useProgressMigration from './hooks/useProgressMigration';
+import { getMigMigrationStatusLabel } from './utils/utils';
 import VirtualMachineMigrationRollback from './VirtualMachineMigrationRollback';
 
 type VirtualMachineMigrationStatusProps = {
+  migMigration: MigMigration;
   onClose: () => void;
-  vm: V1VirtualMachine;
 };
 
-const VirtualMachineMigrationStatus: FC<VirtualMachineMigrationStatusProps> = ({ onClose, vm }) => {
+const VirtualMachineMigrationStatus: FC<VirtualMachineMigrationStatusProps> = ({
+  migMigration,
+  onClose,
+}) => {
   const { t } = useKubevirtTranslation();
-  const vmim = useCurrentStorageMigration(vm);
   const [rollbacking, setRollbacking] = useState(false);
 
-  const migrationPod = getMigrationPod(vmim);
-  const migrationLogURL = migrationPod && `/k8s/ns/default/pods/${migrationPod}/logs`;
+  const {
+    completedMigrationTimestamp,
+    creationTimestamp,
+    error: fetchingError,
+    status,
+  } = useProgressMigration(migMigration);
 
-  const migrationCompleted = vmimStatuses.Succeeded === vmim?.status?.phase;
+  const migrationCompleted = status === MigMigrationStatuses.Completed;
 
   if (rollbacking)
     return (
       <VirtualMachineMigrationRollback
+        migMigration={migMigration}
         onClose={onClose}
         onContinue={() => setRollbacking(false)}
-        vm={vm}
       />
     );
 
@@ -58,7 +67,7 @@ const VirtualMachineMigrationStatus: FC<VirtualMachineMigrationStatusProps> = ({
           />
         </div>
         <div className="pf-v6-c-wizard__title">
-          <h2 className="pf-v6-c-wizard__title-text">{t('Migrate VirtualMachine storage')}</h2>
+          <h2 className="pf-v6-c-wizard__title-text">{t('Migrate VirtualMachines storage')}</h2>
         </div>
         <div className="pf-v6-c-wizard__description">
           {t('Migrate VirtualMachine storage to a different StorageClass.')}
@@ -67,30 +76,28 @@ const VirtualMachineMigrationStatus: FC<VirtualMachineMigrationStatusProps> = ({
 
       <DescriptionList className="migration-status__body">
         <DescriptionListGroup>
-          <DescriptionListTerm>{getMigrationStatusLabel(vmim)}</DescriptionListTerm>
+          <DescriptionListTerm>{getMigMigrationStatusLabel(status)}</DescriptionListTerm>
         </DescriptionListGroup>
 
         <DescriptionListGroup>
           <DescriptionListTerm>{t('Started on')}</DescriptionListTerm>
           <DescriptionListDescription>
-            {vmim?.metadata?.creationTimestamp ? (
-              <Timestamp timestamp={vmim?.metadata?.creationTimestamp} />
-            ) : (
-              t('Not started yet')
-            )}
+            {creationTimestamp ? <Timestamp timestamp={creationTimestamp} /> : t('Not started yet')}
           </DescriptionListDescription>
         </DescriptionListGroup>
 
         <DescriptionListGroup>
           <DescriptionListTerm>{t('Status')}</DescriptionListTerm>
           <DescriptionListDescription>
-            {vmim?.status?.phase || t('Requested')}
+            {status || t('Requested')}
 
             {migrationCompleted && (
               <>
-                {t('Migrated at')} <Timestamp timestamp={getMigrationSuccessTimestamp(vmim)} />{' '}
+                {t('Migrated at')} <Timestamp timestamp={completedMigrationTimestamp} />{' '}
               </>
             )}
+
+            <ErrorAlert error={fetchingError} />
           </DescriptionListDescription>
         </DescriptionListGroup>
       </DescriptionList>
@@ -103,11 +110,11 @@ const VirtualMachineMigrationStatus: FC<VirtualMachineMigrationStatusProps> = ({
             </Button>
           )}
         </ActionListItem>
-        {migrationLogURL && (
-          <ActionListItem className="migration-status__view-report">
-            <ExternalLink href={migrationLogURL}>{t('View logs')}</ExternalLink>
-          </ActionListItem>
-        )}
+        <ActionListItem className="migration-status__view-report">
+          <Link onClick={onClose} to="/k8s/storagemigrations">
+            {t('View storage migrations')}
+          </Link>
+        </ActionListItem>
       </ActionList>
     </div>
   );
diff --git a/src/views/virtualmachines/actions/components/VirtualMachineMigration/hooks/useMigratableStorageClasses.ts b/src/views/virtualmachines/actions/components/VirtualMachineMigration/hooks/useMigratableStorageClasses.ts
deleted file mode 100644
index 5d8c9e6d42..0000000000
--- a/src/views/virtualmachines/actions/components/VirtualMachineMigration/hooks/useMigratableStorageClasses.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import { V1beta1StorageSpecAccessModesEnum } from '@kubevirt-ui/kubevirt-api/kubevirt';
-import { StorageProfileModelGroupVersionKind } from '@kubevirt-utils/models';
-import { getName } from '@kubevirt-utils/resources/shared';
-import { K8sResourceCommon, useK8sWatchResource } from '@openshift-console/dynamic-plugin-sdk';
-
-const useMigratableStorageClasses = (): string[] => {
-  const [storageProfiles] = useK8sWatchResource<K8sResourceCommon[]>({
-    groupVersionKind: StorageProfileModelGroupVersionKind,
-    isList: true,
-  });
-
-  const allowedStorageProfilesNames = storageProfiles?.reduce((acc, storageProfile: any) => {
-    if (
-      storageProfile?.status?.claimPropertySets?.some((claimProperty) =>
-        claimProperty?.accessModes?.includes(V1beta1StorageSpecAccessModesEnum.ReadWriteMany),
-      )
-    )
-      acc.push(getName(storageProfile));
-
-    return acc;
-  }, []);
-
-  return allowedStorageProfilesNames;
-};
-
-export default useMigratableStorageClasses;
diff --git a/src/views/virtualmachines/actions/components/VirtualMachineMigration/hooks/useMigrationState.ts b/src/views/virtualmachines/actions/components/VirtualMachineMigration/hooks/useMigrationState.ts
index 882759325e..d2b3a97882 100644
--- a/src/views/virtualmachines/actions/components/VirtualMachineMigration/hooks/useMigrationState.ts
+++ b/src/views/virtualmachines/actions/components/VirtualMachineMigration/hooks/useMigrationState.ts
@@ -4,8 +4,7 @@ import { IoK8sApiCoreV1PersistentVolumeClaim } from '@kubevirt-ui/kubevirt-api/k
 import { V1VirtualMachine } from '@kubevirt-ui/kubevirt-api/kubevirt';
 
 import { MigMigration } from '../../../../../../utils/resources/migrations/constants';
-import { migrateBulkVMs } from '../utils/migrateBulkVMs';
-import { migrateVM } from '../utils/migrateVM';
+import { migrateVMs } from '../utils/migrateVMs';
 
 type UseMigrationState = (
   vms: V1VirtualMachine[],
@@ -35,11 +34,7 @@ const useMigrationState: UseMigrationState = (
     setMigrationLoading(true);
     setMigrationError(null);
     try {
-      vms.length === 1
-        ? await migrateVM(vms?.[0], pvcsToMigrate, destinationStorageClass)
-        : setMigMigration(
-            await migrateBulkVMs(vms, namespacePVCs, pvcsToMigrate, destinationStorageClass),
-          );
+      setMigMigration(await migrateVMs(vms, namespacePVCs, pvcsToMigrate, destinationStorageClass));
 
       setMigrationStarted(true);
     } catch (apiError) {
diff --git a/src/views/virtualmachines/actions/components/VirtualMachineMigration/tabs/VirtualMachineMigrationDestinationTab.tsx b/src/views/virtualmachines/actions/components/VirtualMachineMigration/tabs/VirtualMachineMigrationDestinationTab.tsx
index ad700a58c5..e6a7982aba 100644
--- a/src/views/virtualmachines/actions/components/VirtualMachineMigration/tabs/VirtualMachineMigrationDestinationTab.tsx
+++ b/src/views/virtualmachines/actions/components/VirtualMachineMigration/tabs/VirtualMachineMigrationDestinationTab.tsx
@@ -7,8 +7,6 @@ import { POPPER_CONTAINER_ID } from '@kubevirt-utils/utils/constants';
 import { ResourceLink } from '@openshift-console/dynamic-plugin-sdk';
 import { Content, ContentVariants, Label, Stack, StackItem, Title } from '@patternfly/react-core';
 
-import useMigratableStorageClasses from '../hooks/useMigratableStorageClasses';
-
 type VirtualMachineMigrationDestinationTabProps = {
   defaultStorageClassName: string;
   destinationStorageClass: string;
@@ -28,8 +26,6 @@ const VirtualMachineMigrationDestinationTab: FC<VirtualMachineMigrationDestinati
 }) => {
   const { t } = useKubevirtTranslation();
 
-  const allowedStorageProfilesNames = useMigratableStorageClasses();
-
   return (
     <Stack hasGutter>
       <StackItem>
@@ -53,7 +49,6 @@ const VirtualMachineMigrationDestinationTab: FC<VirtualMachineMigrationDestinati
                 {defaultStorageClassName === storageClass && <Label>{t('default')}</Label>}
               </>
             ),
-            isDisabled: !allowedStorageProfilesNames?.includes(storageClass),
             value: storageClass,
           }))}
           popperProps={{
diff --git a/src/views/virtualmachines/actions/components/VirtualMachineMigration/tabs/components/utils.ts b/src/views/virtualmachines/actions/components/VirtualMachineMigration/tabs/components/utils.ts
index 2720505a6b..b29d9d0797 100644
--- a/src/views/virtualmachines/actions/components/VirtualMachineMigration/tabs/components/utils.ts
+++ b/src/views/virtualmachines/actions/components/VirtualMachineMigration/tabs/components/utils.ts
@@ -6,7 +6,7 @@ import { getPrintableDiskDrive } from '@kubevirt-utils/resources/vm/utils/disk/s
 import { convertToBaseValue, humanizeBinaryBytes } from '@kubevirt-utils/utils/humanize.js';
 import { isEmpty } from '@kubevirt-utils/utils/utils';
 
-import { getVolumePVC, isDiskMigratable, isPVCMigratable } from '../../utils/utils';
+import { getVolumePVC } from '../../utils/utils';
 
 export type MigrationDisksTableData = {
   drive: string;
@@ -32,7 +32,7 @@ const getDiskData = (
 
   return {
     drive: getPrintableDiskDrive(volumeDisk),
-    isSelectable: isDiskMigratable(volumeDisk) && !isEmpty(volumePVC) && isPVCMigratable(volumePVC),
+    isSelectable: !isEmpty(volumePVC),
     name: volume.name,
     pvc: volumePVC,
     size: pvcSize?.value === 0 ? NO_DATA_DASH : pvcSize?.string,
@@ -50,7 +50,7 @@ export const getTableDiskData = (
   vms: V1VirtualMachine[],
   pvcs: IoK8sApiCoreV1PersistentVolumeClaim[],
 ) => {
-  if (isEmpty(vms) || isEmpty(pvcs)) {
+  if (isEmpty(vms)) {
     return [];
   }
 
diff --git a/src/views/virtualmachines/actions/components/VirtualMachineMigration/utils/constants.ts b/src/views/virtualmachines/actions/components/VirtualMachineMigration/utils/constants.ts
new file mode 100644
index 0000000000..7754c57be1
--- /dev/null
+++ b/src/views/virtualmachines/actions/components/VirtualMachineMigration/utils/constants.ts
@@ -0,0 +1 @@
+export const PVC_BOUND_STATUS = 'Bound';
diff --git a/src/views/virtualmachines/actions/components/VirtualMachineMigration/utils/migrateVM.ts b/src/views/virtualmachines/actions/components/VirtualMachineMigration/utils/migrateVM.ts
deleted file mode 100644
index 1d7b5aed5c..0000000000
--- a/src/views/virtualmachines/actions/components/VirtualMachineMigration/utils/migrateVM.ts
+++ /dev/null
@@ -1,195 +0,0 @@
-import DataVolumeModel from '@kubevirt-ui/kubevirt-api/console/models/DataVolumeModel';
-import VirtualMachineModel from '@kubevirt-ui/kubevirt-api/console/models/VirtualMachineModel';
-import { V1beta1DataVolume } from '@kubevirt-ui/kubevirt-api/containerized-data-importer/models';
-import { IoK8sApiCoreV1PersistentVolumeClaim } from '@kubevirt-ui/kubevirt-api/kubernetes';
-import { V1VirtualMachine } from '@kubevirt-ui/kubevirt-api/kubevirt';
-import { MAX_NAME_LENGTH } from '@kubevirt-utils/components/SSHSecretModal/utils/constants';
-import { getName, getNamespace } from '@kubevirt-utils/resources/shared';
-import { getDataVolumeTemplates, getVolumes } from '@kubevirt-utils/resources/vm';
-import { UPDATE_STRATEGIES } from '@kubevirt-utils/resources/vm/utils/constants';
-import { getStorageClassName } from '@kubevirt-utils/resources/vm/utils/dataVolumeTemplate/selectors';
-import { getRandomChars, isEmpty } from '@kubevirt-utils/utils/utils';
-import { k8sCreate, k8sDelete, k8sPatch, Patch } from '@openshift-console/dynamic-plugin-sdk';
-import { getMigrationClaimNameAnnotation } from '@virtualmachines/actions/utils';
-
-const getBlankDataVolume = (
-  dataVolumeName: string,
-  namespace: string,
-  storageClassName: string,
-  storage: string,
-): V1beta1DataVolume => {
-  const randomChars = getRandomChars();
-
-  const originName = dataVolumeName.replace(/-mig-[\d\w]+$/, '');
-  const namePrefix = `${originName}-mig`.substring(0, MAX_NAME_LENGTH - 5 - randomChars.length);
-
-  return {
-    apiVersion: `${DataVolumeModel.apiGroup}/${DataVolumeModel.apiVersion}`,
-    kind: DataVolumeModel.kind,
-    metadata: {
-      name: `${namePrefix}-${randomChars}`,
-      namespace,
-    },
-    spec: {
-      source: {
-        blank: {},
-      },
-      storage: {
-        resources: {
-          requests: {
-            storage,
-          },
-        },
-        storageClassName,
-      },
-    },
-  };
-};
-
-const createBlankDataVolumes = async (
-  selectedPVCs: IoK8sApiCoreV1PersistentVolumeClaim[],
-  destinationStorageClass: string,
-): Promise<Map<string, V1beta1DataVolume>> => {
-  const dataVolumesCreationResults = await Promise.allSettled(
-    selectedPVCs
-      .map((pvc) => {
-        return getBlankDataVolume(
-          getName(pvc),
-          getNamespace(pvc),
-          destinationStorageClass,
-          pvc?.spec?.resources?.requests?.storage,
-        );
-      })
-      .map((dataVolume) =>
-        k8sCreate({ data: dataVolume, model: DataVolumeModel, ns: getNamespace(dataVolume) }),
-      ),
-  );
-
-  const { fulfilledRequests, rejectedRequests } = dataVolumesCreationResults.reduce(
-    (acc, result) => {
-      result.status === 'rejected'
-        ? acc.rejectedRequests.push(result)
-        : acc.fulfilledRequests.push(result);
-
-      return acc;
-    },
-    {
-      fulfilledRequests: [] as PromiseFulfilledResult<V1beta1DataVolume>[],
-      rejectedRequests: [] as PromiseRejectedResult[],
-    },
-  );
-
-  if (!isEmpty(rejectedRequests)) {
-    fulfilledRequests.map((result) =>
-      k8sDelete({
-        model: DataVolumeModel,
-        resource: result.value,
-      }),
-    );
-
-    throw new Error(rejectedRequests?.[0]?.reason);
-  }
-
-  const dataVolumesCreated = fulfilledRequests.map((result) => result.value);
-
-  return selectedPVCs.reduce((createdDataVolumeByPVCName, pvc, index) => {
-    createdDataVolumeByPVCName.set(getName(pvc), dataVolumesCreated[index]);
-    return createdDataVolumeByPVCName;
-  }, new Map<string, V1beta1DataVolume>());
-};
-
-const createPatchData = (
-  vm: V1VirtualMachine,
-  selectedPVCs: IoK8sApiCoreV1PersistentVolumeClaim[],
-  createdDataVolumeByPVCName: Map<string, V1beta1DataVolume>,
-) =>
-  getVolumes(vm).reduce((patchArray, volume, volumeIndex) => {
-    const pvcName = volume?.persistentVolumeClaim?.claimName || volume?.dataVolume?.name;
-    const pvc = selectedPVCs.find((selectedPVC) => getName(selectedPVC) === pvcName);
-
-    if (isEmpty(pvc)) return patchArray;
-
-    const destination = createdDataVolumeByPVCName.get(pvcName);
-
-    const destinationName = getName(destination);
-
-    const migrationClaimNameAnnotation = getMigrationClaimNameAnnotation(destinationName);
-
-    patchArray.push({
-      op: 'add',
-      path: `/metadata/annotations/${migrationClaimNameAnnotation.replace('/', '~1')}`,
-      value: pvcName,
-    });
-
-    if (volume?.persistentVolumeClaim?.claimName) {
-      patchArray.push({
-        op: 'replace',
-        path: `/spec/template/spec/volumes/${volumeIndex}/persistentVolumeClaim/claimName`,
-        value: destinationName,
-      });
-    }
-
-    if (volume?.dataVolume?.name) {
-      const dataVolumeIndex = getDataVolumeTemplates(vm)?.findIndex(
-        (dataVolumeTemplate) => getName(dataVolumeTemplate) === volume?.dataVolume?.name,
-      );
-
-      patchArray.push({
-        op: 'replace',
-        path: `/spec/template/spec/volumes/${volumeIndex}/dataVolume/name`,
-        value: destinationName,
-      });
-
-      patchArray.push({
-        op: 'replace',
-        path: `/spec/dataVolumeTemplates/${dataVolumeIndex}/metadata/name`,
-        value: destinationName,
-      });
-
-      const storageClassname = getStorageClassName(destination);
-
-      if (storageClassname)
-        patchArray.push({
-          op: 'replace',
-          path: `/spec/dataVolumeTemplates/${dataVolumeIndex}/spec/storage/storageClassName`,
-          value: storageClassname,
-        });
-    }
-    return patchArray;
-  }, [] as Patch[]);
-
-export const migrateVM = async (
-  vm: V1VirtualMachine,
-  selectedPVCs: IoK8sApiCoreV1PersistentVolumeClaim[],
-  destinationStorageClass: string,
-) => {
-  const createdDataVolumeByPVCName = await createBlankDataVolumes(
-    selectedPVCs,
-    destinationStorageClass,
-  );
-
-  const patchData = createPatchData(vm, selectedPVCs, createdDataVolumeByPVCName);
-
-  patchData.push({
-    op: 'add',
-    path: '/spec/updateVolumesStrategy',
-    value: UPDATE_STRATEGIES.Migration,
-  });
-
-  try {
-    return k8sPatch({
-      data: patchData,
-      model: VirtualMachineModel,
-      resource: vm,
-    });
-  } catch (error) {
-    createdDataVolumeByPVCName.forEach((dataVolume) =>
-      k8sDelete({
-        model: DataVolumeModel,
-        resource: dataVolume,
-      }),
-    );
-
-    throw error;
-  }
-};
diff --git a/src/views/virtualmachines/actions/components/VirtualMachineMigration/utils/migrateBulkVMs.ts b/src/views/virtualmachines/actions/components/VirtualMachineMigration/utils/migrateVMs.ts
similarity index 98%
rename from src/views/virtualmachines/actions/components/VirtualMachineMigration/utils/migrateBulkVMs.ts
rename to src/views/virtualmachines/actions/components/VirtualMachineMigration/utils/migrateVMs.ts
index 148d59d017..96f456ce57 100644
--- a/src/views/virtualmachines/actions/components/VirtualMachineMigration/utils/migrateBulkVMs.ts
+++ b/src/views/virtualmachines/actions/components/VirtualMachineMigration/utils/migrateVMs.ts
@@ -51,7 +51,7 @@ const getEmptyMigMigration = (migPlan: MigPlan): MigMigration => ({
   },
 });
 
-export const migrateBulkVMs = async (
+export const migrateVMs = async (
   vms: V1VirtualMachine[],
   namespacePVCs: IoK8sApiCoreV1PersistentVolumeClaim[],
   selectedPVCs: IoK8sApiCoreV1PersistentVolumeClaim[],
diff --git a/src/views/virtualmachines/actions/components/VirtualMachineMigration/utils/utils.ts b/src/views/virtualmachines/actions/components/VirtualMachineMigration/utils/utils.ts
index 9b8c10da68..842ad8b8cc 100644
--- a/src/views/virtualmachines/actions/components/VirtualMachineMigration/utils/utils.ts
+++ b/src/views/virtualmachines/actions/components/VirtualMachineMigration/utils/utils.ts
@@ -1,15 +1,14 @@
 import { IoK8sApiCoreV1PersistentVolumeClaim } from '@kubevirt-ui/kubevirt-api/kubernetes';
 import {
-  V1beta1StorageSpecAccessModesEnum,
-  V1Disk,
   V1VirtualMachine,
   V1VirtualMachineInstanceMigration,
   V1Volume,
 } from '@kubevirt-ui/kubevirt-api/kubevirt';
 import { t } from '@kubevirt-utils/hooks/useKubevirtTranslation';
 import { getName } from '@kubevirt-utils/resources/shared';
-import { getDisks, getVolumes } from '@kubevirt-utils/resources/vm';
+import { getVolumes } from '@kubevirt-utils/resources/vm';
 import { vmimStatuses } from '@kubevirt-utils/resources/vmim/statuses';
+import { isEmpty } from '@kubevirt-utils/utils/utils';
 import { ProgressVariant } from '@patternfly/react-core';
 
 import { MigMigrationStatuses } from '../../../../../../utils/resources/migrations/constants';
@@ -59,11 +58,6 @@ export const getProgressVariantByMigMigrationStatus = (
   return null;
 };
 
-export const isPVCMigratable = (pvc: IoK8sApiCoreV1PersistentVolumeClaim) =>
-  pvc?.spec?.accessModes?.includes(V1beta1StorageSpecAccessModesEnum.ReadWriteMany);
-
-export const isDiskMigratable = (disk: V1Disk) => !disk?.shareable;
-
 export const getVolumePVC = (volume: V1Volume, pvcs: IoK8sApiCoreV1PersistentVolumeClaim[]) =>
   pvcs?.find(
     (pvc) =>
@@ -77,8 +71,7 @@ export const getMigratableVMPVCs = (
 ): IoK8sApiCoreV1PersistentVolumeClaim[] => {
   return getVolumes(vm)?.reduce((acc, volume) => {
     const pvc = getVolumePVC(volume, pvcs);
-    const volumeDisk = getDisks(vm)?.find((disk) => disk.name === volume.name);
-    if (isPVCMigratable(pvc) && isDiskMigratable(volumeDisk)) {
+    if (!isEmpty(pvc)) {
       acc.push(pvc);
     }
 
diff --git a/src/views/virtualmachines/actions/hooks/useIsMTCInstalled.ts b/src/views/virtualmachines/actions/hooks/useIsMTCInstalled.ts
new file mode 100644
index 0000000000..31083157e9
--- /dev/null
+++ b/src/views/virtualmachines/actions/hooks/useIsMTCInstalled.ts
@@ -0,0 +1,12 @@
+import { modelToGroupVersionKind } from '@kubevirt-utils/models';
+import { MigPlanModel } from '@kubevirt-utils/resources/migrations/constants';
+import { isEmpty } from '@kubevirt-utils/utils/utils';
+import { useK8sModel } from '@openshift-console/dynamic-plugin-sdk';
+
+const useIsMTCInstalled = () => {
+  const [migPlan] = useK8sModel(modelToGroupVersionKind(MigPlanModel));
+
+  return !isEmpty(migPlan);
+};
+
+export default useIsMTCInstalled;
diff --git a/src/views/virtualmachines/actions/hooks/useMultipleVirtualMachineActions.tsx b/src/views/virtualmachines/actions/hooks/useMultipleVirtualMachineActions.tsx
index 53bec506b0..4887112514 100644
--- a/src/views/virtualmachines/actions/hooks/useMultipleVirtualMachineActions.tsx
+++ b/src/views/virtualmachines/actions/hooks/useMultipleVirtualMachineActions.tsx
@@ -5,16 +5,13 @@ import { ActionDropdownItemType } from '@kubevirt-utils/components/ActionsDropdo
 import { useModal } from '@kubevirt-utils/components/ModalProvider/ModalProvider';
 import { CONFIRM_VM_ACTIONS, TREE_VIEW_FOLDERS } from '@kubevirt-utils/hooks/useFeatures/constants';
 import { useFeatures } from '@kubevirt-utils/hooks/useFeatures/useFeatures';
-import { modelToGroupVersionKind } from '@kubevirt-utils/models';
 import { getNamespace } from '@kubevirt-utils/resources/shared';
-import { isEmpty } from '@kubevirt-utils/utils/utils';
-import { useK8sModel } from '@openshift-console/dynamic-plugin-sdk';
 import { isPaused, isRunning, isStopped } from '@virtualmachines/utils';
 
-import { MigPlanModel } from '../../../../utils/resources/migrations/constants';
 import { BulkVirtualMachineActionFactory } from '../BulkVirtualMachineActionFactory';
 
 import { ACTIONS_ID } from './constants';
+import useIsMTCInstalled from './useIsMTCInstalled';
 
 type UseMultipleVirtualMachineActions = (vms: V1VirtualMachine[]) => ActionDropdownItemType[];
 
@@ -23,9 +20,7 @@ const useMultipleVirtualMachineActions: UseMultipleVirtualMachineActions = (vms)
   const { featureEnabled: confirmVMActionsEnabled } = useFeatures(CONFIRM_VM_ACTIONS);
   const { featureEnabled: treeViewFoldersEnabled } = useFeatures(TREE_VIEW_FOLDERS);
 
-  const [migPlan] = useK8sModel(modelToGroupVersionKind(MigPlanModel));
-
-  const mtcInstalled = !isEmpty(migPlan);
+  const mtcInstalled = useIsMTCInstalled();
 
   return useMemo(() => {
     const namespaces = new Set(vms?.map((vm) => getNamespace(vm)));
diff --git a/src/views/virtualmachines/actions/hooks/useStorageMigrations.ts b/src/views/virtualmachines/actions/hooks/useStorageMigrations.ts
new file mode 100644
index 0000000000..6bcb59560d
--- /dev/null
+++ b/src/views/virtualmachines/actions/hooks/useStorageMigrations.ts
@@ -0,0 +1,52 @@
+import { V1VirtualMachine } from '@kubevirt-ui/kubevirt-api/kubevirt';
+import { modelToGroupVersionKind } from '@kubevirt-utils/models';
+import {
+  DEFAULT_MIGRATION_NAMESPACE,
+  MigMigration,
+  MigMigrationModel,
+  MigPlan,
+  MigPlanModel,
+} from '@kubevirt-utils/resources/migrations/constants';
+import { getName } from '@kubevirt-utils/resources/shared';
+import { useK8sWatchResource } from '@openshift-console/dynamic-plugin-sdk';
+
+import useIsMTCInstalled from './useIsMTCInstalled';
+import { getVMMigPlans, sortMigPlansByCreationTimestamp } from './utils';
+
+const useCurrentStorageMigration = (vm: V1VirtualMachine): [MigMigration, boolean] => {
+  const mtcInstalled = useIsMTCInstalled();
+
+  const [migPlans, migPlansLoaded] = useK8sWatchResource<MigPlan[]>(
+    mtcInstalled
+      ? {
+          groupVersionKind: modelToGroupVersionKind(MigPlanModel),
+          isList: true,
+          namespace: DEFAULT_MIGRATION_NAMESPACE,
+        }
+      : null,
+  );
+
+  const [migMigrations, migMigrationsLoaded] = useK8sWatchResource<MigMigration[]>(
+    mtcInstalled
+      ? {
+          groupVersionKind: modelToGroupVersionKind(MigMigrationModel),
+          isList: true,
+          namespace: DEFAULT_MIGRATION_NAMESPACE,
+        }
+      : null,
+  );
+
+  const vmMigPlans = getVMMigPlans(vm, migPlans)?.sort(sortMigPlansByCreationTimestamp);
+
+  const latestVMMigPlan = vmMigPlans?.[vmMigPlans?.length - 1];
+
+  const currentMigration = migMigrations?.find(
+    (migMigration) =>
+      migMigration?.spec?.migPlanRef?.name === getName(latestVMMigPlan) &&
+      migMigration.status?.phase !== 'Completed',
+  );
+
+  return [currentMigration, migMigrationsLoaded && migPlansLoaded];
+};
+
+export default useCurrentStorageMigration;
diff --git a/src/views/virtualmachines/actions/hooks/useVirtualMachineActionsProvider.ts b/src/views/virtualmachines/actions/hooks/useVirtualMachineActionsProvider.ts
index 5a02ca81e4..d8ae6044b6 100644
--- a/src/views/virtualmachines/actions/hooks/useVirtualMachineActionsProvider.ts
+++ b/src/views/virtualmachines/actions/hooks/useVirtualMachineActionsProvider.ts
@@ -10,14 +10,15 @@ import { getConsoleVirtctlCommand } from '@kubevirt-utils/components/SSHAccess/u
 import { CONFIRM_VM_ACTIONS, TREE_VIEW_FOLDERS } from '@kubevirt-utils/hooks/useFeatures/constants';
 import { useFeatures } from '@kubevirt-utils/hooks/useFeatures/useFeatures';
 import { VirtualMachineModelRef } from '@kubevirt-utils/models';
-import { getUpdateStrategy } from '@kubevirt-utils/resources/vm';
-import { UPDATE_STRATEGIES } from '@kubevirt-utils/resources/vm/utils/constants';
 import { vmimStatuses } from '@kubevirt-utils/resources/vmim/statuses';
 import { useK8sModel } from '@openshift-console/dynamic-plugin-sdk';
 
 import { printableVMStatus } from '../../utils';
 import { VirtualMachineActionFactory } from '../VirtualMachineActionFactory';
 
+import useIsMTCInstalled from './useIsMTCInstalled';
+import useCurrentStorageMigration from './useStorageMigrations';
+
 type UseVirtualMachineActionsProvider = (
   vm: V1VirtualMachine,
   vmim?: V1VirtualMachineInstanceMigration,
@@ -34,6 +35,9 @@ const useVirtualMachineActionsProvider: UseVirtualMachineActionsProvider = (
 
   const virtctlCommand = getConsoleVirtctlCommand(vm);
 
+  const mtcInstalled = useIsMTCInstalled();
+  const [currentStorageMigration, currentStorageMigrationLoaded] = useCurrentStorageMigration(vm);
+
   const [, inFlight] = useK8sModel(VirtualMachineModelRef);
 
   const { featureEnabled: treeViewFoldersEnabled } = useFeatures(TREE_VIEW_FOLDERS);
@@ -45,8 +49,6 @@ const useVirtualMachineActionsProvider: UseVirtualMachineActionsProvider = (
     const currentMigrationExist =
       vmim && ![vmimStatuses.Failed, vmimStatuses.Succeeded].includes(vmim?.status?.phase);
 
-    const isStorageMigration =
-      currentMigrationExist && getUpdateStrategy(vm) === UPDATE_STRATEGIES.Migration;
     const isComputeMigration = printableStatus === Migrating || currentMigrationExist;
 
     const startOrStop = ((printableStatusMachine) => {
@@ -63,14 +65,16 @@ const useVirtualMachineActionsProvider: UseVirtualMachineActionsProvider = (
 
     const migrateStorage = VirtualMachineActionFactory.migrateStorage(vm, createModal);
 
-    const cancelMigration = isStorageMigration
-      ? VirtualMachineActionFactory.cancelStorageMigration(vm, vmim, isSingleNodeCluster)
+    const startMigrationActions = mtcInstalled
+      ? [migrateCompute, migrateStorage]
+      : [migrateCompute];
+
+    const cancelMigration = currentStorageMigration
+      ? VirtualMachineActionFactory.cancelStorageMigration(currentStorageMigration)
       : VirtualMachineActionFactory.cancelComputeMigration(vm, vmim, isSingleNodeCluster);
 
     const migrationActions =
-      isComputeMigration || isStorageMigration
-        ? [cancelMigration]
-        : [migrateCompute, migrateStorage];
+      isComputeMigration || currentStorageMigration ? [cancelMigration] : startMigrationActions;
 
     const pauseOrUnpause =
       printableStatus === Paused
@@ -93,12 +97,17 @@ const useVirtualMachineActionsProvider: UseVirtualMachineActionsProvider = (
     vmim,
     isSingleNodeCluster,
     createModal,
+    currentStorageMigration,
     confirmVMActionsEnabled,
     virtctlCommand,
     treeViewFoldersEnabled,
+    mtcInstalled,
   ]);
 
-  return useMemo(() => [actions, !inFlight, undefined], [actions, inFlight]);
+  return useMemo(
+    () => [actions, !inFlight && currentStorageMigrationLoaded, undefined],
+    [actions, inFlight, currentStorageMigrationLoaded],
+  );
 };
 
 export default useVirtualMachineActionsProvider;
diff --git a/src/views/virtualmachines/actions/hooks/utils.ts b/src/views/virtualmachines/actions/hooks/utils.ts
new file mode 100644
index 0000000000..2331f86075
--- /dev/null
+++ b/src/views/virtualmachines/actions/hooks/utils.ts
@@ -0,0 +1,18 @@
+import { V1VirtualMachine } from '@kubevirt-ui/kubevirt-api/kubevirt';
+import { MigPlan } from '@kubevirt-utils/resources/migrations/constants';
+import { getVMPVCNames } from '@kubevirt-utils/resources/vm/utils/source';
+
+export const sortMigPlansByCreationTimestamp = (a: MigPlan, b: MigPlan): number =>
+  (a?.metadata?.creationTimestamp ?? '')?.localeCompare(b?.metadata?.creationTimestamp ?? '');
+
+export const isVMMigPlan = (migPlan: MigPlan, vmPVCNames: string[]): boolean =>
+  migPlan?.spec?.persistentVolumes?.some(
+    (pv) =>
+      pv?.selection?.action === 'copy' && vmPVCNames?.includes(pv?.pvc?.name?.split(':')?.[0]),
+  );
+
+export const getVMMigPlans = (vm: V1VirtualMachine, migPlans: MigPlan[]): MigPlan[] => {
+  const vmPVCNames = getVMPVCNames(vm);
+
+  return migPlans?.filter((migPlan) => isVMMigPlan(migPlan, vmPVCNames));
+};


Reviews:
user: login: rszwajko
state: CHANGES_REQUESTED
author_association: MEMBER
submitted_at: 2025-05-05T11:52:36Z
user: login: upalatucci
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-05T11:54:05Z
user: login: upalatucci
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-05T11:54:33Z
user: login: upalatucci
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-05T11:54:58Z
user: login: upalatucci
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-05T11:56:37Z
user: login: upalatucci
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-05T11:56:48Z
user: login: rszwajko
body: Looks good enough! We can refine in follow-ups if needed.
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-05T16:17:42Z

Review comments:
diff_hunk: @@ -0,0 +1,4 @@
+import { MigPlan } from '@kubevirt-utils/resources/migrations/constants';
+
+export const sortMigPlansByCreationTimestamp = (a: MigPlan, b: MigPlan): number =>
+  a?.metadata?.creationTimestamp?.localeCompare(b?.metadata?.creationTimestamp);
path: src/views/virtualmachines/actions/hooks/utils.ts
user: login: rszwajko
body: the comparator is not symetric  - it should treat the falsy values the same on both sides. Currently it's not the case:
```
["a","","b",undefined,"c", null].sort((a,b)=> a?.localeCompare(b))
Array(6) [ "", "a", "b", "c", null, undefined ]
```
created_at: 2025-05-05T11:31:03Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,61 @@
+import { V1VirtualMachine } from '@kubevirt-ui/kubevirt-api/kubevirt';
+import { modelToGroupVersionKind } from '@kubevirt-utils/models';
+import {
+  DEFAULT_MIGRATION_NAMESPACE,
+  MigMigration,
+  MigMigrationModel,
+  MigPlan,
+  MigPlanModel,
+} from '@kubevirt-utils/resources/migrations/constants';
+import { getName } from '@kubevirt-utils/resources/shared';
+import { getVMPVCNames } from '@kubevirt-utils/resources/vm/utils/source';
+import { useK8sWatchResource } from '@openshift-console/dynamic-plugin-sdk';
+
+import useIsMTCInstalled from './useIsMTCInstalled';
+import { sortMigPlansByCreationTimestamp } from './utils';
+
+const useCurrentStorageMigration = (vm: V1VirtualMachine): [MigMigration, boolean] => {
+  const mtcInstalled = useIsMTCInstalled();
+
+  const vmPVCNames = getVMPVCNames(vm);
+
+  const [migPlans, migPlansLoaded] = useK8sWatchResource<MigPlan[]>(
+    mtcInstalled
+      ? {
+          groupVersionKind: modelToGroupVersionKind(MigPlanModel),
+          isList: true,
+          namespace: DEFAULT_MIGRATION_NAMESPACE,
+        }
+      : null,
+  );
+
+  const [migMigrations, migMigrationsLoaded] = useK8sWatchResource<MigMigration[]>(
+    mtcInstalled
+      ? {
+          groupVersionKind: modelToGroupVersionKind(MigMigrationModel),
+          isList: true,
+          namespace: DEFAULT_MIGRATION_NAMESPACE,
+        }
+      : null,
+  );
+
+  const latestVMMigPlan = migPlans
+    ?.filter((migPlan) =>
+      migPlan?.spec?.persistentVolumes?.find(
+        (pv) =>
+          pv?.selection?.action === 'copy' && vmPVCNames?.includes(pv?.pvc?.name?.split(':')?.[0]),
path: src/views/virtualmachines/actions/hooks/useStorageMigrations.ts
user: login: rszwajko
body: 1. a candidate for a named utility method
2. please provide an example for the parsed string (as a comment) 
created_at: 2025-05-05T11:40:21Z
author_association: MEMBER
diff_hunk: @@ -76,23 +80,23 @@ export const VirtualMachineActionFactory = {
       label: t('Cancel compute migration'),
     };
   },
-  cancelStorageMigration: (
-    vm: V1VirtualMachine,
-    vmim: V1VirtualMachineInstanceMigration,
-    isSingleNodeCluster: boolean,
-  ): Action => {
+  cancelStorageMigration: (currentStorageMigration: MigMigration): Action => {
     return {
       accessReview: {
-        group: VirtualMachineModel.apiGroup,
-        namespace: vm?.metadata?.namespace,
-        resource: VirtualMachineModel.plural,
+        group: MigMigrationModel.apiGroup,
+        namespace: DEFAULT_MIGRATION_NAMESPACE,
+        resource: MigMigrationModel.plural,
         verb: 'patch',
       },
-      cta: () => {
-        cancelMigration(vmim);
-        return rollbackStorageMigration(vm);
-      },
-      disabled: isSingleNodeCluster,
+      cta: () =>
+        k8sPatch({
+          data: [
+            { op: 'replace', path: '/spec/rollback', value: true },
+            { op: 'remove', path: '/spec/migrateState' },
path: src/views/virtualmachines/actions/VirtualMachineActionFactory.tsx
user: login: rszwajko
body: removing migration state seems unusual - why it's up to the UI to clean it up?
created_at: 2025-05-05T11:44:35Z
author_association: MEMBER
diff_hunk: @@ -116,22 +110,3 @@ export const deleteVM = async (vm: V1VirtualMachine) => {
     resource: vm,
   });
 };
-
-export const rollbackStorageMigration = async (vm: V1VirtualMachine) => {
-  if (isEmpty(getUpdateStrategy(vm))) return;
-
-  const patchData: Patch[] = createRollbackPatchData(vm);
-
-  patchData.push({
-    op: 'remove',
-    path: '/spec/updateVolumesStrategy',
path: src/views/virtualmachines/actions/actions.ts
user: login: rszwajko
body: it seems we are changing the rollback procedure - is it a new change in 4.19?
created_at: 2025-05-05T11:49:10Z
author_association: MEMBER
diff_hunk: @@ -1,26 +0,0 @@
-import { V1beta1StorageSpecAccessModesEnum } from '@kubevirt-ui/kubevirt-api/kubevirt';
-import { StorageProfileModelGroupVersionKind } from '@kubevirt-utils/models';
-import { getName } from '@kubevirt-utils/resources/shared';
-import { K8sResourceCommon, useK8sWatchResource } from '@openshift-console/dynamic-plugin-sdk';
-
-const useMigratableStorageClasses = (): string[] => {
path: src/views/virtualmachines/actions/components/VirtualMachineMigration/hooks/useMigratableStorageClasses.ts
user: login: rszwajko
body: removal seems not related to the PR
created_at: 2025-05-05T11:52:14Z
author_association: MEMBER
diff_hunk: @@ -76,23 +80,23 @@ export const VirtualMachineActionFactory = {
       label: t('Cancel compute migration'),
     };
   },
-  cancelStorageMigration: (
-    vm: V1VirtualMachine,
-    vmim: V1VirtualMachineInstanceMigration,
-    isSingleNodeCluster: boolean,
-  ): Action => {
+  cancelStorageMigration: (currentStorageMigration: MigMigration): Action => {
     return {
       accessReview: {
-        group: VirtualMachineModel.apiGroup,
-        namespace: vm?.metadata?.namespace,
-        resource: VirtualMachineModel.plural,
+        group: MigMigrationModel.apiGroup,
+        namespace: DEFAULT_MIGRATION_NAMESPACE,
+        resource: MigMigrationModel.plural,
         verb: 'patch',
       },
-      cta: () => {
-        cancelMigration(vmim);
-        return rollbackStorageMigration(vm);
-      },
-      disabled: isSingleNodeCluster,
+      cta: () =>
+        k8sPatch({
+          data: [
+            { op: 'replace', path: '/spec/rollback', value: true },
+            { op: 'remove', path: '/spec/migrateState' },
path: src/views/virtualmachines/actions/VirtualMachineActionFactory.tsx
user: login: upalatucci
body: the migplan do not support rollback and migrateState specs together. only one of the two
created_at: 2025-05-05T11:54:05Z
author_association: MEMBER
diff_hunk: @@ -116,22 +110,3 @@ export const deleteVM = async (vm: V1VirtualMachine) => {
     resource: vm,
   });
 };
-
-export const rollbackStorageMigration = async (vm: V1VirtualMachine) => {
-  if (isEmpty(getUpdateStrategy(vm))) return;
-
-  const patchData: Patch[] = createRollbackPatchData(vm);
-
-  patchData.push({
-    op: 'remove',
-    path: '/spec/updateVolumesStrategy',
path: src/views/virtualmachines/actions/actions.ts
user: login: upalatucci
body: Yes we need that as we don't want to use `updateVolumesStrategy` anymore. Its a storage migration method that do not work for all cases 
created_at: 2025-05-05T11:54:33Z
author_association: MEMBER
diff_hunk: @@ -1,26 +0,0 @@
-import { V1beta1StorageSpecAccessModesEnum } from '@kubevirt-ui/kubevirt-api/kubevirt';
-import { StorageProfileModelGroupVersionKind } from '@kubevirt-utils/models';
-import { getName } from '@kubevirt-utils/resources/shared';
-import { K8sResourceCommon, useK8sWatchResource } from '@openshift-console/dynamic-plugin-sdk';
-
-const useMigratableStorageClasses = (): string[] => {
path: src/views/virtualmachines/actions/components/VirtualMachineMigration/hooks/useMigratableStorageClasses.ts
user: login: upalatucci
body: Yes its related becuase MTC migration support all storage classes  instead of `updateVolumesStrategy` 
created_at: 2025-05-05T11:54:58Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,4 @@
+import { MigPlan } from '@kubevirt-utils/resources/migrations/constants';
+
+export const sortMigPlansByCreationTimestamp = (a: MigPlan, b: MigPlan): number =>
+  a?.metadata?.creationTimestamp?.localeCompare(b?.metadata?.creationTimestamp);
path: src/views/virtualmachines/actions/hooks/utils.ts
user: login: upalatucci
body: oh i understand but the creationTimestamp will not be `""`. Maybe `a` or `b` are undefined so I guarded that with `?` 
created_at: 2025-05-05T11:56:37Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,61 @@
+import { V1VirtualMachine } from '@kubevirt-ui/kubevirt-api/kubevirt';
+import { modelToGroupVersionKind } from '@kubevirt-utils/models';
+import {
+  DEFAULT_MIGRATION_NAMESPACE,
+  MigMigration,
+  MigMigrationModel,
+  MigPlan,
+  MigPlanModel,
+} from '@kubevirt-utils/resources/migrations/constants';
+import { getName } from '@kubevirt-utils/resources/shared';
+import { getVMPVCNames } from '@kubevirt-utils/resources/vm/utils/source';
+import { useK8sWatchResource } from '@openshift-console/dynamic-plugin-sdk';
+
+import useIsMTCInstalled from './useIsMTCInstalled';
+import { sortMigPlansByCreationTimestamp } from './utils';
+
+const useCurrentStorageMigration = (vm: V1VirtualMachine): [MigMigration, boolean] => {
+  const mtcInstalled = useIsMTCInstalled();
+
+  const vmPVCNames = getVMPVCNames(vm);
+
+  const [migPlans, migPlansLoaded] = useK8sWatchResource<MigPlan[]>(
+    mtcInstalled
+      ? {
+          groupVersionKind: modelToGroupVersionKind(MigPlanModel),
+          isList: true,
+          namespace: DEFAULT_MIGRATION_NAMESPACE,
+        }
+      : null,
+  );
+
+  const [migMigrations, migMigrationsLoaded] = useK8sWatchResource<MigMigration[]>(
+    mtcInstalled
+      ? {
+          groupVersionKind: modelToGroupVersionKind(MigMigrationModel),
+          isList: true,
+          namespace: DEFAULT_MIGRATION_NAMESPACE,
+        }
+      : null,
+  );
+
+  const latestVMMigPlan = migPlans
+    ?.filter((migPlan) =>
+      migPlan?.spec?.persistentVolumes?.find(
+        (pv) =>
+          pv?.selection?.action === 'copy' && vmPVCNames?.includes(pv?.pvc?.name?.split(':')?.[0]),
path: src/views/virtualmachines/actions/hooks/useStorageMigrations.ts
user: login: upalatucci
body: okay i'll do it

created_at: 2025-05-05T11:56:47Z
author_association: MEMBER

PR comments:
user: login: openshift-ci-robot
created_at: 2025-04-16T09:49:19Z
body: @upalatucci: This pull request references [CNV-58541](https://issues.redhat.com//browse/CNV-58541) which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the epic to target the "4.19.0" version, but no target version was set.

<details>

In response to [this](https://github.com/kubevirt-ui/kubevirt-plugin/pull/2585):

><!---
>Thanks for creating a Pull Request 💖!
>
>Please read the following before submitting:
>- PRs that adds new external dependencies might take a while to review.
>- Keep your PR as small as possible.
>- Limit your PR to one type (feature, refactoring, ci, or bugfix)
>-->
>
>## 📝 Description
>
>> Add a brief description
>
>## 🎥 Demo
>
>> Please add a video or an image of the behavior/changes
>


Instructions for interacting with me using PR comments are available [here](https://prow.ci.openshift.org/command-help?repo=kubevirt-ui%2Fkubevirt-plugin).  If you have questions or suggestions related to my behavior, please file an issue against the [openshift-eng/jira-lifecycle-plugin](https://github.com/openshift-eng/jira-lifecycle-plugin/issues/new) repository.
</details>
author_association: COLLABORATOR
user: login: openshift-ci-robot
created_at: 2025-05-05T11:11:31Z
body: @upalatucci: This pull request references [CNV-58541](https://issues.redhat.com//browse/CNV-58541) which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the epic to target the "4.20.0" version, but no target version was set.

<details>

In response to [this](https://github.com/kubevirt-ui/kubevirt-plugin/pull/2585):

><!---
>Thanks for creating a Pull Request 💖!
>
>Please read the following before submitting:
>- PRs that adds new external dependencies might take a while to review.
>- Keep your PR as small as possible.
>- Limit your PR to one type (feature, refactoring, ci, or bugfix)
>-->
>
>## 📝 Description
>
>The storage migration will be available only if MTC is installed
>
>## 🎥 Demo
>
>IF MTC IS NOT INSTALLED
>
>
><img width="1920" alt="Screenshot 2025-05-05 at 13 03 42" src="https://github.com/user-attachments/assets/faa9e559-b668-46a1-8e1e-ccd44596875c" />
><img width="1920" alt="Screenshot 2025-05-05 at 13 03 51" src="https://github.com/user-attachments/assets/8c50e878-3244-4272-9e03-6789c0e06215" />
>
>
>
>MTC migration
>
><img width="1920" alt="Screenshot 2025-05-05 at 12 53 58" src="https://github.com/user-attachments/assets/6ba27eb4-2946-436c-b582-2ba749b5a3b3" />
>


Instructions for interacting with me using PR comments are available [here](https://prow.ci.openshift.org/command-help?repo=kubevirt-ui%2Fkubevirt-plugin).  If you have questions or suggestions related to my behavior, please file an issue against the [openshift-eng/jira-lifecycle-plugin](https://github.com/openshift-eng/jira-lifecycle-plugin/issues/new) repository.
</details>
author_association: COLLABORATOR
user: login: openshift-ci-robot
created_at: 2025-05-05T12:13:11Z
body: @upalatucci: This pull request references [CNV-58541](https://issues.redhat.com//browse/CNV-58541) which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the epic to target the "4.20.0" version, but no target version was set.

<details>

In response to [this](https://github.com/kubevirt-ui/kubevirt-plugin/pull/2585):

><!---
>Thanks for creating a Pull Request 💖!
>
>Please read the following before submitting:
>- PRs that adds new external dependencies might take a while to review.
>- Keep your PR as small as possible.
>- Limit your PR to one type (feature, refactoring, ci, or bugfix)
>-->
>
>## 📝 Description
>
>The storage migration will be available only if MTC is installed
>
>The old method using `updateVolumesStrategy` is removed
>
>This means that all storageclass can be used and all pvcs can be migrated
>
>## 🎥 Demo
>
>IF MTC IS NOT INSTALLED
>
>
><img width="1920" alt="Screenshot 2025-05-05 at 13 03 42" src="https://github.com/user-attachments/assets/faa9e559-b668-46a1-8e1e-ccd44596875c" />
><img width="1920" alt="Screenshot 2025-05-05 at 13 03 51" src="https://github.com/user-attachments/assets/8c50e878-3244-4272-9e03-6789c0e06215" />
>
>
>
>MTC migration
>
><img width="1920" alt="Screenshot 2025-05-05 at 12 53 58" src="https://github.com/user-attachments/assets/6ba27eb4-2946-436c-b582-2ba749b5a3b3" />
>


Instructions for interacting with me using PR comments are available [here](https://prow.ci.openshift.org/command-help?repo=kubevirt-ui%2Fkubevirt-plugin).  If you have questions or suggestions related to my behavior, please file an issue against the [openshift-eng/jira-lifecycle-plugin](https://github.com/openshift-eng/jira-lifecycle-plugin/issues/new) repository.
</details>
author_association: COLLABORATOR
user: login: openshift-ci-robot
created_at: 2025-05-05T12:21:49Z
body: @upalatucci: This pull request references [CNV-58541](https://issues.redhat.com//browse/CNV-58541) which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the epic to target the "4.20.0" version, but no target version was set.

<details>

In response to [this](https://github.com/kubevirt-ui/kubevirt-plugin/pull/2585):

><!---
>Thanks for creating a Pull Request 💖!
>
>Please read the following before submitting:
>- PRs that adds new external dependencies might take a while to review.
>- Keep your PR as small as possible.
>- Limit your PR to one type (feature, refactoring, ci, or bugfix)
>-->
>
>## 📝 Description
>
>The storage migration will be available only if MTC is installed
>
>The old method using `updateVolumesStrategy` is removed
>
>This means that all storageclass can be used and all pvcs can be migrated
>
>## 🎥 Demo
>
>IF MTC IS NOT INSTALLED
>
>
><img width="1920" alt="Screenshot 2025-05-05 at 13 03 42" src="https://github.com/user-attachments/assets/faa9e559-b668-46a1-8e1e-ccd44596875c" />
><img width="1920" alt="Screenshot 2025-05-05 at 13 03 51" src="https://github.com/user-attachments/assets/8c50e878-3244-4272-9e03-6789c0e06215" />
>
>
>
>MTC migration
>
><img width="1920" alt="Screenshot 2025-05-05 at 12 53 58" src="https://github.com/user-attachments/assets/6ba27eb4-2946-436c-b582-2ba749b5a3b3" />
>
>
>This should also resolve https://issues.redhat.com/browse/CNV-61006
>


Instructions for interacting with me using PR comments are available [here](https://prow.ci.openshift.org/command-help?repo=kubevirt-ui%2Fkubevirt-plugin).  If you have questions or suggestions related to my behavior, please file an issue against the [openshift-eng/jira-lifecycle-plugin](https://github.com/openshift-eng/jira-lifecycle-plugin/issues/new) repository.
</details>
author_association: COLLABORATOR
user: login: openshift-ci-robot
created_at: 2025-05-05T12:39:20Z
body: @upalatucci: This pull request references [CNV-58541](https://issues.redhat.com//browse/CNV-58541) which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the epic to target the "4.20.0" version, but no target version was set.

<details>

In response to [this](https://github.com/kubevirt-ui/kubevirt-plugin/pull/2585):

><!---
>Thanks for creating a Pull Request 💖!
>
>Please read the following before submitting:
>- PRs that adds new external dependencies might take a while to review.
>- Keep your PR as small as possible.
>- Limit your PR to one type (feature, refactoring, ci, or bugfix)
>-->
>
>## 📝 Description
>
>The storage migration will be available only if MTC is installed
>
>The old method using `updateVolumesStrategy` is removed
>
>This means that all storageclass can be used and all pvcs can be migrated
>
>the migplan do not support `rollback` and `migrateState` specs together. only one of the two. So rollabcking means to remove the `migrateState` and put the `rollback` state
>
>## 🎥 Demo
>
>IF MTC IS NOT INSTALLED
>
>
><img width="1920" alt="Screenshot 2025-05-05 at 13 03 42" src="https://github.com/user-attachments/assets/faa9e559-b668-46a1-8e1e-ccd44596875c" />
><img width="1920" alt="Screenshot 2025-05-05 at 13 03 51" src="https://github.com/user-attachments/assets/8c50e878-3244-4272-9e03-6789c0e06215" />
>
>
>
>MTC migration
>
><img width="1920" alt="Screenshot 2025-05-05 at 12 53 58" src="https://github.com/user-attachments/assets/6ba27eb4-2946-436c-b582-2ba749b5a3b3" />
>
>
>This should also resolve https://issues.redhat.com/browse/CNV-61006
>


Instructions for interacting with me using PR comments are available [here](https://prow.ci.openshift.org/command-help?repo=kubevirt-ui%2Fkubevirt-plugin).  If you have questions or suggestions related to my behavior, please file an issue against the [openshift-eng/jira-lifecycle-plugin](https://github.com/openshift-eng/jira-lifecycle-plugin/issues/new) repository.
</details>
author_association: COLLABORATOR
user: login: rszwajko
created_at: 2025-05-05T16:22:27Z
body: /lgtm
author_association: MEMBER
user: login: openshift-ci[bot]
created_at: 2025-05-05T16:22:34Z
body: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubevirt-ui/kubevirt-plugin/pull/2585#issuecomment-2851538207" title="LGTM">rszwajko</a>*, *<a href="https://github.com/kubevirt-ui/kubevirt-plugin/pull/2585#" title="Author self-approved">upalatucci</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubevirt-ui%2Fkubevirt-plugin).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/kubevirt-ui/kubevirt-plugin/blob/main/OWNERS)~~ [rszwajko,upalatucci]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
author_association: CONTRIBUTOR