Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CNV-43594: Fix bootable incloning #2167

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion src/utils/resources/bootableresources/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ import DataSourceModel, {
} from '@kubevirt-ui/kubevirt-api/console/models/DataSourceModel';
import DataVolumeModel from '@kubevirt-ui/kubevirt-api/console/models/DataVolumeModel';
import {
V1beta1DataImportCron,
V1beta1DataSource,
V1beta1DataVolume,
} from '@kubevirt-ui/kubevirt-api/containerized-data-importer/models';
import { IoK8sApiCoreV1PersistentVolumeClaim } from '@kubevirt-ui/kubevirt-api/kubernetes';
import { isEmpty, kubevirtConsole } from '@kubevirt-utils/utils/utils';
import { k8sDelete } from '@openshift-console/dynamic-plugin-sdk';

import { getLabel } from '../shared';
import { getLabel, getName, getNamespace } from '../shared';

import { deprecatedOSNames, KUBEVIRT_ISO_LABEL } from './constants';
import { BootableVolume } from './types';
Expand Down Expand Up @@ -73,3 +74,13 @@ export const isBootableVolumeISO = (bootableVolume: BootableVolume): boolean =>
getLabel(bootableVolume, KUBEVIRT_ISO_LABEL) === 'true';

export const isDeprecated = (bootVolumeName: string) => deprecatedOSNames.includes(bootVolumeName);

export const getDataImportCronFromDataSource = (
dataImportCrons: V1beta1DataImportCron[],
dataSource: V1beta1DataSource,
): V1beta1DataImportCron =>
dataImportCrons?.find(
(cron) =>
cron?.spec?.managedDataSource === getName(dataSource) &&
getNamespace(dataSource) === getNamespace(cron),
);
28 changes: 22 additions & 6 deletions src/utils/resources/bootableresources/hooks/useBootableVolumes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ import {
PersistentVolumeClaimModel,
VolumeSnapshotModel,
} from '@kubevirt-ui/kubevirt-api/console';
import { V1beta1DataSource } from '@kubevirt-ui/kubevirt-api/containerized-data-importer/models';
import DataImportCronModel from '@kubevirt-ui/kubevirt-api/console/models/DataImportCronModel';
import {
V1beta1DataImportCron,
V1beta1DataSource,
} from '@kubevirt-ui/kubevirt-api/containerized-data-importer/models';
import { IoK8sApiCoreV1PersistentVolumeClaim } from '@kubevirt-ui/kubevirt-api/kubernetes';
import { VolumeSnapshotKind } from '@kubevirt-utils/components/SelectSnapshot/types';
import { ALL_PROJECTS } from '@kubevirt-utils/hooks/constants';
Expand Down Expand Up @@ -36,6 +40,14 @@ const useBootableVolumes: UseBootableVolumes = (namespace) => {
},
});

const [dataImportCrons, loadedDataImportCrons, dataImportCronsError] = useK8sWatchResource<
V1beta1DataImportCron[]
>({
groupVersionKind: modelToGroupVersionKind(DataImportCronModel),
isList: true,
namespace: projectsNamespace,
});

// getting all pvcs since there could be a case where a DS has the label and it's underlying PVC does not
const [pvcs, loadedPVCs, loadErrorPVCs] = useK8sWatchResource<
IoK8sApiCoreV1PersistentVolumeClaim[]
Expand All @@ -52,16 +64,19 @@ const useBootableVolumes: UseBootableVolumes = (namespace) => {
namespace: projectsNamespace,
});

const error = useMemo(() => dataSourcesError || loadErrorPVCs, [dataSourcesError, loadErrorPVCs]);
const error = useMemo(
() => dataSourcesError || loadErrorPVCs || dataImportCronsError,
[dataSourcesError, loadErrorPVCs, dataImportCronsError],
);

const loaded = useMemo(
() => (error ? true : loadedDataSources && loadedPVCs),
[error, loadedDataSources, loadedPVCs],
() => (error ? true : loadedDataSources && loadedPVCs && loadedDataImportCrons),
[error, loadedDataSources, loadedPVCs, loadedDataImportCrons],
);

const readyOrCloningDataSources = useMemo(
() => getReadyOrCloningOrUploadingDataSources(dataSources),
[dataSources],
() => getReadyOrCloningOrUploadingDataSources(dataSources, dataImportCrons),
[dataSources, dataImportCrons],
);
const pvcSources = useMemo(() => convertResourceArrayToMap(pvcs, true), [pvcs]);

