From 99f036a6e0f85ecb6f831069ae1c97804329be23 Mon Sep 17 00:00:00 2001 From: Oleksii Kurinnyi Date: Fri, 10 Nov 2023 11:15:47 +0200 Subject: [PATCH 1/2] fix: preserve dwoc Signed-off-by: Oleksii Kurinnyi --- .../devworkspace/devWorkspaceClient.ts | 22 ++++++------------- 1 file changed, 7 insertions(+), 15 deletions(-) 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 aaa1f63ab..db406f50e 100644 --- a/packages/dashboard-frontend/src/services/workspace-client/devworkspace/devWorkspaceClient.ts +++ b/packages/dashboard-frontend/src/services/workspace-client/devworkspace/devWorkspaceClient.ts @@ -458,23 +458,15 @@ export class DevWorkspaceClient { const cheNamespace = config.cheNamespace; let attributes = workspace.spec.template.attributes; if (cheNamespace) { - const devworkspaceConfig = { name: 'devworkspace-config', namespace: cheNamespace }; - const devworkspaceConfigPath = `/spec/template/attributes/${this.escape( - DEVWORKSPACE_CONFIG_ATTR, - )}`; - if (attributes) { - if (attributes[DEVWORKSPACE_CONFIG_ATTR]) { - if (attributes[DEVWORKSPACE_CONFIG_ATTR] !== devworkspaceConfig) { - patch.push({ op: 'replace', path: devworkspaceConfigPath, value: devworkspaceConfig }); - } - } else { - patch.push({ op: 'add', path: devworkspaceConfigPath, value: devworkspaceConfig }); - } - } else { + if (attributes?.[DEVWORKSPACE_CONFIG_ATTR] === undefined) { + const devworkspaceConfig = { name: 'devworkspace-config', namespace: cheNamespace }; + const devworkspaceConfigPath = `/spec/template/attributes/${this.escape( + DEVWORKSPACE_CONFIG_ATTR, + )}`; patch.push({ op: 'add', - path: '/spec/template/attributes', - value: { [DEVWORKSPACE_CONFIG_ATTR]: devworkspaceConfig }, + path: devworkspaceConfigPath, + value: devworkspaceConfig, }); attributes = {}; } From 0154a64758b5f87b36e5cc2be203fd0819400c50 Mon Sep 17 00:00:00 2001 From: Oleksii Kurinnyi Date: Mon, 20 Nov 2023 14:09:57 +0200 Subject: [PATCH 2/2] fixup! fix: preserve dwoc --- ...vWorkspaceClient.managePvcStrategy.spec.ts | 172 ++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 packages/dashboard-frontend/src/services/workspace-client/devworkspace/__tests__/devWorkspaceClient.managePvcStrategy.spec.ts diff --git a/packages/dashboard-frontend/src/services/workspace-client/devworkspace/__tests__/devWorkspaceClient.managePvcStrategy.spec.ts b/packages/dashboard-frontend/src/services/workspace-client/devworkspace/__tests__/devWorkspaceClient.managePvcStrategy.spec.ts new file mode 100644 index 000000000..c51d0f5f2 --- /dev/null +++ b/packages/dashboard-frontend/src/services/workspace-client/devworkspace/__tests__/devWorkspaceClient.managePvcStrategy.spec.ts @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2018-2023 Red Hat, Inc. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ + +import { api } from '@eclipse-che/common'; + +import { container } from '@/inversify.config'; +import * as DwApi from '@/services/backend-client/devWorkspaceApi'; +import devfileApi from '@/services/devfileApi'; +import { DEVWORKSPACE_CONFIG_ATTR } from '@/services/devfileApi/devWorkspace/spec/template'; +import { DevWorkspaceClient } from '@/services/workspace-client/devworkspace/devWorkspaceClient'; +import { DevWorkspaceBuilder } from '@/store/__mocks__/devWorkspaceBuilder'; + +describe('DevWorkspace client, managePvcStrategy', () => { + const name = 'wksp-test'; + const namespace = 'user-che'; + let client: DevWorkspaceClient; + let devWorkspaceBuilder: DevWorkspaceBuilder; + let spyPatchWorkspace: jest.SpyInstance; + + beforeEach(() => { + client = container.get(DevWorkspaceClient); + devWorkspaceBuilder = new DevWorkspaceBuilder().withMetadata({ name, namespace }); + + spyPatchWorkspace = jest + .spyOn(DwApi, 'patchWorkspace') + .mockResolvedValue({ devWorkspace: {} as devfileApi.DevWorkspace, headers: {} }); + }); + + afterEach(() => { + jest.resetAllMocks(); + }); + + it('should update devWorkspace config', async () => { + const devWorkspace = devWorkspaceBuilder + .withSpec({ + template: { + attributes: { + [DEVWORKSPACE_CONFIG_ATTR]: undefined, + }, + }, + }) + .build(); + const config = { + defaults: {}, + cheNamespace: namespace, + } as api.IServerConfig; + + await client.managePvcStrategy(devWorkspace, config); + + expect(spyPatchWorkspace).toHaveBeenCalledWith(namespace, name, [ + { + op: 'add', + path: '/spec/template/attributes/controller.devfile.io~1devworkspace-config', + value: { name: 'devworkspace-config', namespace: 'user-che' }, + }, + ]); + }); + + it('should update devWorkspace storage type', async () => { + const devWorkspace = devWorkspaceBuilder + .withSpec({ + template: { + attributes: { + [DEVWORKSPACE_CONFIG_ATTR]: 'custom-config', + }, + }, + }) + .build(); + const config = { + defaults: { + pvcStrategy: 'custom-pvc-strategy', + }, + cheNamespace: namespace, + } as api.IServerConfig; + + await client.managePvcStrategy(devWorkspace, config); + + expect(spyPatchWorkspace).toHaveBeenCalledWith(namespace, name, [ + { + op: 'add', + path: '/spec/template/attributes/controller.devfile.io~1storage-type', + value: 'custom-pvc-strategy', + }, + ]); + }); + + it('should update devWorkspace template components', async () => { + const devWorkspace = devWorkspaceBuilder + .withSpec({ + template: { + attributes: { + [DEVWORKSPACE_CONFIG_ATTR]: 'custom-config', + }, + components: [ + { + name: 'component1', + container: { + env: [ + { + name: 'OPENVSX_REGISTRY_URL', + value: 'https://open-vsx.org', + }, + ], + image: 'container1-image', + }, + }, + { + name: 'component2', + }, + ], + }, + }) + .build(); + const config = { + defaults: {}, + cheNamespace: namespace, + pluginRegistry: { + openVSXURL: 'custom-openvsx-url', + }, + } as api.IServerConfig; + + await client.managePvcStrategy(devWorkspace, config); + + expect(spyPatchWorkspace).toHaveBeenCalledWith(namespace, name, [ + { + op: 'replace', + path: '/spec/template/components', + value: [ + { + container: { + env: [{ name: 'OPENVSX_REGISTRY_URL', value: 'custom-openvsx-url' }], + image: 'container1-image', + }, + name: 'component1', + }, + { + name: 'component2', + }, + ], + }, + ]); + }); + + it('should NOT update devWorkspace config nor devWorkspace storage type', async () => { + const devWorkspace = devWorkspaceBuilder + .withSpec({ + template: { + attributes: { + [DEVWORKSPACE_CONFIG_ATTR]: 'custom-config', + }, + }, + }) + .build(); + const config = { + defaults: {}, + cheNamespace: namespace, + } as api.IServerConfig; + + await client.managePvcStrategy(devWorkspace, config); + + expect(spyPatchWorkspace).not.toHaveBeenCalled(); + }); +});