Skip to content

Commit

Permalink
Merge pull request #2133 from metalice/CNV-23485-iso-flow
Browse files Browse the repository at this point in the history
CNV-23485: Adding iso flow
  • Loading branch information
openshift-merge-bot[bot] committed Aug 21, 2024
2 parents aa8c707 + 648af5d commit 708fff9
Show file tree
Hide file tree
Showing 18 changed files with 290 additions and 93 deletions.
13 changes: 7 additions & 6 deletions locales/en/plugin__kubevirt-plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"<0>Clicking \"Launch Remote Viewer\" will download a .vv file and launch <2>Remote Viewer</2></0><1><0>Remote Viewer</0> is available for most operating systems. To install it, search for it in GNOME Software or run the following:</1>": "<0>Clicking \"Launch Remote Viewer\" will download a .vv file and launch <2>Remote Viewer</2></0><1><0>Remote Viewer</0> is available for most operating systems. To install it, search for it in GNOME Software or run the following:</1>",
"<0>Deleting this PVC will also delete <2>{{pvcName}}</2> Data Volume</0>": "<0>Deleting this PVC will also delete <2>{{pvcName}}</2> Data Volume</0>",
"<0>Donuts chart represent current values.</0><1>Sparkline charts represent data over time</1>": "<0>Donuts chart represent current values.</0><1>Sparkline charts represent data over time</1>",
"<0>From the Volume table, select DataSources to boot your VirtualMachine.</0><1>To add a bootable volume that is not listed, click <2></2></1><2>Learn how to <2>create a bootable volume automatically by using pipelines</2></2>": "<0>From the Volume table, select DataSources to boot your VirtualMachine.</0><1>To add a bootable volume that is not listed, click <2></2></1><2>Learn how to <2>create a bootable volume automatically by using pipelines</2></2>",
"<0>From the Volume table, select a bootable volume to boot your VirtualMachine.</0><1>To add a bootable volume that is not listed, click <2></2></1><2>Learn how to <2>create a bootable volume automatically by using pipelines</2></2>": "<0>From the Volume table, select a bootable volume to boot your VirtualMachine.</0><1>To add a bootable volume that is not listed, click <2></2></1><2>Learn how to <2>create a bootable volume automatically by using pipelines</2></2>",
"<0>List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.</0><1><0>{{kind}}</0><1>metadata</1><2>ownerReferences</2></1>": "<0>List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.</0><1><0>{{kind}}</0><1>metadata</1><2>ownerReferences</2></1>",
"<0>No volumes found</0>To add a bootable volume, click <2></2> Add volume": "<0>No volumes found</0>To add a bootable volume, click <2></2> Add volume",
"<0>Open an SSH connection with the VM using the cluster API server. You must be able to access the API server and have virtctl command line tool installed.</0><br/><2>For more details, see <2>Installing virtctl</2> in Getting started with OpenShift Virtualization.</2>": "<0>Open an SSH connection with the VM using the cluster API server. You must be able to access the API server and have virtctl command line tool installed.</0><br/><2>For more details, see <2>Installing virtctl</2> in Getting started with OpenShift Virtualization.</2>",
Expand Down Expand Up @@ -77,6 +77,7 @@
"Active users ({{users}})": "Active users ({{users}})",
"Activity": "Activity",
"Add a NetworkAttachmentDefinition to this namespace in order to use checkups": "Add a NetworkAttachmentDefinition to this namespace in order to use checkups",
"Add a new bootable volume to the cluster.": "Add a new bootable volume to the cluster.",
"Add a snapshot available on the cluster to the VirtualMachine.": "Add a snapshot available on the cluster to the VirtualMachine.",
"Add a volume already available on the cluster.": "Add a volume already available on the cluster.",
"Add affinity rule": "Add affinity rule",
Expand Down Expand Up @@ -302,6 +303,7 @@
"Container disk": "Container disk",
"Container Image": "Container Image",
"Container is required.": "Container is required.",
"Content from container registry": "Content from container registry",
"Copied": "Copied",
"Copy SSH command": "Copy SSH command",
"Copy template's boot source disk": "Copy template's boot source disk",
Expand Down Expand Up @@ -440,7 +442,6 @@
"Documentation": "Documentation",
"Domain": "Domain",
"Download": "Download",
"Download from registry": "Download from registry",
"Download the MSI from ": "Download the MSI from ",
"Download the virtctl command-line utility": "Download the virtctl command-line utility",
"Drag and drop an image or upload one": "Drag and drop an image or upload one",
Expand Down Expand Up @@ -594,6 +595,7 @@
"Image URL": "Image URL",
"Import content via container registry.": "Import content via container registry.",
"Import content via URL (HTTP or HTTPS endpoint).": "Import content via URL (HTTP or HTTPS endpoint).",
"Import from": "Import from",
"In": "In",
"In order to add a new source for {{osName}} you will need to delete the following PVC:": "In order to add a new source for {{osName}} you will need to delete the following PVC:",
"In process": "In process",
Expand Down Expand Up @@ -1238,6 +1240,7 @@
"The VirtualMachineInstance has": "The VirtualMachineInstance has",
"This field is required": "This field is required",
"This is a CD-ROM boot source": "This is a CD-ROM boot source",
"This is an ISO file": "This is an ISO file",
"This key will override the SSH key secret set on the template": "This key will override the SSH key secret set on the template",
"This Persistent Volume Claim will be created using a DataVolume through Containerized Data Importer (CDI)": "This Persistent Volume Claim will be created using a DataVolume through Containerized Data Importer (CDI)",
"This process can take 1-2 minutes to complete.": "This process can take 1-2 minutes to complete.",
Expand Down Expand Up @@ -1292,17 +1295,16 @@
"Upload (Upload a new file to a PVC)": "Upload (Upload a new file to a PVC)",
"Upload a base image from local disk": "Upload a base image from local disk",
"Upload a new file to a PVC. A new PVC will be created.": "Upload a new file to a PVC. A new PVC will be created.",
"Upload a new volume, or use an existing PersistentVolumeClaim (PVC), VolumeSnapshot or DataSource.": "Upload a new volume, or use an existing PersistentVolumeClaim (PVC), VolumeSnapshot or DataSource.",
"Upload canceled": "Upload canceled",
"Upload cancelled": "Upload cancelled",
"Upload data": "Upload data",
"Upload data to Persistent Volume Claim": "Upload data to Persistent Volume Claim",
"Upload error": "Upload error",
"Upload finished": "Upload finished",
"Upload in progress": "Upload in progress",
"Upload new": "Upload new",
"Upload new file using the \"Upload data to Persistent Volume Claim\" page": "Upload new file using the \"Upload data to Persistent Volume Claim\" page",
"Upload PVC image": "Upload PVC image",
"Upload volume": "Upload volume",
"Uploading": "Uploading",
"Uploading data to Persistent Volume Claim": "Uploading data to Persistent Volume Claim",
"URL": "URL",
Expand All @@ -1315,14 +1317,13 @@
"Use custom registration server url": "Use custom registration server url",
"Use DataSource": "Use DataSource",
"Use existing": "Use existing",
"Use existing volume": "Use existing volume",
"Use existing volume snapshot": "Use existing volume snapshot",
"Use optimized access mode & volume mode settings from StorageProfile resource.": "Use optimized access mode & volume mode settings from StorageProfile resource.",
"Use our collection of resources to help you get started with virtualization.": "Use our collection of resources to help you get started with virtualization.",
"Use template size PVC": "Use template size PVC",
"Use the default Template disk source": "Use the default Template disk source",
"Use this disk as a boot source": "Use this disk as a boot source",
"Use UEFI when bootloading the guest OS. Requires SMM feature, if the SMM feature is not set, choosing this method will set it to true": "Use UEFI when bootloading the guest OS. Requires SMM feature, if the SMM feature is not set, choosing this method will set it to true",
"Use volume already available on the cluster": "Use volume already available on the cluster",
"Used": "Used",
"Used bytes": "Used bytes",
"Used of ": "Used of ",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const AddBootableVolumeModal: FC<AddBootableVolumeModalProps> = ({
});