Expand Down Expand Up @@ -89,6 +104,7 @@ const useBootableVolumes: UseBootableVolumes = (namespace) => {

return {
bootableVolumes,
dataImportCrons,
error,
loaded,
pvcSources,
Expand Down
31 changes: 19 additions & 12 deletions src/utils/resources/shared.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { modelToGroupVersionKind } from '@kubevirt-ui/kubevirt-api/console';
import { V1beta1DataSource } from '@kubevirt-ui/kubevirt-api/containerized-data-importer/models';
import {
V1beta1DataImportCron,
V1beta1DataSource,
} from '@kubevirt-ui/kubevirt-api/containerized-data-importer/models';
import { V1alpha1Condition, V1VirtualMachine } from '@kubevirt-ui/kubevirt-api/kubevirt';
import { ALL_NAMESPACES_SESSION_KEY } from '@kubevirt-utils/hooks/constants';
import { TemplateModel } from '@kubevirt-utils/models';
Expand All @@ -16,6 +19,7 @@ import {
import { isDataSourceReady } from '../../views/datasources/utils';

import { isEmpty } from './../utils/utils';
import { getDataImportCronFromDataSource } from './bootableresources/helpers';
import {
isDataSourceCloning,
isDataSourceUploading,
Expand Down Expand Up @@ -327,25 +331,28 @@ export const convertResourceArrayToMap = <A extends K8sResourceCommon = K8sResou
export const getAvailableDataSources = (dataSources: V1beta1DataSource[]): V1beta1DataSource[] =>
dataSources?.filter((dataSource) => isDataSourceReady(dataSource));

export const isDataImportCronProgressing = (dataImportCron: V1beta1DataImportCron): boolean =>
dataImportCron?.status?.conditions?.find((condition) => condition.type === 'UpToDate')?.reason ===
'ImportProgressing';

/**
* function to get all V1beta1DataSource objects with condition type 'Ready'and status 'True'
* and/or also those with 'False' status but only 'CloneScheduled' or 'CloneInProgress' reason (cloning of the DS in progress)
* @param {V1beta1DataSource[]} dataSources list of DataSources to be filtered
* @param {V1beta1DataImportCron[]} dataImportCrons list of DataImportCrons related to DataSources
* @returns list of available/ready/cloning DataSources
*/
export const getAvailableOrCloningDataSources = (
dataSources: V1beta1DataSource[],
): V1beta1DataSource[] =>
dataSources?.filter(
(dataSource) => isDataSourceReady(dataSource) || isDataSourceCloning(dataSource),
);

export const getReadyOrCloningOrUploadingDataSources = (
dataSources: V1beta1DataSource[],
dataImportCrons: V1beta1DataImportCron[],
): V1beta1DataSource[] =>
dataSources?.filter(
(dataSource) =>
dataSources?.filter((dataSource) => {
const dataImportCron = getDataImportCronFromDataSource(dataImportCrons, dataSource);

return (
isDataSourceReady(dataSource) ||
isDataSourceCloning(dataSource) ||
isDataSourceUploading(dataSource),
);
isDataSourceUploading(dataSource) ||
isDataImportCronProgressing(dataImportCron)
);
});
3 changes: 2 additions & 1 deletion src/views/bootablevolumes/list/BootableVolumesList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const BootableVolumesList: FC = () => {
const { ns: namespace } = useParams<{ ns: string }>();
const { t } = useKubevirtTranslation();

const { bootableVolumes, error, loaded } = useBootableVolumes(namespace);
const { bootableVolumes, dataImportCrons, error, loaded } = useBootableVolumes(namespace);
const [preferences] = useClusterPreferences();

const rowFilters = useBootableVolumesFilters();
Expand Down Expand Up @@ -117,6 +117,7 @@ const BootableVolumesList: FC = () => {
</div>
)}
rowData={{
dataImportCrons,
preferences,
}}
columns={activeColumns}
Expand Down
24 changes: 18 additions & 6 deletions src/views/bootablevolumes/list/components/BootableVolumesRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,24 @@ import React, { FC } from 'react';
import DataSourceActions from 'src/views/datasources/actions/DataSourceActions';

import DataSourceModel from '@kubevirt-ui/kubevirt-api/console/models/DataSourceModel';
import { V1beta1DataSource } from '@kubevirt-ui/kubevirt-api/containerized-data-importer/models';
import {
V1beta1DataImportCron,
V1beta1DataSource,
} from '@kubevirt-ui/kubevirt-api/containerized-data-importer/models';
import { V1beta1VirtualMachineClusterPreference } from '@kubevirt-ui/kubevirt-api/kubevirt';
import DeprecatedBadge from '@kubevirt-utils/components/badges/DeprecatedBadge/DeprecatedBadge';
import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation';
import {
getBootableVolumeGroupVersionKind,
getDataImportCronFromDataSource,
isBootableVolumePVCKind,
isDeprecated,
} from '@kubevirt-utils/resources/bootableresources/helpers';
import { getName, getNamespace } from '@kubevirt-utils/resources/shared';
import {
getName,
getNamespace,
isDataImportCronProgressing,
} from '@kubevirt-utils/resources/shared';
import { ANNOTATIONS } from '@kubevirt-utils/resources/template';
import { isDataSourceCloning } from '@kubevirt-utils/resources/template/hooks/useVmTemplateSource/utils';
import { NO_DATA_DASH } from '@kubevirt-utils/resources/vm/utils/constants';
Expand All @@ -29,15 +37,21 @@ const BootableVolumesRow: FC<
RowProps<
BootableResource,
{
dataImportCrons: V1beta1DataImportCron[];
preferences: V1beta1VirtualMachineClusterPreference[];
}
>
> = ({ activeColumnIDs, obj, rowData: { preferences } }) => {
> = ({ activeColumnIDs, obj, rowData: { dataImportCrons, preferences } }) => {
const { t } = useKubevirtTranslation();

const bootableVolumeName = getName(obj);
const bootableVolumeNamespace = getNamespace(obj);

const dataImportCron = getDataImportCronFromDataSource(dataImportCrons, obj as V1beta1DataSource);

const isCloning =
isDataSourceCloning(obj as V1beta1DataSource) || isDataImportCronProgressing(dataImportCron);

return (
<>
<TableData activeColumnIDs={activeColumnIDs} className="pf-m-width-20" id="name">
Expand All @@ -49,9 +63,7 @@ const BootableVolumesRow: FC<
namespace={bootableVolumeNamespace}
/>
{isDeprecated(bootableVolumeName) && <DeprecatedBadge />}
{obj.kind === DataSourceModel.kind && isDataSourceCloning(obj as V1beta1DataSource) && (
<Label>{t('Clone in progress')}</Label>
)}
{obj.kind === DataSourceModel.kind && isCloning && <Label>{t('Clone in progress')}</Label>}
</TableData>
<TableData activeColumnIDs={activeColumnIDs} className="pf-m-width-20" id="namespace">
<ResourceLink kind="Namespace" name={bootableVolumeNamespace} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import React, { FC, MouseEvent } from 'react';
import { useInstanceTypeVMStore } from '@catalog/CreateFromInstanceTypes/state/useInstanceTypeVMStore';
import { InstanceTypeVMStore } from '@catalog/CreateFromInstanceTypes/state/utils/types';
import { getTemplateOSIcon, getVolumeNameOSIcon } from '@catalog/templatescatalog/utils/os-icons';
import { V1beta1DataSource } from '@kubevirt-ui/kubevirt-api/containerized-data-importer/models';
import {
V1beta1DataImportCron,
V1beta1DataSource,
} from '@kubevirt-ui/kubevirt-api/containerized-data-importer/models';
import { IoK8sApiCoreV1PersistentVolumeClaim } from '@kubevirt-ui/kubevirt-api/kubernetes';
import { V1beta1VirtualMachineClusterPreference } from '@kubevirt-ui/kubevirt-api/kubevirt';
import DeprecatedBadge from '@kubevirt-utils/components/badges/DeprecatedBadge/DeprecatedBadge';
Expand All @@ -18,7 +21,11 @@ import {
getVolumeSnapshotStorageClass,
} from '@kubevirt-utils/resources/bootableresources/selectors';
import { BootableVolume } from '@kubevirt-utils/resources/bootableresources/types';
import { getName, getNamespace } from '@kubevirt-utils/resources/shared';
import {
getName,
getNamespace,
isDataImportCronProgressing,
} from '@kubevirt-utils/resources/shared';
import { ANNOTATIONS } from '@kubevirt-utils/resources/template';
import {
isDataSourceCloning,
Expand All @@ -38,6 +45,7 @@ type BootableVolumeRowProps = {
bootableVolume: BootableVolume;
rowData: {
bootableVolumeSelectedState: [BootableVolume, InstanceTypeVMStore['onSelectCreatedVolume']];
dataImportCron: V1beta1DataImportCron;
favorites: [isFavorite: boolean, updaterFavorites: (val: boolean) => void];
preference: V1beta1VirtualMachineClusterPreference;
pvcSource: IoK8sApiCoreV1PersistentVolumeClaim;
Expand All @@ -50,6 +58,7 @@ const BootableVolumeRow: FC<BootableVolumeRowProps> = ({
bootableVolume,
rowData: {
bootableVolumeSelectedState: [selectedBootableVolume, setSelectedBootableVolume],
dataImportCron,
favorites,
preference,
pvcSource,
Expand All @@ -74,6 +83,9 @@ const BootableVolumeRow: FC<BootableVolumeRowProps> = ({
};

const { volumeListNamespace } = useInstanceTypeVMStore();
const isCloning =
isDataImportCronProgressing(dataImportCron) ||
isDataSourceCloning(bootableVolume as V1beta1DataSource);

return (
<Tr
Expand Down Expand Up @@ -103,9 +115,7 @@ const BootableVolumeRow: FC<BootableVolumeRowProps> = ({
{bootVolumeName}
</Text>
{isDeprecated(bootVolumeName) && <DeprecatedBadge />}
{isDataSourceCloning(bootableVolume as V1beta1DataSource) && (
<Label className="vm-catalog-row-label">{t('Clone in progress')}</Label>
)}
{isCloning && <Label className="vm-catalog-row-label">{t('Clone in progress')}</Label>}
{isDataSourceUploading(bootableVolume as V1beta1DataSource) && (
<Label className="vm-catalog-row-label">{t('Upload in progress')}</Label>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@ import {
UseBootableVolumesValues,
} from '@catalog/CreateFromInstanceTypes/state/utils/types';
import { DEFAULT_PREFERENCE_LABEL } from '@catalog/CreateFromInstanceTypes/utils/constants';
import { V1beta1DataSource } from '@kubevirt-ui/kubevirt-api/containerized-data-importer/models';
import { V1beta1VirtualMachineClusterPreference } from '@kubevirt-ui/kubevirt-api/kubevirt';
import { UserSettingFavorites } from '@kubevirt-utils/hooks/useKubevirtUserSettings/utils/types';
import { getBootableVolumePVCSource } from '@kubevirt-utils/resources/bootableresources/helpers';
import {
getBootableVolumePVCSource,
getDataImportCronFromDataSource,
} from '@kubevirt-utils/resources/bootableresources/helpers';
import { BootableVolume } from '@kubevirt-utils/resources/bootableresources/types';
import { getLabel, getName } from '@kubevirt-utils/resources/shared';
import { TableColumn } from '@openshift-console/dynamic-plugin-sdk';
Expand Down Expand Up @@ -38,7 +42,7 @@ const BootableVolumeTable: FC<BootableVolumeTableProps> = ({
sortedPaginatedData,
}) => {
const [volumeFavorites, updateFavorites] = favorites;
const { pvcSources, volumeSnapshotSources } = bootableVolumesData;
const { dataImportCrons, pvcSources, volumeSnapshotSources } = bootableVolumesData;
return (
<Table className="BootableVolumeList-table" variant={TableVariant.compact}>
<Thead>
Expand All @@ -63,6 +67,10 @@ const BootableVolumeTable: FC<BootableVolumeTableProps> = ({
<BootableVolumeRow
rowData={{
bootableVolumeSelectedState: selectedBootableVolumeState,
dataImportCron: getDataImportCronFromDataSource(
dataImportCrons,
bs as V1beta1DataSource,
),
favorites: [
volumeFavorites?.includes(bs?.metadata?.name),
(addTofavorites: boolean) =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Dispatch } from 'react';

import { V1beta1DataImportCron } from '@kubevirt-ui/kubevirt-api/containerized-data-importer/models';
import { IoK8sApiCoreV1PersistentVolumeClaim } from '@kubevirt-ui/kubevirt-api/kubernetes';
import {
V1beta1VirtualMachineClusterInstancetype,
Expand Down Expand Up @@ -27,6 +28,7 @@ export type UseInstanceTypeAndPreferencesValues = {

export type UseBootableVolumesValues = {
bootableVolumes: BootableVolume[];
dataImportCrons: V1beta1DataImportCron[];
error: Error;
loaded: boolean;
pvcSources: {
Expand Down
Loading