-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1205 from yaacov/add-rootDisk
🐾 Add a plan details item to edit boot disk
- Loading branch information
Showing
10 changed files
with
353 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 79 additions & 0 deletions
79
...modules/Plans/views/details/components/SettingsSection/components/RootDiskDetailsItem.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import React from 'react'; | ||
import { useModal } from 'src/modules/Providers/modals'; | ||
import { DetailsItem } from 'src/modules/Providers/utils'; | ||
import { useForkliftTranslation } from 'src/utils/i18n'; | ||
|
||
import { Label, Tooltip } from '@patternfly/react-core'; | ||
import { ExclamationTriangleIcon } from '@patternfly/react-icons'; | ||
|
||
import { PlanDetailsItemProps } from '../../DetailsSection'; | ||
import { VIRT_V2V_HELP_LINK } from '../modals'; | ||
import { getRootDiskLabelByKey } from '../modals/EditRootDisk'; | ||
import { EditRootDisk } from '../modals/EditRootDisk/EditRootDisk'; | ||
|
||
export const RootDiskDetailsItem: React.FC<PlanDetailsItemProps> = ({ | ||
resource, | ||
canPatch, | ||
helpContent, | ||
}) => { | ||
const { t } = useForkliftTranslation(); | ||
const { showModal } = useModal(); | ||
|
||
const defaultHelpContent = t(`Choose the root filesystem to be converted.`); | ||
|
||
const rootDisk = resource?.spec?.vms?.[0].rootDisk; | ||
|
||
return ( | ||
<DetailsItem | ||
title={t('Root device')} | ||
content={getDiskLabel(rootDisk)} | ||
helpContent={helpContent ?? defaultHelpContent} | ||
moreInfoLink={VIRT_V2V_HELP_LINK} | ||
crumbs={['spec', 'vms', 'rootDisk']} | ||
onEdit={canPatch && (() => showModal(<EditRootDisk resource={resource} />))} | ||
/> | ||
); | ||
}; | ||
|
||
/** | ||
* Generates a label component for the given disk key. | ||
* @param {string} diskKey - The key representing the disk option. | ||
* @returns {JSX.Element} The label component for the disk. | ||
*/ | ||
const getDiskLabel = (diskKey: string) => { | ||
const diskLabel = getRootDiskLabelByKey(diskKey); | ||
|
||
// First boot disk, color green | ||
if (!diskKey) { | ||
return ( | ||
<Label isCompact color={'green'}> | ||
{diskLabel} | ||
</Label> | ||
); | ||
} | ||
|
||
// Known boot disk format, color grey. | ||
if (diskKey.startsWith('/dev/sd')) { | ||
return ( | ||
<Label isCompact color={'grey'}> | ||
{diskLabel} | ||
</Label> | ||
); | ||
} | ||
|
||
// Unknown boot disk format. | ||
return ( | ||
<Tooltip | ||
content={ | ||
'Root filesystem format should start with "/dev/sd[X]", see documentation for more information.' | ||
} | ||
> | ||
<Label isCompact color={'orange'}> | ||
<span className="forklift-page-plan-settings-icon"> | ||
<ExclamationTriangleIcon color="orange" /> | ||
</span> | ||
{diskLabel} | ||
</Label> | ||
</Tooltip> | ||
); | ||
}; |
1 change: 1 addition & 0 deletions
1
...ole-plugin/src/modules/Plans/views/details/components/SettingsSection/components/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
117 changes: 117 additions & 0 deletions
117
...dules/Plans/views/details/components/SettingsSection/modals/EditRootDisk/EditRootDisk.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
import React from 'react'; | ||
import { FilterableSelect } from 'src/components/FilterableSelect/FilterableSelect'; | ||
import { | ||
EditModal, | ||
EditModalProps, | ||
ModalInputComponentType, | ||
OnConfirmHookType, | ||
} from 'src/modules/Providers/modals'; | ||
import { useForkliftTranslation } from 'src/utils/i18n'; | ||
|
||
import { Modify, PlanModel, V1beta1Plan } from '@kubev2v/types'; | ||
import { K8sModel, k8sPatch } from '@openshift-console/dynamic-plugin-sdk'; | ||
import { HelperText, HelperTextItem, Text } from '@patternfly/react-core'; | ||
|
||
import { editRootDiskModalAlert } from './editRootDiskModalAlert'; | ||
import { editRootDiskModalBody } from './editRootDiskModalBody'; | ||
import { diskOptions, getRootDiskLabelByKey } from './getRootDiskLabelByKey'; | ||
|
||
const onConfirm: OnConfirmHookType = async ({ resource, model, newValue }) => { | ||
const plan = resource as V1beta1Plan; | ||
|
||
const resourceValue = plan?.spec?.vms; | ||
const op = resourceValue ? 'replace' : 'add'; | ||
const newVMs = resourceValue.map((vm) => ({ | ||
...vm, | ||
rootDisk: newValue || undefined, | ||
})); | ||
|
||
const obj = await k8sPatch({ | ||
model: model, | ||
resource: resource, | ||
data: [ | ||
{ | ||
op, | ||
path: '/spec/vms', | ||
value: newVMs || undefined, | ||
}, | ||
], | ||
}); | ||
|
||
return obj; | ||
}; | ||
|
||
interface DropdownRendererProps { | ||
value: string | number; | ||
onChange: (string) => void; | ||
} | ||
|
||
const RootDiskInputFactory: () => ModalInputComponentType = () => { | ||
const DropdownRenderer: React.FC<DropdownRendererProps> = ({ value, onChange }) => { | ||
const { t } = useForkliftTranslation(); | ||
const options = diskOptions(t); | ||
|
||
const dropdownItems = options.map((option) => ({ | ||
itemId: option.key, | ||
children: ( | ||
<> | ||
<Text>{getRootDiskLabelByKey(option.key)}</Text> | ||
{option.description && ( | ||
<HelperText> | ||
<HelperTextItem variant="indeterminate">{option.description}</HelperTextItem> | ||
</HelperText> | ||
)} | ||
</> | ||
), | ||
})); | ||
|
||
return ( | ||
<FilterableSelect | ||
selectOptions={dropdownItems} | ||
value={value as string} | ||
onSelect={onChange} | ||
canCreate | ||
placeholder={t('First root device')} | ||
></FilterableSelect> | ||
); | ||
}; | ||
|
||
return DropdownRenderer; | ||
}; | ||
|
||
export const EditRootDisk: React.FC<EditRootDiskProps> = (props) => { | ||
const { t } = useForkliftTranslation(); | ||
|
||
const plan = props.resource; | ||
const rootDisk = plan.spec.vms?.[0]?.rootDisk; | ||
const allVMsHasMatchingRootDisk = plan.spec.vms.every((vm) => vm?.rootDisk === rootDisk); | ||
|
||
return ( | ||
<EditModal | ||
{...props} | ||
jsonPath={(obj: V1beta1Plan) => obj?.spec?.vms?.[0]?.rootDisk} | ||
title={props?.title || t('Edit root device')} | ||
label={props?.label || t('Root device')} | ||
model={PlanModel} | ||
onConfirmHook={onConfirm} | ||
body={ | ||
<> | ||
{editRootDiskModalBody} | ||
{!allVMsHasMatchingRootDisk && editRootDiskModalAlert} | ||
</> | ||
} | ||
InputComponent={RootDiskInputFactory()} | ||
/> | ||
); | ||
}; | ||
|
||
export type EditRootDiskProps = Modify< | ||
EditModalProps, | ||
{ | ||
resource: V1beta1Plan; | ||
title?: string; | ||
label?: string; | ||
model?: K8sModel; | ||
jsonPath?: string | string[]; | ||
} | ||
>; |
15 changes: 15 additions & 0 deletions
15
...s/views/details/components/SettingsSection/modals/EditRootDisk/editRootDiskModalAlert.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import React from 'react'; | ||
import { AlertMessageForModals } from 'src/modules/Providers/modals'; | ||
|
||
export const editRootDiskModalAlert = ( | ||
<AlertMessageForModals | ||
variant="warning" | ||
title={'The plan rootDisk keys was manually configured'} | ||
message={ | ||
<> | ||
<p>Warning: not all virtual machines are configures using the same root disk number,</p> | ||
<p>updating the root disk number will override the current configuration.</p> | ||
</> | ||
} | ||
/> | ||
); |
30 changes: 30 additions & 0 deletions
30
...ns/views/details/components/SettingsSection/modals/EditRootDisk/editRootDiskModalBody.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import React from 'react'; | ||
import { ForkliftTrans } from 'src/utils'; | ||
|
||
import { ExternalLink } from '@kubev2v/common'; | ||
|
||
import { VIRT_V2V_HELP_LINK } from '../EditLUKSEncryptionPasswords'; | ||
|
||
export const editRootDiskModalBody = ( | ||
<> | ||
<ForkliftTrans> | ||
<p>Choose the root filesystem to be converted.</p> | ||
<br /> | ||
<p> | ||
Default behavior is to choose the first root device in the case of a multi-boot operating | ||
system. Since this is a heuristic, it may sometimes choose the wrong one. | ||
</p> | ||
<br /> | ||
<p> | ||
When using a multi-boot VM, you can also name a specific root device, eg.{' '} | ||
<strong>/dev/sda2</strong> would mean to use the second partition on the first hard drive. | ||
If the named root device does not exist or was not detected as a root device, the migration | ||
will fail.{' '} | ||
<ExternalLink isInline href={VIRT_V2V_HELP_LINK}> | ||
Learn more | ||
</ExternalLink> | ||
. | ||
</p> | ||
</ForkliftTrans> | ||
</> | ||
); |
Oops, something went wrong.