Skip to content

Commit

Permalink
Add pause/unpause VM feature
Browse files Browse the repository at this point in the history
  • Loading branch information
pcbailey committed Jan 16, 2020
1 parent 57bede6 commit 65bc648
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 8 deletions.
@@ -0,0 +1 @@
export * from './vm-status-modal';
@@ -0,0 +1,61 @@
import * as React from 'react';
import { Modal } from '@patternfly/react-core';
import { HandlePromiseProps, withHandlePromise } from '@console/internal/components/utils';
import { ModalComponentProps } from '@console/internal/components/factory';
import { ModalFooter } from '../modal/modal-footer';
import { PAUSED_VM_MODAL_MESSAGE } from '../../../constants/vm';
import { VMLikeEntityKind } from '../../../types';

const modalTitle = 'Edit pause state';

const VMStatusModalComponent = ({
vmLikeEntity,
isOpen,
setOpen,
title = modalTitle,
handlePromise,
inProgress,
errorMessage,
}: VMStatusModalProps) => {
const [showPatchError, setPatchError] = React.useState<boolean>(false);

const footer = (
<ModalFooter
errorMessage={showPatchError && errorMessage}
inProgress={inProgress}
onSubmit={() => {
// this try/catch is only a placeholder for the unpauseVM function
try {
// TODO Create function to unpause VM
} catch (error) {
setPatchError(error);
}
}}
onCancel={() => setOpen(false)}
submitButtonText="Unpause"
/>
);

return (
<Modal
title={title}
isOpen={isOpen}
isSmall
onClose={() => setOpen(false)}
footer={footer}
isFooterLeftAligned
>
<div>{PAUSED_VM_MODAL_MESSAGE}</div>
</Modal>
);
};

export type VMStatusModalProps = HandlePromiseProps &
ModalComponentProps & {
vmLikeEntity: VMLikeEntityKind;
title?: string;
isOpen: boolean;
setOpen: (isOpen: boolean) => void;
};

