From 4eb98176c2212297cc2862c685f9400801ed2348 Mon Sep 17 00:00:00 2001 From: Sven Thoms <21118431+shalberd@users.noreply.github.com> Date: Sun, 3 Sep 2023 21:11:35 +0200 Subject: [PATCH 1/9] StorageClassKind array of cluster storage classes. get logic in App / AppContext and additional property. Storage classes info only gets loaded anew on app starts or hard browser page refresh. Custom hook usePreferredStorageClass for decision logic. StorageClassKind array of cluster storage classes. get logic in App / AppContext and additional property. Storage classes info only gets loaded anew on app starts or hard browser page refresh. Custom hook usePreferredStorageClass for decision logic. --- frontend/src/api/index.ts | 1 + frontend/src/api/k8s/pvcs.ts | 2 + frontend/src/api/k8s/storageClasses.ts | 8 ++++ frontend/src/api/models/k8s.ts | 7 +++ frontend/src/app/App.tsx | 5 ++- frontend/src/app/AppContext.ts | 3 ++ .../src/concepts/k8s/useStorageClasses.ts | 6 +++ frontend/src/k8sTypes.ts | 21 +++++++++ .../screens/spawner/SpawnerFooter.tsx | 9 +++- .../pages/projects/screens/spawner/service.ts | 3 +- .../storage/usePreferredStorageClass.ts | 45 +++++++++++++++++++ frontend/src/types.ts | 1 + 12 files changed, 108 insertions(+), 3 deletions(-) create mode 100644 frontend/src/api/k8s/storageClasses.ts create mode 100644 frontend/src/concepts/k8s/useStorageClasses.ts create mode 100644 frontend/src/pages/projects/screens/spawner/storage/usePreferredStorageClass.ts diff --git a/frontend/src/api/index.ts b/frontend/src/api/index.ts index 89261907fa..83ba6b1577 100644 --- a/frontend/src/api/index.ts +++ b/frontend/src/api/index.ts @@ -13,6 +13,7 @@ export * from './k8s/routes'; export * from './k8s/secrets'; export * from './k8s/serviceAccounts'; export * from './k8s/servingRuntimes'; +export * from './k8s/storageClasses'; export * from './k8s/users'; export * from './k8s/groups'; export * from './k8s/templates'; diff --git a/frontend/src/api/k8s/pvcs.ts b/frontend/src/api/k8s/pvcs.ts index 9fe9a16f96..a814f429c8 100644 --- a/frontend/src/api/k8s/pvcs.ts +++ b/frontend/src/api/k8s/pvcs.ts @@ -15,6 +15,7 @@ export const assemblePvc = ( projectName: string, description: string, pvcSize: number, + storageClassName?: string, ): PersistentVolumeClaimKind => ({ apiVersion: 'v1', kind: 'PersistentVolumeClaim', @@ -36,6 +37,7 @@ export const assemblePvc = ( storage: `${pvcSize}Gi`, }, }, + storageClassName: storageClassName, volumeMode: 'Filesystem', }, status: { diff --git a/frontend/src/api/k8s/storageClasses.ts b/frontend/src/api/k8s/storageClasses.ts new file mode 100644 index 0000000000..fdf6893783 --- /dev/null +++ b/frontend/src/api/k8s/storageClasses.ts @@ -0,0 +1,8 @@ +import { k8sListResource } from '@openshift/dynamic-plugin-sdk-utils'; +import { StorageClassKind } from '~/k8sTypes'; +import { StorageClassModel } from '~/api/models'; +export const getStorageClasses = (): Promise => + k8sListResource({ + model: StorageClassModel, + queryOptions: {}, + }).then((listResource) => listResource.items); diff --git a/frontend/src/api/models/k8s.ts b/frontend/src/api/models/k8s.ts index 7da19cbcf0..23faeca480 100644 --- a/frontend/src/api/models/k8s.ts +++ b/frontend/src/api/models/k8s.ts @@ -24,6 +24,13 @@ export const PVCModel: K8sModelCommon = { plural: 'persistentvolumeclaims', }; +export const StorageClassModel: K8sModelCommon = { + apiVersion: 'v1', + apiGroup: 'storage.k8s.io', + kind: 'StorageClass', + plural: 'storageclasses', +}; + export const NamespaceModel: K8sModelCommon = { apiVersion: 'v1', kind: 'Namespace', diff --git a/frontend/src/app/App.tsx b/frontend/src/app/App.tsx index 89da2dde65..90d7d28411 100644 --- a/frontend/src/app/App.tsx +++ b/frontend/src/app/App.tsx @@ -18,6 +18,7 @@ import { useUser } from '~/redux/selectors'; import { DASHBOARD_MAIN_CONTAINER_SELECTOR } from '~/utilities/const'; import useDetectUser from '~/utilities/useDetectUser'; import ProjectsContextProvider from '~/concepts/projects/ProjectsContext'; +import useStorageClasses from '~/concepts/k8s/useStorageClasses'; import Header from './Header'; import AppRoutes from './AppRoutes'; import NavSidebar from './NavSidebar'; @@ -40,6 +41,8 @@ const App: React.FC = () => { loadError: fetchConfigError, } = useApplicationSettings(); + const [storageClasses] = useStorageClasses(); + useDetectUser(); if (!username || !configLoaded || !dashboardConfig) { @@ -72,7 +75,6 @@ const App: React.FC = () => { ); } - // Assume we are still waiting on the API to finish return ( @@ -86,6 +88,7 @@ const App: React.FC = () => { value={{ buildStatuses, dashboardConfig, + storageClasses, }} > useFetchState(getStorageClasses, []); + +export default useStorageClasses; diff --git a/frontend/src/k8sTypes.ts b/frontend/src/k8sTypes.ts index 3b4f16524e..2ee67505e4 100644 --- a/frontend/src/k8sTypes.ts +++ b/frontend/src/k8sTypes.ts @@ -41,6 +41,14 @@ type DisplayNameAnnotations = Partial<{ 'openshift.io/display-name': string; // the name provided by the user }>; +type StorageClassAnnotations = Partial<{ + // if true, enables any persistent volume claim (PVC) that does not specify a specific storage class to automatically be provisioned. + // Only one, if any, StorageClass per cluster can be set as default. + 'storageclass.kubernetes.io/is-default-class': 'true' | 'false'; + // the description provided by the cluster admin or Container Storage Interface (CSI) provider + 'kubernetes.io/description': string; +}>; + export type K8sDSGResource = K8sResourceCommon & { metadata: { annotations?: DisplayNameAnnotations; @@ -250,6 +258,18 @@ export type PersistentVolumeClaimKind = K8sResourceCommon & { } & Record; }; +export type StorageClassKind = K8sResourceCommon & { + metadata: { + annotations?: StorageClassAnnotations; + name: string; + }; + provisioner: string; + parameters?: string; + reclaimPolicy: string; + volumeBindingMode: string; + allowVolumeExpansion?: boolean; +}; + export type NotebookKind = K8sResourceCommon & { metadata: { annotations: DisplayNameAnnotations & NotebookAnnotations; @@ -721,6 +741,7 @@ export type DashboardConfigKind = K8sResourceCommon & { notebookController?: { enabled: boolean; pvcSize?: string; + storageClassName?: string; notebookNamespace?: string; gpuSetting?: GpuSettingString; notebookTolerationSettings?: TolerationSettings; diff --git a/frontend/src/pages/projects/screens/spawner/SpawnerFooter.tsx b/frontend/src/pages/projects/screens/spawner/SpawnerFooter.tsx index fbf05a466d..aab054936c 100644 --- a/frontend/src/pages/projects/screens/spawner/SpawnerFooter.tsx +++ b/frontend/src/pages/projects/screens/spawner/SpawnerFooter.tsx @@ -19,6 +19,7 @@ import { useUser } from '~/redux/selectors'; import { ProjectDetailsContext } from '~/pages/projects/ProjectDetailsContext'; import { AppContext } from '~/app/AppContext'; import { fireTrackingEvent } from '~/utilities/segmentIOUtils'; +import usePreferredStorageClass from '~/pages/projects/screens/spawner/storage/usePreferredStorageClass'; import { createPvcDataForNotebook, createConfigMapsAndSecretsForNotebook, @@ -44,12 +45,14 @@ const SpawnerFooter: React.FC = ({ canEnablePipelines, }) => { const [errorMessage, setErrorMessage] = React.useState(''); + const { dashboardConfig: { spec: { notebookController }, }, } = React.useContext(AppContext); const tolerationSettings = notebookController?.notebookTolerationSettings; + const storageClass = usePreferredStorageClass(); const { notebooks: { data }, dataConnections: { data: existingDataConnections }, @@ -187,7 +190,11 @@ const SpawnerFooter: React.FC = ({ ? [dataConnection.existing] : []; - const pvcDetails = await createPvcDataForNotebook(projectName, storageData).catch(handleError); + const pvcDetails = await createPvcDataForNotebook( + projectName, + storageData, + storageClass?.metadata.name, + ).catch(handleError); const envFrom = await createConfigMapsAndSecretsForNotebook(projectName, [ ...envVariables, ...newDataConnection, diff --git a/frontend/src/pages/projects/screens/spawner/service.ts b/frontend/src/pages/projects/screens/spawner/service.ts index cd3fa8a273..bcbcc9673c 100644 --- a/frontend/src/pages/projects/screens/spawner/service.ts +++ b/frontend/src/pages/projects/screens/spawner/service.ts @@ -30,6 +30,7 @@ import { fetchNotebookEnvVariables } from './environmentVariables/useNotebookEnv export const createPvcDataForNotebook = async ( projectName: string, storageData: StorageData, + storageClassName?: string, ): Promise<{ volumes: Volume[]; volumeMounts: VolumeMount[] }> => { const { storageType, @@ -42,7 +43,7 @@ export const createPvcDataForNotebook = async ( const { volumes, volumeMounts } = getVolumesByStorageData(storageData); if (storageType === StorageType.NEW_PVC) { - const pvcData = assemblePvc(pvcName, projectName, pvcDescription, size); + const pvcData = assemblePvc(pvcName, projectName, pvcDescription, size, storageClassName); const pvc = await createPvc(pvcData); const newPvcName = pvc.metadata.name; volumes.push({ name: newPvcName, persistentVolumeClaim: { claimName: newPvcName } }); diff --git a/frontend/src/pages/projects/screens/spawner/storage/usePreferredStorageClass.ts b/frontend/src/pages/projects/screens/spawner/storage/usePreferredStorageClass.ts new file mode 100644 index 0000000000..f1993163f7 --- /dev/null +++ b/frontend/src/pages/projects/screens/spawner/storage/usePreferredStorageClass.ts @@ -0,0 +1,45 @@ +import * as React from 'react'; +import { AppContext } from '~/app/AppContext'; +import { StorageClassKind } from '~/k8sTypes'; + +const usePreferredStorageClass = (): StorageClassKind | undefined => { + const { + dashboardConfig: { + spec: { notebookController }, + }, + storageClasses, + } = React.useContext(AppContext); + + const defaultClusterStorageClasses = storageClasses.filter((storageclass) => + storageclass.metadata.annotations?.['storageclass.kubernetes.io/is-default-class']?.includes( + 'true', + ), + ); + + const configStorageClassName = notebookController?.storageClassName ?? ''; + + if (defaultClusterStorageClasses.length != 0) { + return undefined; + } + + if (configStorageClassName == '') { + return undefined; + } + + const storageClassDashBoardConfigVsCluster = storageClasses.filter((storageclass) => + storageclass.metadata.name.includes(configStorageClassName), + ); + + if (storageClassDashBoardConfigVsCluster.length === 0) { + // eslint-disable-next-line no-console + console.error( + 'no cluster default storageclass set and notebooks.storageClassName entry is not in list of cluster StorageClasses', + ); + + return undefined; + } + + return storageClassDashBoardConfigVsCluster[0]; +}; + +export default usePreferredStorageClass; diff --git a/frontend/src/types.ts b/frontend/src/types.ts index 4781bc9072..550ea81eb5 100644 --- a/frontend/src/types.ts +++ b/frontend/src/types.ts @@ -59,6 +59,7 @@ export type DashboardConfig = K8sResourceCommon & { notebookController?: { enabled: boolean; pvcSize?: string; + storageClassName?: string; notebookNamespace?: string; gpuSetting?: GpuSettingString; notebookTolerationSettings?: TolerationSettings; From a1100d6b3080f16bc2dfe5ef1ad8dc93ab0c7318 Mon Sep 17 00:00:00 2001 From: Sven Thoms <21118431+shalberd@users.noreply.github.com> Date: Fri, 6 Oct 2023 18:57:30 +0200 Subject: [PATCH 2/9] fix bug when filtering cluster storageclasses and now doing correct string equality compare instead of string includes. also using strict equality comparison --- .../screens/spawner/storage/usePreferredStorageClass.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/src/pages/projects/screens/spawner/storage/usePreferredStorageClass.ts b/frontend/src/pages/projects/screens/spawner/storage/usePreferredStorageClass.ts index f1993163f7..c66488d763 100644 --- a/frontend/src/pages/projects/screens/spawner/storage/usePreferredStorageClass.ts +++ b/frontend/src/pages/projects/screens/spawner/storage/usePreferredStorageClass.ts @@ -18,16 +18,16 @@ const usePreferredStorageClass = (): StorageClassKind | undefined => { const configStorageClassName = notebookController?.storageClassName ?? ''; - if (defaultClusterStorageClasses.length != 0) { + if (defaultClusterStorageClasses.length !== 0) { return undefined; } - if (configStorageClassName == '') { + if (configStorageClassName === '') { return undefined; } - const storageClassDashBoardConfigVsCluster = storageClasses.filter((storageclass) => - storageclass.metadata.name.includes(configStorageClassName), + const storageClassDashBoardConfigVsCluster = storageClasses.filter( + (storageclass) => storageclass.metadata.name === configStorageClassName, ); if (storageClassDashBoardConfigVsCluster.length === 0) { From 7f83c2cf4e1af846432bc5828f5ebcff3491b561 Mon Sep 17 00:00:00 2001 From: Alex Creasy Date: Wed, 14 Feb 2024 11:17:56 +0000 Subject: [PATCH 3/9] Fixes errors from merge conflict resolution --- frontend/src/api/k8s/storageClasses.ts | 1 + frontend/src/app/AppContext.ts | 3 +-- frontend/src/concepts/k8s/useStorageClasses.ts | 6 ++++-- frontend/src/pages/projects/screens/spawner/service.ts | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/frontend/src/api/k8s/storageClasses.ts b/frontend/src/api/k8s/storageClasses.ts index fdf6893783..7f9bcbbd81 100644 --- a/frontend/src/api/k8s/storageClasses.ts +++ b/frontend/src/api/k8s/storageClasses.ts @@ -1,6 +1,7 @@ import { k8sListResource } from '@openshift/dynamic-plugin-sdk-utils'; import { StorageClassKind } from '~/k8sTypes'; import { StorageClassModel } from '~/api/models'; + export const getStorageClasses = (): Promise => k8sListResource({ model: StorageClassModel, diff --git a/frontend/src/app/AppContext.ts b/frontend/src/app/AppContext.ts index 3e0fd149d5..0b9fa68329 100644 --- a/frontend/src/app/AppContext.ts +++ b/frontend/src/app/AppContext.ts @@ -1,6 +1,5 @@ import * as React from 'react'; -import { StorageClassKind } from '~/k8sTypes'; -import { DashboardConfigKind } from '~/k8sTypes'; +import { StorageClassKind, DashboardConfigKind } from '~/k8sTypes'; import { BuildStatus } from '~/types'; type AppContextProps = { diff --git a/frontend/src/concepts/k8s/useStorageClasses.ts b/frontend/src/concepts/k8s/useStorageClasses.ts index 02422b3376..2c8a2eb71a 100644 --- a/frontend/src/concepts/k8s/useStorageClasses.ts +++ b/frontend/src/concepts/k8s/useStorageClasses.ts @@ -1,6 +1,8 @@ -import useFetchState from '~/utilities/useFetchState'; +import useFetchState, { FetchState } from '~/utilities/useFetchState'; import { getStorageClasses } from '~/api'; +import { StorageClassKind } from '~/k8sTypes'; -const useStorageClasses = () => useFetchState(getStorageClasses, []); +const useStorageClasses = (): FetchState => + useFetchState(getStorageClasses, []); export default useStorageClasses; diff --git a/frontend/src/pages/projects/screens/spawner/service.ts b/frontend/src/pages/projects/screens/spawner/service.ts index d47b94ef7d..75c649d105 100644 --- a/frontend/src/pages/projects/screens/spawner/service.ts +++ b/frontend/src/pages/projects/screens/spawner/service.ts @@ -69,7 +69,7 @@ export const replaceRootVolumesForNotebook = async ( }; replacedVolumeMount = { name: existingName, mountPath: ROOT_MOUNT_PATH }; } else { - const pvc = await createPvc(storageData.creating, projectName, { dryRun }); + const pvc = await createPvc(storageData.creating, projectName, undefined, { dryRun }); const newPvcName = pvc.metadata.name; replacedVolume = { name: newPvcName, persistentVolumeClaim: { claimName: newPvcName } }; replacedVolumeMount = { mountPath: ROOT_MOUNT_PATH, name: newPvcName }; From 30db3eaae2ee83256ed36489034cbb8c01728368 Mon Sep 17 00:00:00 2001 From: Alex Creasy Date: Wed, 14 Feb 2024 11:36:30 +0000 Subject: [PATCH 4/9] Fixes errors from merge conflict resolution round 2 --- frontend/src/app/App.tsx | 130 ++++++++++++++++++++------------------- 1 file changed, 67 insertions(+), 63 deletions(-) diff --git a/frontend/src/app/App.tsx b/frontend/src/app/App.tsx index b06d182f6f..977041a3af 100644 --- a/frontend/src/app/App.tsx +++ b/frontend/src/app/App.tsx @@ -47,75 +47,79 @@ const App: React.FC = () => { useDetectUser(); - if (!username || !configLoaded || !dashboardConfig) { - // We lack the critical data to startup the app - if (userError || fetchConfigError) { - // There was an error fetching critical data - return ( - - - - - -

- {(userError ? userError.message : fetchConfigError?.message) || - 'Unknown error occurred during startup.'} -

-

Logging out and logging back in may solve the issue.

-
-
- - - -
-
-
- ); - } - - // Assume we are still waiting on the API to finish + // We lack the critical data to startup the app + if (userError || fetchConfigError) { + // There was an error fetching critical data return ( - - - + + + + + +