const [sourceType, setSourceType] = useState<DROPDOWN_FORM_SELECTION>(
DROPDOWN_FORM_SELECTION.UPLOAD_IMAGE,
DROPDOWN_FORM_SELECTION.UPLOAD_VOLUME,
);

const applyStorageProfileState = useState<boolean>(true);
Expand Down Expand Up @@ -110,9 +110,7 @@ const AddBootableVolumeModal: FC<AddBootableVolumeModalProps> = ({
obj={emptyDataSource}
submitBtnText={t('Save')}
>
{t(
'Upload a new volume, or use an existing PersistentVolumeClaim (PVC), VolumeSnapshot or DataSource.',
)}
{t('Add a new bootable volume to the cluster.')}
<Form className="pf-u-mt-md">
<SourceTypeSelection
formSelection={sourceType}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import SelectToggle from '@kubevirt-utils/components/toggles/SelectToggle';
import { t } from '@kubevirt-utils/hooks/useKubevirtTranslation';
import usePermissions from '@kubevirt-utils/hooks/usePermissions/usePermissions';
import useCanCreateBootableVolume from '@kubevirt-utils/resources/bootableresources/hooks/useCanCreateBootableVolume';
import { FormGroup } from '@patternfly/react-core';
import { Divider, FormGroup, SelectGroup } from '@patternfly/react-core';
import { Select, SelectOption } from '@patternfly/react-core';

import { DROPDOWN_FORM_SELECTION, optionsValueLabelMapper } from '../../utils/constants';
Expand Down Expand Up @@ -40,7 +40,7 @@ const SourceTypeSelection: FC<SourceTypeSelectionProps> = ({
setFormSelection(
!canUploadImage
? DROPDOWN_FORM_SELECTION.USE_REGISTRY
: DROPDOWN_FORM_SELECTION.UPLOAD_IMAGE,
: DROPDOWN_FORM_SELECTION.UPLOAD_VOLUME,
);
}
}, [canUploadImage, permissionsLoading, loading, setFormSelection]);
Expand All @@ -61,33 +61,43 @@ const SourceTypeSelection: FC<SourceTypeSelectionProps> = ({
onSelect={onSelect}
selected={formSelection}
>
<SelectOption
isDisabled={!canUploadImage}
value={DROPDOWN_FORM_SELECTION.UPLOAD_IMAGE}
{...(!canUploadImage && {
description: t("You don't have permission to perform this action"),
})}
>
{optionsValueLabelMapper[DROPDOWN_FORM_SELECTION.UPLOAD_IMAGE]}
</SelectOption>

<SelectOption isDisabled={!canCreatePVC} value={DROPDOWN_FORM_SELECTION.USE_EXISTING_PVC}>
{optionsValueLabelMapper[DROPDOWN_FORM_SELECTION.USE_EXISTING_PVC]}
</SelectOption>

<SelectOption isDisabled={!canCreateSnapshots} value={DROPDOWN_FORM_SELECTION.USE_SNAPSHOT}>
{optionsValueLabelMapper[DROPDOWN_FORM_SELECTION.USE_SNAPSHOT]}
</SelectOption>

<SelectOption
description={t(
'Creates a DataImportCron, which defines a cron job to poll and import the disk image.',
)}
isDisabled={!canCreateDS}
value={DROPDOWN_FORM_SELECTION.USE_REGISTRY}
>
{optionsValueLabelMapper[DROPDOWN_FORM_SELECTION.USE_REGISTRY]}
</SelectOption>
<SelectGroup label={t('Upload new')}>
<SelectOption
isDisabled={!canUploadImage}
value={DROPDOWN_FORM_SELECTION.UPLOAD_VOLUME}
{...(!canUploadImage && {
description: t("You don't have permission to perform this action"),
})}
>
{optionsValueLabelMapper[DROPDOWN_FORM_SELECTION.UPLOAD_VOLUME]}
</SelectOption>
</SelectGroup>
<Divider />
<SelectGroup label={t('Use existing')}>
<SelectOption
description={t('Use volume already available on the cluster')}
isDisabled={!canCreatePVC}
value={DROPDOWN_FORM_SELECTION.USE_EXISTING_PVC}
>
{optionsValueLabelMapper[DROPDOWN_FORM_SELECTION.USE_EXISTING_PVC]}
</SelectOption>
<SelectOption
isDisabled={!canCreateSnapshots}
value={DROPDOWN_FORM_SELECTION.USE_SNAPSHOT}
>
{optionsValueLabelMapper[DROPDOWN_FORM_SELECTION.USE_SNAPSHOT]}
</SelectOption>
</SelectGroup>
<Divider />
<SelectGroup label={t('Import from')}>
<SelectOption
description={t('Content from container registry')}
isDisabled={!canCreateDS}
value={DROPDOWN_FORM_SELECTION.USE_REGISTRY}
>
{optionsValueLabelMapper[DROPDOWN_FORM_SELECTION.USE_REGISTRY]}
</SelectOption>
</SelectGroup>
</Select>
</FormGroup>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type VolumeSourceProps = {
setBootableVolumeField: (
key: keyof AddBootableVolumeState,
fieldKey?: string,
) => (value: string) => void;
) => (value: boolean | File | number | string) => void;
sourceType: DROPDOWN_FORM_SELECTION;
upload: DataUpload;
};
Expand All @@ -31,10 +31,12 @@ const VolumeSource: FC<VolumeSourceProps> = ({
const { registryURL, uploadFile, uploadFilename } = bootableVolume || {};

const sourceComponentByType = {
[DROPDOWN_FORM_SELECTION.UPLOAD_IMAGE]: (
[DROPDOWN_FORM_SELECTION.UPLOAD_VOLUME]: (
<DiskSourceUploadPVC
isIso={bootableVolume.isIso}
label={t('Upload PVC image')}
relevantUpload={upload}
setIsIso={setBootableVolumeField('isIso')}
setUploadFile={setBootableVolumeField('uploadFile')}
setUploadFileName={setBootableVolumeField('uploadFilename')}
uploadFile={uploadFile}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React, { FC } from 'react';

import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation';
import { Checkbox } from '@patternfly/react-core';

type DiskSourceUploadISOProps = {
isIso: boolean;
setIsIso: (value: boolean) => void;
};

const DiskSourceUploadISO: FC<DiskSourceUploadISOProps> = ({ isIso, setIsIso }) => {
const { t } = useKubevirtTranslation();

return (
<Checkbox
id="iso-checkbox"
isChecked={isIso}
label={t('This is an ISO file')}
onChange={(_, value: boolean) => setIsIso(value)}
/>
);
};

export default DiskSourceUploadISO;
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,25 @@ import { DataUpload } from '@kubevirt-utils/hooks/useCDIUpload/useCDIUpload';
import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation';
import { DropEvent, FileUpload, FormGroup } from '@patternfly/react-core';

import DiskSourceUploadISO from './DiskSourceUploadISO';
import { DiskSourceUploadPVCProgress } from './DiskSourceUploadPVCProgress';

type DiskSourceUploadPVCProps = {
isIso: boolean;
label?: string;
relevantUpload: DataUpload;
setIsIso: (value: boolean) => void;
setUploadFile: (file: File | string) => void;
setUploadFileName: (name: string) => void;
uploadFile: File | string;
uploadFileName: string;
};

const DiskSourceUploadPVC: FC<DiskSourceUploadPVCProps> = ({
isIso,
label,
relevantUpload,
setIsIso,
setUploadFile,
setUploadFileName,
uploadFile,
Expand Down Expand Up @@ -54,6 +59,7 @@ const DiskSourceUploadPVC: FC<DiskSourceUploadPVCProps> = ({
value={uploadFile}
/>
</FormGroup>
<DiskSourceUploadISO isIso={isIso} setIsIso={setIsIso} />
{relevantUpload && <DiskSourceUploadPVCProgress upload={relevantUpload} />}
</>
);
Expand Down
14 changes: 8 additions & 6 deletions src/utils/components/AddBootableVolumeModal/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,25 @@ import { CDI_BIND_REQUESTED_ANNOTATION } from '@kubevirt-utils/hooks/useCDIUploa
import { t } from '@kubevirt-utils/hooks/useKubevirtTranslation';

export enum DROPDOWN_FORM_SELECTION {
UPLOAD_IMAGE = 'upload',
UPLOAD_VOLUME = 'volume',
USE_EXISTING_PVC = 'pvc',
USE_REGISTRY = 'registry',
USE_SNAPSHOT = 'snapshot',
}

export const optionsValueLabelMapper = {
[DROPDOWN_FORM_SELECTION.UPLOAD_IMAGE]: t('Upload volume'),
[DROPDOWN_FORM_SELECTION.USE_EXISTING_PVC]: t('Use existing volume'),
[DROPDOWN_FORM_SELECTION.USE_REGISTRY]: t('Download from registry'),
[DROPDOWN_FORM_SELECTION.USE_SNAPSHOT]: t('Use existing volume snapshot'),
[DROPDOWN_FORM_SELECTION.UPLOAD_VOLUME]: t('Volume'),
[DROPDOWN_FORM_SELECTION.USE_EXISTING_PVC]: t('Volume'),
[DROPDOWN_FORM_SELECTION.USE_REGISTRY]: t('Registry'),
[DROPDOWN_FORM_SELECTION.USE_SNAPSHOT]: t('Volume snapshot'),
};

export type AddBootableVolumeState = {
annotations: { [key: string]: string };
bootableVolumeName: string;
bootableVolumeNamespace: string;
cronExpression: string;
isIso: boolean;
labels: { [key: string]: string };
pvcName: string;
pvcNamespace: string;
Expand All @@ -47,13 +48,14 @@ export type AddBootableVolumeState = {
export type SetBootableVolumeFieldType = (
key: keyof AddBootableVolumeState,
fieldKey?: string,
) => (value: number | string) => void;
) => (value: boolean | number | string) => void;

export const initialBootableVolumeState: AddBootableVolumeState = {
annotations: {},
bootableVolumeName: null,
bootableVolumeNamespace: null,
cronExpression: null,
isIso: false,
labels: {},
pvcName: null,
pvcNamespace: null,
Expand Down
11 changes: 9 additions & 2 deletions src/utils/components/AddBootableVolumeModal/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
V1beta1StorageSpecVolumeModeEnum,
} from '@kubevirt-ui/kubevirt-api/kubevirt';
import { UploadDataProps } from '@kubevirt-utils/hooks/useCDIUpload/useCDIUpload';
import { KUBEVIRT_ISO_LABEL } from '@kubevirt-utils/resources/bootableresources/constants';
import { BootableVolume } from '@kubevirt-utils/resources/bootableresources/types';
import { buildOwnerReference } from '@kubevirt-utils/resources/shared';
import { DATA_SOURCE_CRONJOB_LABEL } from '@kubevirt-utils/resources/template';
Expand Down Expand Up @@ -54,7 +55,7 @@ export const createBootableVolume: createBootableVolumeType =
);

const actionBySourceType: Record<string, () => Promise<V1beta1DataSource>> = {
[DROPDOWN_FORM_SELECTION.UPLOAD_IMAGE]: () =>
[DROPDOWN_FORM_SELECTION.UPLOAD_VOLUME]: () =>
createBootableVolumeFromUpload(
bootableVolume,
bootableVolumeNamespace,
Expand Down Expand Up @@ -144,7 +145,7 @@ const createBootableVolumeFromUpload = async (
draftDataSource: V1beta1DataSource,
uploadData: ({ dataVolume, file }: UploadDataProps) => Promise<void>,
) => {
const { uploadFile } = bootableVolume || {};
const { isIso, uploadFile } = bootableVolume || {};

const bootableVolumeToCreate = getDataVolumeWithSource(
bootableVolume,
Expand All @@ -155,6 +156,12 @@ const createBootableVolumeFromUpload = async (
);

const dataSourceToCreate = produce(draftDataSource, (draftDS) => {
if (isIso) {
draftDS.metadata.labels = {
...(draftDS.metadata.labels || {}),
[KUBEVIRT_ISO_LABEL]: 'true',
};
}
draftDS.spec.source = {
pvc: {
name: bootableVolumeToCreate.metadata.name,
Expand Down
3 changes: 2 additions & 1 deletion src/utils/components/CloudinitModal/utils/useCloudInit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
V1VirtualMachine,
V1Volume,
} from '@kubevirt-ui/kubevirt-api/kubevirt';
import { InterfaceTypes } from '@kubevirt-utils/components/DiskModal/utils/types';
import { getVolumes } from '@kubevirt-utils/resources/vm';

import {
Expand Down Expand Up @@ -112,7 +113,7 @@ export const useCloudInit = (vm: V1VirtualMachine): UseCloudInitValues => {
if (!cloudInitDisk) {
vmDraft.spec.template.spec.domain.devices.disks.push({
disk: {
bus: 'virtio',
bus: InterfaceTypes.VIRTIO,
},
name: cloudInitDiskName,
});
Expand Down
Loading

0 comments on commit 708fff9

Please sign in to comment.