export const VMStatusModal = withHandlePromise(VMStatusModalComponent);
@@ -1,6 +1,6 @@
import * as React from 'react';
import { PodKind, K8sResourceKind } from '@console/internal/module/k8s';
import { OffIcon, UnknownIcon, SyncAltIcon } from '@patternfly/react-icons';
import { OffIcon, PausedIcon, UnknownIcon } from '@patternfly/react-icons';
import {
PopoverStatus,
StatusIconAndText,
Expand All @@ -10,12 +10,23 @@ import {
ProgressStatus,
PendingStatus,
} from '@console/shared';
import { Progress, ProgressVariant, ProgressSize } from '@patternfly/react-core';
import {
Progress,
ProgressVariant,
ProgressSize,
Button,
ButtonVariant,
} from '@patternfly/react-core';
import { Link } from 'react-router-dom';
import { resourcePath } from '@console/internal/components/utils';
import { PodModel } from '@console/internal/models';
import { VirtualMachineModel } from '../../models';
import { VM_DETAIL_EVENTS_HREF, CDI_KUBEVIRT_IO, STORAGE_IMPORT_PVC_NAME } from '../../constants';
import {
VM_DETAIL_EVENTS_HREF,
CDI_KUBEVIRT_IO,
STORAGE_IMPORT_PVC_NAME,
PAUSED_VM_MODAL_MESSAGE,
} from '../../constants';
import { getLabels } from '../../selectors/selectors';
import { getVMStatus } from '../../statuses/vm/vm';
import {
Expand All @@ -33,6 +44,7 @@ import {
VM_STATUS_OFF,
VM_STATUS_ERROR,
VM_STATUS_IMPORT_PENDING,
VM_STATUS_PAUSED,
} from '../../statuses/vm/constants';
import { VMKind, VMIKind } from '../../types';

Expand Down Expand Up @@ -249,7 +261,24 @@ export const VMStatus: React.FC<VMStatusProps> = ({
</ProgressStatus>
);
case VM_STATUS_RUNNING:
return <StatusIconAndText title="Running" icon={<SyncAltIcon />} />;
case VM_STATUS_PAUSED:
return (
<PopoverStatus title="Paused" icon={<PausedIcon />}>
<VMStatusPopoverContent message={PAUSED_VM_MODAL_MESSAGE}>
<Button
variant={ButtonVariant.primary}
onClick={() => {
// TODO Create function to unpause VM
}}
id="paused-popover-submit"
>
Unpause
</Button>
</VMStatusPopoverContent>
</PopoverStatus>
);
// case VM_STATUS_RUNNING:
// return <StatusIconAndText title="Running" icon={<SyncAltIcon />} />;
case VM_STATUS_OFF:
return <StatusIconAndText title="Off" icon={<OffIcon />} />;
default:
Expand Down
Expand Up @@ -9,7 +9,7 @@ import { isVMImporting, isVMRunning, isVMRunningWithVMI } from '../../selectors/
import { getMigrationVMIName, isMigrating, findVMIMigration } from '../../selectors/vmi-migration';
import { VirtualMachineInstanceMigrationModel } from '../../models';
import { VMMultiStatus } from '../../types';
import { restartVM, startVM, stopVM, VMActionType } from '../../k8s/requests/vm';
import { restartVM, startVM, stopVM, unpauseVM, VMActionType } from '../../k8s/requests/vm';
import { startVMIMigration } from '../../k8s/requests/vmi';
import { cancelMigration } from '../../k8s/requests/vmim';
import { cloneVMModal } from '../modals/clone-vm-modal';
Expand Down Expand Up @@ -85,6 +85,22 @@ const menuActionRestart = (
};
};

const menuActionUnpause = (kindObj: K8sKind, vm: VMKind): KebabOption => {
const title = 'Unpause Virtual Machine';
return {
hidden: !isVMRunning(vm), // TODO Write isVMPaused function and replace
label: title,
callback: () =>
confirmModal({
title,
message: getVMActionMessage(vm, VMActionType.Unpause),
btnText: _.capitalize(VMActionType.Unpause),
executeFn: () => unpauseVM(vm),
}),
accessReview: asAccessReview(kindObj, vm, 'patch'),
};
};

const menuActionMigrate = (
kindObj: K8sKind,
vm: VMKind,
Expand Down Expand Up @@ -156,6 +172,7 @@ export const vmMenuActions = [
menuActionStart,
menuActionStop,
menuActionRestart,
menuActionUnpause,
menuActionMigrate,
menuActionCancelMigration,
menuActionClone,
Expand Down
Expand Up @@ -9,8 +9,9 @@ import { getBasicID, prefixedID } from '../../utils';
import { vmDescriptionModal, vmFlavorModal } from '../modals';
import { VMCDRomModal } from '../modals/cdrom-vm-modal';
import { BootOrderModal } from '../modals/boot-order-modal/boot-order-modal';
import { VMStatusModal } from '../modals/vm-status-modal/vm-status-modal';
import { getDescription } from '../../selectors/selectors';
import { getCDRoms } from '../../selectors/vm/selectors';
import { getCDRoms, isVMRunning } from '../../selectors/vm/selectors';
import { getVMTemplateNamespacedName } from '../../selectors/vm-template/selectors';
import { getVMStatus } from '../../statuses/vm/vm';
import { getFlavorText } from '../flavor-text';
Expand All @@ -26,7 +27,6 @@ import {
getWorkloadProfile,
getDevices,
} from '../../selectors/vm';

import './vm-resource.scss';

export const VMDetailsItem: React.FC<VMDetailsItemProps> = ({
Expand Down Expand Up @@ -94,6 +94,7 @@ export const VMDetailsList: React.FC<VMResourceListProps> = ({
canUpdateVM,
}) => {
const [isBootOrderModalOpen, setBootOrderModalOpen] = React.useState<boolean>(false);
const [isStatusModalOpen, setStatusModalOpen] = React.useState<boolean>(false);

const id = getBasicID(vm);
const vmStatus = getVMStatus({ vm, vmi, pods, migrations });
Expand All @@ -107,7 +108,14 @@ export const VMDetailsList: React.FC<VMResourceListProps> = ({

return (
<dl className="co-m-pane__details">
<VMDetailsItem title="Status" idValue={prefixedID(id, 'vm-statuses')}>
<VMDetailsItem
title="Status"
canEdit={isVMRunning(vm)} // TODO Write isVMPaused function and replace
editButtonId={prefixedID(id, 'status-edit')}
onEditClick={() => setStatusModalOpen(true)}
idValue={prefixedID(id, 'vm-statuses')}
>
<VMStatusModal isOpen={isStatusModalOpen} setOpen={setStatusModalOpen} vmLikeEntity={vm} />
<VMStatuses vm={vm} vmi={vmi} pods={pods} migrations={migrations} />
</VMDetailsItem>

Expand Down
Expand Up @@ -42,3 +42,7 @@ export enum DeviceType {
}

export const VM_DETAIL_EVENTS_HREF = 'events';

export const PAUSED_VM_MODAL_MESSAGE = `This VM has been paused.
If you wish to unpause it, please click the Unpause button below.
For further details, please check with your system administrator.`;
Expand Up @@ -9,6 +9,7 @@ export enum VMActionType {
Start = 'start',
Stop = 'stop',
Restart = 'restart',
Unpause = 'unpause',
}

const VMActionRequest = async (vm: VMKind, action: VMActionType) => {
Expand Down Expand Up @@ -41,3 +42,4 @@ export const VMActionWithPXERequest = async (vm: VMKind, action: VMActionType) =
export const startVM = async (vm: VMKind) => VMActionWithPXERequest(vm, VMActionType.Start);
export const stopVM = async (vm: VMKind) => VMActionRequest(vm, VMActionType.Stop);
export const restartVM = async (vm: VMKind) => VMActionWithPXERequest(vm, VMActionType.Restart);
export const unpauseVM = async (vm: VMKind) => VMActionRequest(vm, VMActionType.Unpause);
Expand Up @@ -4,6 +4,7 @@ export const VM_STATUS_STARTING = 'VM_STATUS_STARTING';
export const VM_STATUS_VMI_WAITING = 'VM_STATUS_VMI_WAITING';
export const VM_STATUS_IMPORTING = 'VM_STATUS_IMPORTING';
export const VM_STATUS_STOPPING = 'VM_STATUS_STOPPING';
export const VM_STATUS_PAUSED = 'VM_STATUS_PAUSED';

export const VM_STATUS_V2V_CONVERSION_IN_PROGRESS = 'VM_STATUS_CONVERSION_IN_PROGRESS';
export const VM_STATUS_V2V_CONVERSION_PENDING = 'VM_STATUS_CONVERSION_PENDING';
Expand Down

0 comments on commit 65bc648

Please sign in to comment.