+ {(userError ? userError.message : fetchConfigError?.message) || + 'Unknown error occurred during startup.'} +

+

Logging out and logging back in may solve the issue.

+
+
+ + + +
+
+
); } + // Waiting on the API to finish + const loading = !username || !configLoaded || !dashboardConfig; + return ( - - - setNotificationsOpen(!notificationsOpen)} />} - sidebar={isAllowed ? : undefined} - notificationDrawer={ setNotificationsOpen(false)} />} - isNotificationDrawerExpanded={notificationsOpen} - mainContainerId={DASHBOARD_MAIN_CONTAINER_ID} + + {loading ? ( + + + + ) : ( + - - - - - - - - - - - - + setNotificationsOpen(!notificationsOpen)} /> + } + sidebar={isAllowed ? : undefined} + notificationDrawer={ + setNotificationsOpen(false)} /> + } + isNotificationDrawerExpanded={notificationsOpen} + mainContainerId={DASHBOARD_MAIN_CONTAINER_ID} + > + + + + + + + + + + + + )} + ); }; From 65400cb95b8126ae170b037f8d624e6ad775a890 Mon Sep 17 00:00:00 2001 From: Alex Creasy Date: Fri, 16 Feb 2024 14:28:04 +0000 Subject: [PATCH 5/9] Fixes log message --- .../screens/spawner/storage/usePreferredStorageClass.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/projects/screens/spawner/storage/usePreferredStorageClass.ts b/frontend/src/pages/projects/screens/spawner/storage/usePreferredStorageClass.ts index c66488d763..0f133e0907 100644 --- a/frontend/src/pages/projects/screens/spawner/storage/usePreferredStorageClass.ts +++ b/frontend/src/pages/projects/screens/spawner/storage/usePreferredStorageClass.ts @@ -33,7 +33,7 @@ const usePreferredStorageClass = (): StorageClassKind | undefined => { if (storageClassDashBoardConfigVsCluster.length === 0) { // eslint-disable-next-line no-console console.error( - 'no cluster default storageclass set and notebooks.storageClassName entry is not in list of cluster StorageClasses', + 'no cluster default storageclass set and notebookController.storageClassName entry is not in list of cluster StorageClasses', ); return undefined; From 9ad5f2c2db475f6169b5387e40aecb88aabec8a3 Mon Sep 17 00:00:00 2001 From: Alex Creasy Date: Mon, 19 Feb 2024 14:06:16 +0000 Subject: [PATCH 6/9] Fix tests --- frontend/src/api/k8s/__tests__/pvcs.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/api/k8s/__tests__/pvcs.spec.ts b/frontend/src/api/k8s/__tests__/pvcs.spec.ts index 9696232fc8..c3425cede9 100644 --- a/frontend/src/api/k8s/__tests__/pvcs.spec.ts +++ b/frontend/src/api/k8s/__tests__/pvcs.spec.ts @@ -62,6 +62,7 @@ const assemblePvcResult: PersistentVolumeClaimKind = { accessModes: ['ReadWriteOnce'], resources: { requests: { storage: '5Gi' } }, volumeMode: 'Filesystem', + storageClassName: undefined, }, status: { phase: 'Pending' }, }; From abbeebd5447438023a5196b866a5ae79a5f1b4fe Mon Sep 17 00:00:00 2001 From: Alex Creasy Date: Thu, 22 Feb 2024 14:57:00 +0000 Subject: [PATCH 7/9] Default storage class is now added to standalone PVCs created without a workbench --- .../projects/screens/detail/storage/ManageStorageModal.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/frontend/src/pages/projects/screens/detail/storage/ManageStorageModal.tsx b/frontend/src/pages/projects/screens/detail/storage/ManageStorageModal.tsx index 6eaf6bcda5..2a6604778a 100644 --- a/frontend/src/pages/projects/screens/detail/storage/ManageStorageModal.tsx +++ b/frontend/src/pages/projects/screens/detail/storage/ManageStorageModal.tsx @@ -13,6 +13,7 @@ import NotebookRestartAlert from '~/pages/projects/components/NotebookRestartAle import useWillNotebooksRestart from '~/pages/projects/notebook/useWillNotebooksRestart'; import DashboardModalFooter from '~/concepts/dashboard/DashboardModalFooter'; import { getPvcDescription, getPvcDisplayName } from '~/pages/projects/utils'; +import usePreferredStorageClass from '~/pages/projects/screens/spawner/storage/usePreferredStorageClass'; import ExistingConnectedNotebooks from './ExistingConnectedNotebooks'; type AddStorageModalProps = { @@ -39,6 +40,8 @@ const ManageStorageModal: React.FC = ({ existingData, isOp createData.forNotebook.name, ]); + const storageClassName = usePreferredStorageClass(); + const onBeforeClose = (submitted: boolean) => { onClose(submitted); setActionInProgress(false); @@ -84,7 +87,9 @@ const ManageStorageModal: React.FC = ({ existingData, isOp } return; } - const createdPvc = await createPvc(createData, namespace, undefined, { dryRun }); + const createdPvc = await createPvc(createData, namespace, storageClassName?.metadata.name, { + dryRun, + }); if (notebookName) { await attachNotebookPVC(notebookName, namespace, createdPvc.metadata.name, mountPath.value, { dryRun, From d0170325536acc7701b48f4caddaacae47552696 Mon Sep 17 00:00:00 2001 From: Alex Creasy Date: Mon, 26 Feb 2024 15:56:54 +0000 Subject: [PATCH 8/9] Default storage class now added when changing root storage class of workbench --- frontend/src/pages/projects/screens/spawner/SpawnerFooter.tsx | 1 + frontend/src/pages/projects/screens/spawner/service.ts | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/frontend/src/pages/projects/screens/spawner/SpawnerFooter.tsx b/frontend/src/pages/projects/screens/spawner/SpawnerFooter.tsx index 2b539ffe07..a5fe350747 100644 --- a/frontend/src/pages/projects/screens/spawner/SpawnerFooter.tsx +++ b/frontend/src/pages/projects/screens/spawner/SpawnerFooter.tsx @@ -138,6 +138,7 @@ const SpawnerFooter: React.FC = ({ projectName, editNotebook, storageData, + storageClass?.metadata.name, dryRun, ).catch(handleError); diff --git a/frontend/src/pages/projects/screens/spawner/service.ts b/frontend/src/pages/projects/screens/spawner/service.ts index 75c649d105..3d84738503 100644 --- a/frontend/src/pages/projects/screens/spawner/service.ts +++ b/frontend/src/pages/projects/screens/spawner/service.ts @@ -49,6 +49,7 @@ export const replaceRootVolumesForNotebook = async ( projectName: string, notebook: NotebookKind, storageData: StorageData, + storageClassName?: string, dryRun?: boolean, ): Promise<{ volumes: Volume[]; volumeMounts: VolumeMount[] }> => { const { @@ -69,7 +70,7 @@ export const replaceRootVolumesForNotebook = async ( }; replacedVolumeMount = { name: existingName, mountPath: ROOT_MOUNT_PATH }; } else { - const pvc = await createPvc(storageData.creating, projectName, undefined, { dryRun }); + const pvc = await createPvc(storageData.creating, projectName, storageClassName, { dryRun }); const newPvcName = pvc.metadata.name; replacedVolume = { name: newPvcName, persistentVolumeClaim: { claimName: newPvcName } }; replacedVolumeMount = { mountPath: ROOT_MOUNT_PATH, name: newPvcName }; From ce34a6b57d40deabdbc833a11d30f343867f269b Mon Sep 17 00:00:00 2001 From: Alex Creasy Date: Mon, 26 Feb 2024 17:07:19 +0000 Subject: [PATCH 9/9] Codestyle tweaks --- frontend/src/app/AppContext.ts | 2 +- .../projects/screens/detail/storage/ManageStorageModal.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/app/AppContext.ts b/frontend/src/app/AppContext.ts index 0b9fa68329..bdc0141450 100644 --- a/frontend/src/app/AppContext.ts +++ b/frontend/src/app/AppContext.ts @@ -1,5 +1,5 @@ import * as React from 'react'; -import { StorageClassKind, DashboardConfigKind } from '~/k8sTypes'; +import { DashboardConfigKind, StorageClassKind } from '~/k8sTypes'; import { BuildStatus } from '~/types'; type AppContextProps = { diff --git a/frontend/src/pages/projects/screens/detail/storage/ManageStorageModal.tsx b/frontend/src/pages/projects/screens/detail/storage/ManageStorageModal.tsx index 2a6604778a..8a105de661 100644 --- a/frontend/src/pages/projects/screens/detail/storage/ManageStorageModal.tsx +++ b/frontend/src/pages/projects/screens/detail/storage/ManageStorageModal.tsx @@ -40,7 +40,7 @@ const ManageStorageModal: React.FC = ({ existingData, isOp createData.forNotebook.name, ]); - const storageClassName = usePreferredStorageClass(); + const storageClass = usePreferredStorageClass(); const onBeforeClose = (submitted: boolean) => { onClose(submitted); @@ -87,7 +87,7 @@ const ManageStorageModal: React.FC = ({ existingData, isOp } return; } - const createdPvc = await createPvc(createData, namespace, storageClassName?.metadata.name, { + const createdPvc = await createPvc(createData, namespace, storageClass?.metadata.name, { dryRun, }); if (notebookName) {