Skip to content

Commit

Permalink
CNV-33063: Add KSM to Cluster settings
Browse files Browse the repository at this point in the history
Add KSM (Kernel Samepage Merging) configuration to Cluster settings,
under "Resource management" expandable section.

Fixes https://issues.redhat.com/browse/CNV-33063
  • Loading branch information
Hilda Stastna committed Oct 12, 2023
1 parent 4c03b2d commit f009437
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 6 deletions.
4 changes: 4 additions & 0 deletions locales/en/plugin__kubevirt-plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -546,8 +546,10 @@
"IP addresses": "IP addresses",
"It may take several minutes until the clone is done and the VirtualMachine is ready.": "It may take several minutes until the clone is done and the VirtualMachine is ready.",
"It seems that your browser does not trust the certificate of the upload proxy. {uploadProxyURL && (\n <>\n Please{' '}\n <a href={`https://${uploadProxyURL}`} rel=\"noopener noreferrer\" target=\"_blank\">\n approve this certificate\n </a>{' '}\n and try again\n </>\n )}": "It seems that your browser does not trust the certificate of the upload proxy. {uploadProxyURL && (\n <>\n Please{' '}\n <a href={`https://${uploadProxyURL}`} rel=\"noopener noreferrer\" target=\"_blank\">\n approve this certificate\n </a>{' '}\n and try again\n </>\n )}",
"Kernel Samepage Merging (KSM)": "Kernel Samepage Merging (KSM)",
"key": "key",
"Key": "Key",
"KSM is a memory-saving de-duplication feature designed to fit more VirtualMachines into physical memory by sharing the data common between them.": "KSM is a memory-saving de-duplication feature designed to fit more VirtualMachines into physical memory by sharing the data common between them.",
"Kubernetes NMState Operator": "Kubernetes NMState Operator",
"KV data transfer rate": "KV data transfer rate",
"Label selectors let you select Nodes based on the value of one or more labels.": "Label selectors let you select Nodes based on the value of one or more labels.",
Expand Down Expand Up @@ -743,6 +745,7 @@
"Node labels": "Node labels",
"Node port": "Node port",
"Node selector": "Node selector",
"Node selector configuration": "Node selector configuration",
"Nodes": "Nodes",
"None": "None",
"Not available": "Not available",
Expand Down Expand Up @@ -873,6 +876,7 @@
"Reset": "Reset",
"Resource": "Resource",
"Resource already selected": "Resource already selected",
"Resource management": "Resource management",
"Resource name": "Resource name",
"Resources": "Resources",
"Resources are being removed, please wait.": "Resources are being removed, please wait.",
Expand Down
6 changes: 3 additions & 3 deletions src/utils/components/NodeSelectorModal/NodeSelectorModal.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as React from 'react';
import React, { FC, useMemo } from 'react';
import produce from 'immer';

import { NodeModel } from '@kubevirt-ui/kubevirt-api/console';
Expand Down Expand Up @@ -29,7 +29,7 @@ type NodeSelectorModalProps = {
vmi?: V1VirtualMachineInstance;
};

