Skip to content

Commit

Permalink
Merge pull request #2084 from metalice/CNV-37371-add-change-bootable-…
Browse files Browse the repository at this point in the history
…volume-namespace

CNV-37371: New setting for change bootable volumes default ns
  • Loading branch information
openshift-merge-bot[bot] authored Jul 17, 2024
2 parents d5e7d3d + 4cb7bcb commit 8143df2
Show file tree
Hide file tree
Showing 12 changed files with 295 additions and 108 deletions.
2 changes: 2 additions & 0 deletions locales/en/plugin__kubevirt-plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@
"bootable": "bootable",
"Bootable volume: {{bootableVolumeName}}": "Bootable volume: {{bootableVolumeName}}",
"Bootable volumes": "Bootable volumes",
"Bootable volumes project": "Bootable volumes project",
"Breakdown by network": "Breakdown by network",
"Bridge": "Bridge",
"Build with guided documentation": "Build with guided documentation",
Expand Down Expand Up @@ -1037,6 +1038,7 @@
"See the <2>catalog tab</2> to quickly create a VirtualMachine from the available Templates.": "See the <2>catalog tab</2> to quickly create a VirtualMachine from the available Templates.",
"Select": "Select",
"Select {{label}}": "Select {{label}}",
"Select a project for Red Hat bootable volumes. The default project is 'openshift-virtualization-os-images'": "Select a project for Red Hat bootable volumes. The default project is 'openshift-virtualization-os-images'",
"Select a project for Red Hat templates. The default project is 'openshift'. If you want to store Red Hat templates in multiple projects, you must clone<br/>the Red Hat template by selecting <3>Clone template</3> from the template action menu and then selecting another project for the cloned template.": "Select a project for Red Hat templates. The default project is 'openshift'. If you want to store Red Hat templates in multiple projects, you must clone<br/>the Red Hat template by selecting <3>Clone template</3> from the template action menu and then selecting another project for the cloned template.",
"Select a project in order to see user-provided InstanceTypes": "Select a project in order to see user-provided InstanceTypes",
"Select a resource": "Select a resource",
Expand Down
1 change: 0 additions & 1 deletion src/utils/components/FilterSelect/InlineFilterSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ const InlineFilterSelect: FC<InlineFilterSelectProps> = ({

const onSelect = (_event: React.MouseEvent<Element, MouseEvent> | undefined, value: string) => {
if (value && value !== NO_RESULTS) {
setSelected(value);
setFilterValue('');
}
setIsOpen(false);
Expand Down
1 change: 1 addition & 0 deletions src/utils/hooks/useHyperConvergeConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { K8sResourceCommon, useK8sWatchResource } from '@openshift-console/dynam

export type HyperConverged = K8sResourceCommon & {
spec: {
commonBootImageNamespace?: string;
commonTemplatesNamespace?: string;
dataImportCronTemplates: K8sResourceCommon[];
evictionStrategy?: string;
Expand Down
2 changes: 1 addition & 1 deletion src/utils/resources/vm/hooks/useProvisioningPercentage.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { DataVolumeModelGroupVersionKind } from '@kubevirt-ui/kubevirt-api/console';
import type { V1beta1DataVolume } from '@kubevirt-ui/kubevirt-api/containerized-data-importer/models';
import { V1beta1DataVolume } from '@kubevirt-ui/kubevirt-api/containerized-data-importer/models';
import { V1VirtualMachine } from '@kubevirt-ui/kubevirt-api/kubevirt';
import { getNamespace, getVMStatus } from '@kubevirt-utils/resources/shared';
import { getVolumes } from '@kubevirt-utils/resources/vm';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React, { FC } from 'react';

import { OPENSHIFT_OS_IMAGES_NS } from '@kubevirt-utils/constants/constants';
import { HyperConverged } from '@kubevirt-utils/hooks/useHyperConvergeConfiguration';
import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation';
import { K8sResourceCommon } from '@openshift-console/dynamic-plugin-sdk';

import GeneralSettingsProject from '../shared/GeneralSettingsProject';

import {
getCurrentBootableVolumesNamespaceFromHCO,
updateHCOBootableVolumesNamespace,
} from './utils/utils';

import '../shared/general-settings.scss';

type BootableVolumeProjectSectionProps = {
hyperConvergeConfiguration: [hyperConvergeConfig: HyperConverged, loaded: boolean, error: any];
projectsData: [projects: K8sResourceCommon[], loaded: boolean, error: any];
};

const BootableVolumeProjectSection: FC<BootableVolumeProjectSectionProps> = ({
hyperConvergeConfiguration,
projectsData,
}) => {
const { t } = useKubevirtTranslation();

return (
<GeneralSettingsProject
description={t(
"Select a project for Red Hat bootable volumes. The default project is 'openshift-virtualization-os-images'",
)}
hcoResourceNamespace={getCurrentBootableVolumesNamespaceFromHCO(
hyperConvergeConfiguration?.[0],
)}
hyperConvergeConfiguration={hyperConvergeConfiguration}
namespace={OPENSHIFT_OS_IMAGES_NS}
onChange={updateHCOBootableVolumesNamespace}
projectsData={projectsData}
toggleText={t('Bootable volumes project')}
/>
);
};

export default BootableVolumeProjectSection;
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import HyperConvergedModel from '@kubevirt-ui/kubevirt-api/console/models/HyperConvergedModel';
import { OPENSHIFT_OS_IMAGES_NS } from '@kubevirt-utils/constants/constants';
import { HyperConverged } from '@kubevirt-utils/hooks/useHyperConvergeConfiguration';
import { k8sPatch } from '@openshift-console/dynamic-plugin-sdk';

export const getCurrentBootableVolumesNamespaceFromHCO = (hyperConverged: HyperConverged): string =>
hyperConverged?.spec?.commonBootImageNamespace || OPENSHIFT_OS_IMAGES_NS;

export const updateHCOBootableVolumesNamespace = async (
hyperConverged: HyperConverged,
newNamespace: null | number | string,
handelError: (value: string) => void,
handleLoading: (value: boolean) => void,
) => {
const currentTemplatesNamespace = getCurrentBootableVolumesNamespaceFromHCO(hyperConverged);
if (newNamespace !== currentTemplatesNamespace) {
handleLoading(true);
try {
await k8sPatch<HyperConverged>({
data: [
{
op: 'replace',
path: `/spec/commonBootImageNamespace`,
value: newNamespace === OPENSHIFT_OS_IMAGES_NS ? null : newNamespace,
},
],
model: HyperConvergedModel,
resource: hyperConverged,
});
} catch (error) {
handelError(error?.message || error);
} finally {
handleLoading(false);
}
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ import React, { FC } from 'react';

import { HyperConverged } from '@kubevirt-utils/hooks/useHyperConvergeConfiguration';
import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation';
import { modelToGroupVersionKind, ProjectModel } from '@kubevirt-utils/models';
import { K8sResourceCommon, useK8sWatchResource } from '@openshift-console/dynamic-plugin-sdk';
import { Stack, StackItem } from '@patternfly/react-core';

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

import AutomaticImagesDownload from './AutomaticImagesDownload/AutomaticImagesDownload';
import BootableVolumeProjectSection from './BootableVolumeProjectSection/BootableVolumeProjectSection';
import LiveMigrationSection from './LiveMigrationSection/LiveMigrationSection';
import MemoryDensity from './MemoryDensity/MemoryDensity';
import SSHConfiguration from './SSHConfiguration/SSHConfiguration';
Expand All @@ -19,6 +22,10 @@ type GeneralSettingsProps = {

const GeneralSettings: FC<GeneralSettingsProps> = ({ hyperConvergeConfiguration, newBadge }) => {
const { t } = useKubevirtTranslation();
const projectsData = useK8sWatchResource<K8sResourceCommon[]>({
groupVersionKind: modelToGroupVersionKind(ProjectModel),
isList: true,
});

return (
<ExpandSection toggleText={t('General settings')}>
Expand All @@ -30,7 +37,16 @@ const GeneralSettings: FC<GeneralSettingsProps> = ({ hyperConvergeConfiguration,
<SSHConfiguration newBadge={newBadge} />
</StackItem>
<StackItem isFilled>
<TemplatesProjectSection hyperConvergeConfiguration={hyperConvergeConfiguration} />
<TemplatesProjectSection
hyperConvergeConfiguration={hyperConvergeConfiguration}
projectsData={projectsData}
/>
</StackItem>
<StackItem isFilled>
<BootableVolumeProjectSection
hyperConvergeConfiguration={hyperConvergeConfiguration}
projectsData={projectsData}
/>
</StackItem>
<StackItem isFilled>
<MemoryDensity
Expand Down
Original file line number Diff line number Diff line change
@@ -1,137 +1,49 @@
import React, { FC, useEffect, useState } from 'react';
import React, { FC } from 'react';
import { Trans } from 'react-i18next';

import { modelToGroupVersionKind, ProjectModel } from '@kubevirt-ui/kubevirt-api/console';
import CreateProjectModal from '@kubevirt-utils/components/CreateProjectModal/CreateProjectModal';
import InlineFilterSelect from '@kubevirt-utils/components/FilterSelect/InlineFilterSelect';
import { useModal } from '@kubevirt-utils/components/ModalProvider/ModalProvider';
import { HyperConverged } from '@kubevirt-utils/hooks/useHyperConvergeConfiguration';
import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation';
import { getName } from '@kubevirt-utils/resources/shared';
import { kubevirtConsole } from '@kubevirt-utils/utils/utils';
import { K8sResourceCommon, useK8sWatchResource } from '@openshift-console/dynamic-plugin-sdk';
import {
Alert,
AlertVariant,
Button,
ButtonVariant,
MenuFooter,
Skeleton,
Spinner,
Text,
TextVariants,
} from '@patternfly/react-core';
import { K8sResourceCommon } from '@openshift-console/dynamic-plugin-sdk';

import ExpandSection from '../../../../ExpandSection/ExpandSection';
import GeneralSettingsProject from '../shared/GeneralSettingsProject';

import {
getCurrentTemplatesNamespaceFromHCO,
OPENSHIFT,
updateHCOCommonTemplatesNamespace,
} from './utils/utils';

import './templates-project-section.scss';
import '../shared/general-settings.scss';

type TemplatesProjectSectionProps = {
hyperConvergeConfiguration: [hyperConvergeConfig: HyperConverged, loaded: boolean, error: any];
projectsData: [projects: K8sResourceCommon[], loaded: boolean, error: any];
};

const TemplatesProjectSection: FC<TemplatesProjectSectionProps> = ({
hyperConvergeConfiguration,
projectsData,
}) => {
const { t } = useKubevirtTranslation();
const [loading, setLoading] = useState<boolean>(false);
const [selectedProject, setSelectedProject] = useState<string>();
const [error, setError] = useState<string>();
const { createModal } = useModal();

const [projects, projectsLoaded, projectsLoadingError] = useK8sWatchResource<K8sResourceCommon[]>(
{
groupVersionKind: modelToGroupVersionKind(ProjectModel),
isList: true,
},
);

const [hyperConverge, hyperLoaded] = hyperConvergeConfiguration;

useEffect(() => {
if (hyperConverge) {
const currentNamespaceHCO = getCurrentTemplatesNamespaceFromHCO(hyperConverge);
!selectedProject && setSelectedProject(currentNamespaceHCO ?? OPENSHIFT);
}
}, [hyperConverge, selectedProject]);

const onSelect = (value: string) => {
setSelectedProject(value);
updateHCOCommonTemplatesNamespace(hyperConverge, value, setError, setLoading).catch((e) =>
kubevirtConsole.log(e),
);
};

return (
<ExpandSection className="templates-project-tab__main" toggleText={t('Template project')}>
<Text className="templates-project-tab__main--help" component={TextVariants.small}>
<GeneralSettingsProject
description={
<Trans ns="plugin__kubevirt-plugin" t={t}>
Select a project for Red Hat templates. The default project is &apos;openshift&apos;. If
you want to store Red Hat templates in multiple projects, you must clone
<br />
the Red Hat template by selecting <b>Clone template</b> from the template action menu and
then selecting another project for the cloned template.
</Trans>
</Text>
<Text className="templates-project-tab__main--field-title" component={TextVariants.h6}>
{t('Project')}
</Text>
{projectsLoaded && hyperLoaded ? (
<InlineFilterSelect
menuFooter={
<MenuFooter>
<Button
onClick={() =>
createModal((props) => (
<CreateProjectModal
{...props}
createdProject={(value) =>
value?.metadata?.name && setSelectedProject(value?.metadata?.name)
}
/>
))
}
key="create-project"
variant={ButtonVariant.secondary}
>
{t('Create project')}
</Button>
</MenuFooter>
}
options={[
...projects?.map((proj) => ({
groupVersionKind: modelToGroupVersionKind(ProjectModel),
value: getName(proj),
})),
]}
toggleProps={{
icon: loading && <Spinner size="sm" />,
isDisabled: loading,
placeholder: t('Select project'),
}}
selected={selectedProject}
setSelected={onSelect}
/>
) : (
<Skeleton width={'300px'} />
)}
{(error || projectsLoadingError) && (
<Alert
className="templates-project-tab__main--error"
isInline
title={t('Error')}
variant={AlertVariant.danger}
>
{error || projectsLoadingError}
</Alert>
)}
</ExpandSection>
}
hcoResourceNamespace={getCurrentTemplatesNamespaceFromHCO(hyperConvergeConfiguration?.[0])}
hyperConvergeConfiguration={hyperConvergeConfiguration}
namespace={OPENSHIFT}
onChange={updateHCOCommonTemplatesNamespace}
projectsData={projectsData}
toggleText={t('Template project')}
/>
);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React, { FC } from 'react';

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

type GeneralSettingsErrorProps = {
error: string;
loading: string;
};

const GeneralSettingsError: FC<GeneralSettingsErrorProps> = ({ error, loading }) => {
const { t } = useKubevirtTranslation();

return (
(error || loading) && (
<Alert
className="project-tab__main--error"
isInline
title={t('Error')}
variant={AlertVariant.danger}
>
{error || loading}
</Alert>
)
);
};

export default GeneralSettingsError;
Loading

0 comments on commit 8143df2

Please sign in to comment.