diff --git a/packages/forklift-console-plugin/src/modules/NetworkMaps/views/details/components/MapsSection/MapsSection.tsx b/packages/forklift-console-plugin/src/modules/NetworkMaps/views/details/components/MapsSection/MapsSection.tsx index af0e90af1..1c05f6b1e 100644 --- a/packages/forklift-console-plugin/src/modules/NetworkMaps/views/details/components/MapsSection/MapsSection.tsx +++ b/packages/forklift-console-plugin/src/modules/NetworkMaps/views/details/components/MapsSection/MapsSection.tsx @@ -129,7 +129,7 @@ export const MapsSection: React.FC = ({ obj }) => { const currentDestinationNet = destinationNetworks.find( (n) => OpenShiftNetworkAttachmentDefinitionToName(n) == current.destination, ) || { type: 'pod' }; - const currentSourceNet = sourceNetworks.find((n) => n.name === current.source); + const currentSourceNet = sourceNetworks.find((n) => n?.name === current.source); dispatch({ type: 'SET_MAP', diff --git a/packages/forklift-console-plugin/src/modules/Plans/views/details/tabs/VirtualMachines/Migration/MigrationVirtualMachinesList.tsx b/packages/forklift-console-plugin/src/modules/Plans/views/details/tabs/VirtualMachines/Migration/MigrationVirtualMachinesList.tsx index 8357dff23..1b30ad25a 100644 --- a/packages/forklift-console-plugin/src/modules/Plans/views/details/tabs/VirtualMachines/Migration/MigrationVirtualMachinesList.tsx +++ b/packages/forklift-console-plugin/src/modules/Plans/views/details/tabs/VirtualMachines/Migration/MigrationVirtualMachinesList.tsx @@ -8,6 +8,7 @@ import { useForkliftTranslation } from 'src/utils/i18n'; import { loadUserSettings, ResourceFieldFactory } from '@kubev2v/common'; import { + IoK8sApiBatchV1Job, IoK8sApiCoreV1Pod, MigrationModelGroupVersionKind, V1beta1Migration, @@ -88,7 +89,7 @@ const fieldsMetadataFactory: ResourceFieldFactory = (t) => [ { resourceFieldId: 'status', jsonPath: (obj: VMData) => { - const completed = obj.statusVM?.pipeline.filter((p) => p.phase === 'Completed'); + const completed = obj.statusVM?.pipeline.filter((p) => p?.phase === 'Completed'); return (completed || []).length; }, @@ -142,6 +143,21 @@ export const MigrationVirtualMachinesList: FC<{ obj: PlanData }> = ({ obj }) => : (podsDict[p.metadata.labels.vmID] = [p]), ); + const [jobs, jobsLoaded, jobsLoadError] = useK8sWatchResource({ + groupVersionKind: { kind: 'Job', group: 'batch', version: 'v1' }, + namespaced: true, + isList: true, + namespace: plan?.spec?.targetNamespace, + selector: { matchLabels: { plan: plan?.metadata?.uid } }, + }); + + const jobsDict: Record = {}; + (jobs && jobsLoaded && !jobsLoadError ? jobs : []).forEach((j) => + jobsDict[j.metadata.labels.vmID] + ? jobsDict[j.metadata.labels.vmID].push(j) + : (jobsDict[j.metadata.labels.vmID] = [j]), + ); + const [selectedIds, setSelectedIds] = useState([]); const [expandedIds, setExpandedIds] = useState([]); const [userSettings] = useState(() => loadUserSettings({ pageId: 'PlanVirtualMachines' })); @@ -157,6 +173,7 @@ export const MigrationVirtualMachinesList: FC<{ obj: PlanData }> = ({ obj }) => specVM: m, statusVM: vmDict[m.id], pods: podsDict[m.id], + jobs: jobsDict[m.id], targetNamespace: plan?.spec?.targetNamespace, })); diff --git a/packages/forklift-console-plugin/src/modules/Plans/views/details/tabs/VirtualMachines/Migration/MigrationVirtualMachinesRow.tsx b/packages/forklift-console-plugin/src/modules/Plans/views/details/tabs/VirtualMachines/Migration/MigrationVirtualMachinesRow.tsx index 78fda881f..cf9e81aab 100644 --- a/packages/forklift-console-plugin/src/modules/Plans/views/details/tabs/VirtualMachines/Migration/MigrationVirtualMachinesRow.tsx +++ b/packages/forklift-console-plugin/src/modules/Plans/views/details/tabs/VirtualMachines/Migration/MigrationVirtualMachinesRow.tsx @@ -47,7 +47,7 @@ const cellRenderers: Record> = { return ; }, transfer: (props: PlanVMsCellProps) => { - const diskTransfer = props.data.statusVM?.pipeline.find((p) => p.name === 'DiskTransfer'); + const diskTransfer = props.data.statusVM?.pipeline.find((p) => p?.name === 'DiskTransfer'); const annotations: { unit: string } = diskTransfer?.annotations as undefined; return annotations?.unit ? ( @@ -63,12 +63,12 @@ const cellRenderers: Record> = { const pipeline = props.data.statusVM?.pipeline; let lastRunningItem: V1beta1PlanStatusMigrationVmsPipeline; - if (pipeline[0].phase === 'Pending') { + if (pipeline[0]?.phase === 'Pending') { lastRunningItem = pipeline[0]; - } else if (pipeline[pipeline.length - 1].phase === 'Completed') { + } else if (pipeline[pipeline.length - 1]?.phase === 'Completed') { lastRunningItem = pipeline[pipeline.length - 1]; } else { - const lastNonePendingIndex = pipeline.findIndex((p) => p.phase === 'Pending') - 1; + const lastNonePendingIndex = pipeline.findIndex((p) => p?.phase === 'Pending') - 1; lastRunningItem = pipeline[lastNonePendingIndex]; } @@ -79,7 +79,7 @@ const cellRenderers: Record> = { showClose={false} alertSeverityVariant={alertSeverityVariant} headerIcon={getIcon(lastRunningItem)} - headerContent={lastRunningItem.name} + headerContent={lastRunningItem?.name} bodyContent={ @@ -120,13 +120,13 @@ const cellRenderers: Record> = { > {pipeline.map((p) => ( - {p.name} + {p?.name} ))} @@ -154,7 +154,7 @@ const getVariant: GetVariantType = (p) => { return 'danger'; } - switch (p.phase) { + switch (p?.phase) { case 'Completed': return 'success'; case 'Pending': @@ -171,7 +171,7 @@ const gePopoverVariant: GetPopoverVariantType = (p) => { return 'danger'; } - switch (p.phase) { + switch (p?.phase) { case 'Completed': return 'success'; case 'Pending': @@ -187,7 +187,7 @@ const getIcon: GetIconType = (p) => { return ; } - switch (p.phase) { + switch (p?.phase) { case 'Completed': return ; case 'Pending': diff --git a/packages/forklift-console-plugin/src/modules/Plans/views/details/tabs/VirtualMachines/Migration/MigrationVirtualMachinesRowExtended.tsx b/packages/forklift-console-plugin/src/modules/Plans/views/details/tabs/VirtualMachines/Migration/MigrationVirtualMachinesRowExtended.tsx index 4943dfd55..bc23e0565 100644 --- a/packages/forklift-console-plugin/src/modules/Plans/views/details/tabs/VirtualMachines/Migration/MigrationVirtualMachinesRowExtended.tsx +++ b/packages/forklift-console-plugin/src/modules/Plans/views/details/tabs/VirtualMachines/Migration/MigrationVirtualMachinesRowExtended.tsx @@ -3,7 +3,7 @@ import SectionHeading from 'src/components/headers/SectionHeading'; import { useForkliftTranslation } from 'src/utils/i18n'; import { RowProps, TableComposable, Tbody, Td, Th, Thead, Tr } from '@kubev2v/common'; -import { V1beta1PlanStatusMigrationVmsPipeline } from '@kubev2v/types'; +import { IoK8sApiBatchV1Job, V1beta1PlanStatusMigrationVmsPipeline } from '@kubev2v/types'; import { ResourceLink, Timestamp } from '@openshift-console/dynamic-plugin-sdk'; import Status from '@openshift-console/dynamic-plugin-sdk/lib/app/components/status/Status'; import { Flex, FlexItem, PageSection } from '@patternfly/react-core'; @@ -21,6 +21,7 @@ export const MigrationVirtualMachinesRowExtended: React.FC> = ( const pipeline = props.resourceData.statusVM?.pipeline; const conditions = props.resourceData.statusVM?.conditions; const pods = props.resourceData.pods; + const jobs = props.resourceData.jobs; const success = conditions?.find((c) => c.type === 'Succeeded' && c.status === 'True'); const getStatusLabel = (status: string) => { @@ -52,7 +53,7 @@ export const MigrationVirtualMachinesRowExtended: React.FC> = ( version: 'v1', kind: 'VirtualMachine', }} - name={props.resourceData.statusVM.name} + name={props.resourceData.statusVM?.name} namespace={props.resourceData.targetNamespace} /> @@ -93,6 +94,37 @@ export const MigrationVirtualMachinesRowExtended: React.FC> = ( )} + {(jobs || []).length > 0 && ( + <> + + + + {(jobs || []).map((job) => ( + + + + ))} + + + + )} + { return ; } - switch (p.phase) { + switch (p?.phase) { case 'Completed': return ; case 'Pending': @@ -172,3 +204,20 @@ const getIcon: GetIconType = (p) => { return ; } }; + +const getJobPhase = (job: IoK8sApiBatchV1Job) => { + const conditions = job?.status?.conditions || []; + + const conditionFailed = conditions.find((c) => c.type === 'Failed' && c.status === 'True'); + const conditionComplete = conditions.find((c) => c.type === 'Complete' && c.status === 'True'); + + if (conditionFailed) { + return 'Error'; + } + + if (conditionComplete) { + return 'Complete'; + } + + return 'Pending'; +}; diff --git a/packages/forklift-console-plugin/src/modules/Plans/views/details/tabs/VirtualMachines/Plan/PlanVirtualMachinesList.tsx b/packages/forklift-console-plugin/src/modules/Plans/views/details/tabs/VirtualMachines/Plan/PlanVirtualMachinesList.tsx index 0af6b5d39..939a06844 100644 --- a/packages/forklift-console-plugin/src/modules/Plans/views/details/tabs/VirtualMachines/Plan/PlanVirtualMachinesList.tsx +++ b/packages/forklift-console-plugin/src/modules/Plans/views/details/tabs/VirtualMachines/Plan/PlanVirtualMachinesList.tsx @@ -52,6 +52,7 @@ export const PlanVirtualMachinesList: FC<{ obj: PlanData }> = ({ obj }) => { specVM: m, statusVM: vmDict[m.id], pods: [], + jobs: [], targetNamespace: plan?.spec?.targetNamespace, })); diff --git a/packages/forklift-console-plugin/src/modules/Plans/views/details/tabs/VirtualMachines/types/VMData.ts b/packages/forklift-console-plugin/src/modules/Plans/views/details/tabs/VirtualMachines/types/VMData.ts index 2080bf8ce..98e968aa6 100644 --- a/packages/forklift-console-plugin/src/modules/Plans/views/details/tabs/VirtualMachines/types/VMData.ts +++ b/packages/forklift-console-plugin/src/modules/Plans/views/details/tabs/VirtualMachines/types/VMData.ts @@ -1,4 +1,5 @@ import { + IoK8sApiBatchV1Job, IoK8sApiCoreV1Pod, V1beta1PlanSpecVms, V1beta1PlanStatusMigrationVms, @@ -8,5 +9,6 @@ export type VMData = { specVM: V1beta1PlanSpecVms; statusVM?: V1beta1PlanStatusMigrationVms; pods: IoK8sApiCoreV1Pod[]; + jobs: IoK8sApiBatchV1Job[]; targetNamespace: string; };
+ + + + + + + + +