const NodeSelectorModal: React.FC<NodeSelectorModalProps> = ({
const NodeSelectorModal: FC<NodeSelectorModalProps> = ({
isOpen,
nodes,
nodesLoaded,
Expand All @@ -50,7 +50,7 @@ const NodeSelectorModal: React.FC<NodeSelectorModalProps> = ({

const onSelectorLabelAdd = () => onLabelAdd({ id: null, key: '', value: '' });

const updatedVirtualMachine = React.useMemo(() => {
const updatedVirtualMachine = useMemo(() => {
const updatedVM = produce<V1VirtualMachine>(vm, (vmDraft: V1VirtualMachine) => {
ensurePath(vmDraft, ['spec.template.template.spec.nodeSelector']);
if (!vmDraft.spec.template.spec.nodeSelector) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import EnableLoadBalancerSection from './components/EnableLoadBalancerSection/En
import EnablePreviewFeaturesSection from './components/EnablePreviewFeaturesSection/EnablePreviewFeaturesSection';
import GeneralInformation from './components/GeneralInformation/GeneralInformation';
import LiveMigrationSection from './components/LiveMigrationSection/LiveMigrationSection';
import ResourceManagementSection from './components/ResourceManagementSection/ResourceManagementSection';
import TemplatesProjectSection from './components/TemplatesProjectSection/TemplatesProjectSection';

const ClusterTab: FC = () => {
Expand All @@ -22,6 +23,8 @@ const ClusterTab: FC = () => {
<EnableLoadBalancerSection />
<Divider className="section-divider" />
<TemplatesProjectSection />
<Divider className="section-divider" />
<ResourceManagementSection />
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React, { FC } from 'react';

import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation';

import ExpandSection from '../../../ExpandSection/ExpandSection';

import KernelSamepageMerging from './components/KernelSamepageMerging/KernelSamepageMerging';

const ResourceManagementSection: FC = () => {
const { t } = useKubevirtTranslation();

return (
<ExpandSection toggleText={t('Resource management')}>
<KernelSamepageMerging />
</ExpandSection>
);
};

export default ResourceManagementSection;
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
.KernelSamepageMerging {
&__ExpandSection {
padding-left: var(--pf-global--spacer--lg);

.pf-c-expandable-section__content {
padding-left: var(--pf-global--spacer--lg);
}

.pf-c-expandable-section__toggle {
padding-right: var(--pf-global--spacer--sm);
}
}

&__HelpIcon,
.pf-c-switch {
vertical-align: -moz-middle-with-baseline !important;
}

&__HelpIcon {
color: var(--pf-global--Color--100);
}

&__HelpTextIcon {
.pf-c-popover__content {
width: 400px;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React, { FC, useState } from 'react';
import ExpandSection from 'src/views/clusteroverview/SettingsTab/ExpandSection/ExpandSection';

import HelpTextIcon from '@kubevirt-utils/components/HelpTextIcon/HelpTextIcon';
import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation';
import { PopoverPosition, Split, SplitItem, Switch } from '@patternfly/react-core';

import NodeSelectorConfiguration from './components/NodeSelectorConfiguration/NodeSelectorConfiguration';

import './KernelSamepageMerging.scss';

const KernelSamepageMerging: FC = () => {
const { t } = useKubevirtTranslation();
const [isEnabled, setIsEnabled] = useState(false);
// TODO enable KSM if isEnabled

return (
<Split className="KernelSamepageMerging">
<SplitItem>
<ExpandSection
className="KernelSamepageMerging__ExpandSection"
toggleContent={t('Kernel Samepage Merging (KSM)')}
>
<NodeSelectorConfiguration />
</ExpandSection>
</SplitItem>
<SplitItem isFilled>
<HelpTextIcon
bodyContent={t(
'KSM is a memory-saving de-duplication feature designed to fit more VirtualMachines into physical memory by sharing the data common between them.',
)}
className="KernelSamepageMerging__HelpTextIcon"
helpIconClassName="KernelSamepageMerging__HelpIcon"
position={PopoverPosition.right}
/>
</SplitItem>
<SplitItem>
<Switch id="kernel-samepage-merging" isChecked={isEnabled} onChange={setIsEnabled} />
</SplitItem>
</Split>
);
};

export default KernelSamepageMerging;
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React, { FC } from 'react';

import { useWizardVMContext } from '@catalog/utils/WizardVMContext';
import { modelToGroupVersionKind, NodeModel } from '@kubevirt-ui/kubevirt-api/console';
import { IoK8sApiCoreV1Node } from '@kubevirt-ui/kubevirt-api/kubernetes';
import { useModal } from '@kubevirt-utils/components/ModalProvider/ModalProvider';
import NodeSelectorModal from '@kubevirt-utils/components/NodeSelectorModal/NodeSelectorModal';
import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation';
import { useK8sWatchResource } from '@openshift-console/dynamic-plugin-sdk';
import { Button, ButtonVariant } from '@patternfly/react-core';
import { PencilAltIcon } from '@patternfly/react-icons';

const NodeSelectorConfiguration: FC = () => {
const { createModal } = useModal();
const { t } = useKubevirtTranslation();
const { updateVM } = useWizardVMContext();

const [nodes, nodesLoaded] = useK8sWatchResource<IoK8sApiCoreV1Node[]>({
groupVersionKind: modelToGroupVersionKind(NodeModel),
isList: true,
});

const onNodeConfigure = () =>
createModal(({ isOpen, onClose }) => (
<NodeSelectorModal
isOpen={isOpen}
nodes={nodes}
nodesLoaded={nodesLoaded}
onClose={onClose}
onSubmit={updateVM}
vm={undefined} // TODO!!!
/>
));

return (
<Button
className="NodeSelectorConfiguration__Button"
isInline
onClick={onNodeConfigure}
variant={ButtonVariant.link}
>
{t('Node selector configuration')}
<PencilAltIcon alt={t('Edit')} className="co-icon-space-l pf-c-button-icon--plain" />
</Button>
);
};

export default NodeSelectorConfiguration;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { FC } from 'react';
import { TemplateSchedulingGridProps } from 'src/views/templates/details/tabs/scheduling/components/TemplateSchedulingLeftGrid';
import { getNodeSelector } from 'src/views/templates/utils/selectors';

Expand All @@ -7,6 +7,7 @@ import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTransla
import { isEmpty } from '@kubevirt-utils/utils/utils';
import {
Button,
ButtonVariant,
DescriptionListDescription,
DescriptionListGroup,
DescriptionListTerm,
Expand All @@ -17,7 +18,7 @@ import { PencilAltIcon } from '@patternfly/react-icons';

import NodeSelectorModal from './NodeSelectorModal';

const NodeSelector: React.FC<TemplateSchedulingGridProps> = ({ editable, onSubmit, template }) => {
const NodeSelector: FC<TemplateSchedulingGridProps> = ({ editable, onSubmit, template }) => {
const { t } = useKubevirtTranslation();
const { createModal } = useModal();
const nodeSelector = getNodeSelector(template);
Expand Down Expand Up @@ -51,7 +52,7 @@ const NodeSelector: React.FC<TemplateSchedulingGridProps> = ({ editable, onSubmi
isInline
onClick={onEditClick}
type="button"
variant="link"
variant={ButtonVariant.link}
>
{nodeSelectorLabels}
<PencilAltIcon className="co-icon-space-l pf-c-button-icon--plain" />
Expand Down

0 comments on commit f009437

Please sign in to comment.