diff --git a/packages/dashboard-frontend/src/services/workspace-client/devworkspace/devWorkspaceClient.ts b/packages/dashboard-frontend/src/services/workspace-client/devworkspace/devWorkspaceClient.ts index 528826235..3c62ec8da 100644 --- a/packages/dashboard-frontend/src/services/workspace-client/devworkspace/devWorkspaceClient.ts +++ b/packages/dashboard-frontend/src/services/workspace-client/devworkspace/devWorkspaceClient.ts @@ -33,6 +33,7 @@ import { import { DEVWORKSPACE_CONFIG_ATTR, DEVWORKSPACE_CONTAINER_BUILD_ATTR, + DEVWORKSPACE_STORAGE_TYPE_ATTR, } from '@/services/devfileApi/devWorkspace/spec/template'; import { delay } from '@/services/helpers/delay'; import { isWebTerminal } from '@/services/helpers/devworkspace'; @@ -209,14 +210,22 @@ export class DevWorkspaceClient { return DwtApi.createTemplate(devWorkspaceTemplateResource); } - async updateDevWorkspace( - devWorkspace: devfileApi.DevWorkspace, + /** + * Update the storage-type of a devworkspace + * @param namespace + * @param name + * @param storageType + */ + async updateDevWorkspaceStorageType( + namespace, + name, + storageType, ): Promise<{ headers: DwApi.Headers; devWorkspace: devfileApi.DevWorkspace }> { - return await DwApi.patchWorkspace(devWorkspace.metadata.namespace, devWorkspace.metadata.name, [ + return await DwApi.patchWorkspace(namespace, name, [ { op: 'replace', - path: '/spec/template/components', - value: devWorkspace.spec.template.components || [], + path: '/spec/template/attributes/' + DEVWORKSPACE_STORAGE_TYPE_ATTR.replace(/\//g, '~1'), + value: storageType, }, ]); } diff --git a/packages/dashboard-frontend/src/store/Workspaces/devWorkspaces/actions/actionCreators/__tests__/createWorkspaceFromResources.spec.ts b/packages/dashboard-frontend/src/store/Workspaces/devWorkspaces/actions/actionCreators/__tests__/createWorkspaceFromResources.spec.ts index 92422364e..c5ce53f0b 100644 --- a/packages/dashboard-frontend/src/store/Workspaces/devWorkspaces/actions/actionCreators/__tests__/createWorkspaceFromResources.spec.ts +++ b/packages/dashboard-frontend/src/store/Workspaces/devWorkspaces/actions/actionCreators/__tests__/createWorkspaceFromResources.spec.ts @@ -40,6 +40,25 @@ jest.mock('@/store/InfrastructureNamespaces'); jest.mock('@/store/ClusterInfo'); describe('devWorkspaces, actions', () => { + let mockWorkspace: devfileApi.DevWorkspace; + + beforeEach(() => { + mockWorkspace = { + metadata: { + namespace: 'test-namespace', + name: 'test-workspace', + uid: '1', + }, + spec: { + template: { + attributes: { + 'controller.devfile.io/storage-type': 'per-user', + }, + }, + }, + } as devfileApi.DevWorkspace; + }); + afterEach(() => { jest.clearAllMocks(); }); @@ -48,20 +67,12 @@ describe('devWorkspaces, actions', () => { let store: ReturnType; const mockCreateDevWorkspace = jest.fn(); const mockCreateDevWorkspaceTemplate = jest.fn(); - const mockUpdateDevWorkspace = jest.fn(); + const mockUpdateDevWorkspaceStorageType = jest.fn(); const mockVerifyAuthorized = verifyAuthorized as jest.MockedFunction; const mockUpdateDevWorkspaceTemplate = updateDevWorkspaceTemplate as jest.MockedFunction< typeof updateDevWorkspaceTemplate >; - const mockWorkspace = { - metadata: { - namespace: 'test-namespace', - name: 'test-workspace', - uid: '1', - }, - } as devfileApi.DevWorkspace; - const mockWorkspaceTemplate = {} as devfileApi.DevWorkspaceTemplate; const mockFactoryParams = {} as Partial; @@ -92,7 +103,7 @@ describe('devWorkspaces, actions', () => { (getDevWorkspaceClient as jest.Mock).mockReturnValue({ createDevWorkspace: mockCreateDevWorkspace, createDevWorkspaceTemplate: mockCreateDevWorkspaceTemplate, - updateDevWorkspace: mockUpdateDevWorkspace, + updateDevWorkspaceStorageType: mockUpdateDevWorkspaceStorageType, }); mockCreateDevWorkspace.mockResolvedValue({ @@ -100,7 +111,7 @@ describe('devWorkspaces, actions', () => { headers: {}, }); - mockUpdateDevWorkspace.mockResolvedValue({ + mockUpdateDevWorkspaceStorageType.mockResolvedValue({ devWorkspace: mockWorkspace, headers: {}, }); @@ -132,7 +143,11 @@ describe('devWorkspaces, actions', () => { expect(mockCreateDevWorkspaceTemplate).toHaveBeenCalled(); - expect(mockUpdateDevWorkspace).toHaveBeenCalledWith(mockWorkspace); + expect(mockUpdateDevWorkspaceStorageType).toHaveBeenCalledWith( + 'test-namespace', + 'test-workspace', + 'per-user', + ); }); it('should handle warnings from createDevWorkspace and dispatch warning action', async () => { @@ -159,8 +174,8 @@ describe('devWorkspaces, actions', () => { expect(actions[2]).toEqual(devWorkspacesAddAction(mockWorkspace)); }); - it('should handle warnings from updateDevWorkspace and dispatch warning action', async () => { - mockUpdateDevWorkspace.mockResolvedValueOnce({ + it('should handle warnings from updateDevWorkspaceStorageType and dispatch warning action', async () => { + mockUpdateDevWorkspaceStorageType.mockResolvedValueOnce({ devWorkspace: mockWorkspace, headers: { warning: '299 - Another warning message', diff --git a/packages/dashboard-frontend/src/store/Workspaces/devWorkspaces/actions/actionCreators/createWorkspaceFromResources.ts b/packages/dashboard-frontend/src/store/Workspaces/devWorkspaces/actions/actionCreators/createWorkspaceFromResources.ts index 2d9e782a5..7635f03c4 100644 --- a/packages/dashboard-frontend/src/store/Workspaces/devWorkspaces/actions/actionCreators/createWorkspaceFromResources.ts +++ b/packages/dashboard-frontend/src/store/Workspaces/devWorkspaces/actions/actionCreators/createWorkspaceFromResources.ts @@ -13,6 +13,7 @@ import common, { ApplicationId } from '@eclipse-che/common'; import devfileApi from '@/services/devfileApi'; +import { DEVWORKSPACE_STORAGE_TYPE_ATTR } from '@/services/devfileApi/devWorkspace/spec/template'; import { FactoryParams } from '@/services/helpers/factoryFlow/buildFactoryParams'; import { AppThunk } from '@/store'; import { selectApplications } from '@/store/ClusterInfo'; @@ -54,6 +55,10 @@ export const createWorkspaceFromResources = dispatch(devWorkspacesRequestAction()); + const storageType = devWorkspace.spec?.template?.attributes?.[DEVWORKSPACE_STORAGE_TYPE_ATTR]; + if (storageType && storageType !== 'ephemeral') { + devWorkspace.spec.template.attributes[DEVWORKSPACE_STORAGE_TYPE_ATTR] = 'ephemeral'; + } /* create a new DevWorkspace */ const createResp = await getDevWorkspaceClient().createDevWorkspace( defaultNamespace, @@ -90,18 +95,27 @@ export const createWorkspaceFromResources = /* update the DevWorkspace */ - const updateResp = await getDevWorkspaceClient().updateDevWorkspace(createResp.devWorkspace); - - if (updateResp.headers.warning) { - dispatch( - devWorkspaceWarningUpdateAction({ - warning: cleanupMessage(updateResp.headers.warning), - workspace: updateResp.devWorkspace, - }), + if (storageType && storageType !== 'ephemeral') { + const { namespace, name } = devWorkspace.metadata; + const updateResp = await getDevWorkspaceClient().updateDevWorkspaceStorageType( + namespace, + name, + storageType, ); - } - dispatch(devWorkspacesAddAction(updateResp.devWorkspace)); + if (updateResp.headers.warning) { + dispatch( + devWorkspaceWarningUpdateAction({ + warning: cleanupMessage(updateResp.headers.warning), + workspace: updateResp.devWorkspace, + }), + ); + } + + dispatch(devWorkspacesAddAction(updateResp.devWorkspace)); + } else { + dispatch(devWorkspacesAddAction(createResp.devWorkspace)); + } } catch (e) { const errorMessage = 'Failed to create a new workspace, reason: ' + common.helpers.errors.getMessage(e);