Skip to content

Commit

Permalink
fixup! fixup! fixup! fixup! feat: implement an ability to start works…
Browse files Browse the repository at this point in the history
…paces in Safe Mode
  • Loading branch information
olexii4 committed Aug 15, 2023
1 parent 9b3d857 commit 90f9794
Show file tree
Hide file tree
Showing 6 changed files with 209 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ import { ProgressStep, ProgressStepProps, ProgressStepState } from '../../Progre
import { ProgressStepTitle } from '../../StepTitle';
import { TimeLimit } from '../../TimeLimit';
import {
DEBUG_WORKSPACE_START,
USE_DEFAULT_DEVFILE,
} from '../../../../services/helpers/factoryFlow/buildFactoryParams';
applyRestartDefaultLocation,
applyRestartInDebugModeLocation,
applyRestartInSafeModeLocation,
} from '../StartWorkspace/prepareRestart';

export type Props = MappedProps &
ProgressStepProps & {
Expand Down Expand Up @@ -97,36 +98,7 @@ class StartingStepOpenWorkspace extends ProgressStep<Props, State> {
return false;
}

protected handleRestartInSafeMode(alertKey: string, tab: LoaderTab): void {
const searchParams = new URLSearchParams(this.props.history.location.search);
searchParams.set(USE_DEFAULT_DEVFILE, 'true');
searchParams.delete(DEBUG_WORKSPACE_START);
this.props.history.location.search = searchParams.toString();

this.props.onHideError(alertKey);

this.clearStepError();
this.props.onRestart(tab);
}

protected handleRestartInDebugMode(alertKey: string, tab: LoaderTab): void {
const searchParams = new URLSearchParams(this.props.history.location.search);
searchParams.set(DEBUG_WORKSPACE_START, 'true');
searchParams.delete(USE_DEFAULT_DEVFILE);
this.props.history.location.search = searchParams.toString();

this.props.onHideError(alertKey);

this.clearStepError();
this.props.onRestart(tab);
}

protected handleRestart(alertKey: string, tab: LoaderTab): void {
const searchParams = new URLSearchParams(this.props.history.location.search);
searchParams.delete(DEBUG_WORKSPACE_START);
searchParams.delete(USE_DEFAULT_DEVFILE);
this.props.history.location.search = searchParams.toString();

this.props.onHideError(alertKey);

this.clearStepError();
Expand Down Expand Up @@ -191,15 +163,24 @@ class StartingStepOpenWorkspace extends ProgressStep<Props, State> {
actionCallbacks: [
{
title: 'Restart',
callback: () => this.handleRestart(key, LoaderTab.Progress),
callback: () => {
applyRestartDefaultLocation(this.props.history.location);
this.handleRestart(key, LoaderTab.Progress);
},
},
{
title: 'Restart in Safe mode',
callback: () => this.handleRestartInSafeMode(key, LoaderTab.Progress),
callback: () => {
applyRestartInSafeModeLocation(this.props.history.location);
this.handleRestart(key, LoaderTab.Progress);
},
},
{
title: 'Restart in Debug mode',
callback: () => this.handleRestartInDebugMode(key, LoaderTab.Logs),
callback: () => {
applyRestartInDebugModeLocation(this.props.history.location);
this.handleRestart(key, LoaderTab.Logs);
},
},
],
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`ProgressStepTitle snapshot - non-active step 1`] = `
Object {
"search": "tab=Progress",
}
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* 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 {
applyStartWorkspace,
applyRestartDefaultLocation,
applyRestartInDebugModeLocation,
applyRestartInSafeModeLocation,
resetRestartInSafeModeLocation,
} from '../prepareRestart';
import { Location } from 'history';
import { DevWorkspaceBuilder } from '../../../../../store/__mocks__/devWorkspaceBuilder';
import { constructWorkspace } from '../../../../../services/workspace-adapter';

describe('Prepare workspace start', () => {
const startCallback = jest.fn();

beforeEach(() => {
startCallback.mockResolvedValueOnce(Promise.resolve());
});

afterEach(() => {
jest.clearAllMocks();
});

test('apply Safe Mode location', () => {
const location = { search: '?tab=Progress' } as Location<unknown>;

applyRestartInDebugModeLocation(location);

expect(location).toEqual({ search: 'tab=Progress&debugWorkspaceStart=true' });
});

test('apply Safe Mode location', () => {
const location = { search: '?tab=Progress' } as Location<unknown>;

applyRestartInSafeModeLocation(location);

expect(location).toEqual({ search: 'tab=Progress&useDefaultDevfile=true' });
});

test('apply default location', () => {
const location = { search: '?debugWorkspaceStart=true&tab=Logs' } as Location<unknown>;

applyRestartDefaultLocation(location);

expect(location).toEqual({ search: 'tab=Logs' });
});

test('reset Safe Mode location', () => {
const location = { search: '?tab=Logs&useDefaultDevfile=true' } as Location<unknown>;

let hasChanged = resetRestartInSafeModeLocation(location);

expect(hasChanged).toBeTruthy();
expect(location).toEqual({ search: 'tab=Logs' });

hasChanged = resetRestartInSafeModeLocation(location);

expect(hasChanged).toBeFalsy();
expect(location).toEqual({ search: 'tab=Logs' });
});

test('apply start workspace', async () => {
const workspace = constructWorkspace(new DevWorkspaceBuilder().build());
const location = { search: '' } as Location<unknown>;

await applyStartWorkspace(startCallback, workspace, location);

expect(startCallback).toBeCalledWith(workspace, undefined);
});

test('apply start workspace in Debug Mode', async () => {
const workspace = constructWorkspace(new DevWorkspaceBuilder().build());
const location = { search: '?debugWorkspaceStart=true' } as Location<unknown>;

await applyStartWorkspace(startCallback, workspace, location);

expect(startCallback).toBeCalledWith(workspace, {
'debug-workspace-start': true,
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,12 @@ import { ProgressStepTitle } from '../../StepTitle';
import { TimeLimit } from '../../TimeLimit';
import workspaceStatusIs from '../../workspaceStatusIs';
import {
DEBUG_WORKSPACE_START,
USE_DEFAULT_DEVFILE,
} from '../../../../services/helpers/factoryFlow/buildFactoryParams';
applyRestartDefaultLocation,
applyRestartInDebugModeLocation,
applyRestartInSafeModeLocation,
applyStartWorkspace,
resetRestartInSafeModeLocation,
} from './prepareRestart';

export type Props = MappedProps &
ProgressStepProps & {
Expand Down Expand Up @@ -59,12 +62,9 @@ class StartingStepStartWorkspace extends ProgressStep<Props, State> {
}

public async componentDidUpdate() {
const searchParams = new URLSearchParams(this.props.history.location.search);
const safeMode = searchParams.get(USE_DEFAULT_DEVFILE) === 'true';
const safeMode = resetRestartInSafeModeLocation(this.props.history.location);
if (safeMode) {
this.setState({ shouldUpdateWithDefaultDevfile: safeMode });
searchParams.delete(USE_DEFAULT_DEVFILE);
this.props.history.location.search = searchParams.toString();
return;
}

Expand Down Expand Up @@ -130,38 +130,7 @@ class StartingStepStartWorkspace extends ProgressStep<Props, State> {
this.prepareAndRun();
}

protected handleRestartInSafeMode(alertKey: string, tab: LoaderTab): void {
const searchParams = new URLSearchParams(this.props.history.location.search);
searchParams.set(USE_DEFAULT_DEVFILE, 'true');
searchParams.delete(DEBUG_WORKSPACE_START);
this.props.history.location.search = searchParams.toString();

this.props.onHideError(alertKey);

this.setState({ shouldStart: true });
this.clearStepError();
this.props.onRestart(tab);
}

protected handleRestartInDebugMode(alertKey: string, tab: LoaderTab): void {
const searchParams = new URLSearchParams(this.props.history.location.search);
searchParams.set(DEBUG_WORKSPACE_START, 'true');
searchParams.delete(USE_DEFAULT_DEVFILE);
this.props.history.location.search = searchParams.toString();

this.props.onHideError(alertKey);

this.setState({ shouldStart: true });
this.clearStepError();
this.props.onRestart(tab);
}

protected handleRestart(alertKey: string, tab: LoaderTab): void {
const searchParams = new URLSearchParams(this.props.history.location.search);
searchParams.delete(DEBUG_WORKSPACE_START);
searchParams.delete(USE_DEFAULT_DEVFILE);
this.props.history.location.search = searchParams.toString();

this.props.onHideError(alertKey);

this.setState({ shouldStart: true });
Expand Down Expand Up @@ -226,14 +195,7 @@ class StartingStepStartWorkspace extends ProgressStep<Props, State> {
this.state.shouldStart &&
workspaceStatusIs(workspace, DevWorkspaceStatus.STOPPED, DevWorkspaceStatus.FAILED)
) {
const searchParams = new URLSearchParams(this.props.history.location.search);
const params =
searchParams.get(DEBUG_WORKSPACE_START) === 'true'
? {
'debug-workspace-start': true,
}
: undefined;
await this.props.startWorkspace(workspace, params);
await applyStartWorkspace(this.props.startWorkspace, workspace, this.props.history.location);
}

// do not switch to the next step
Expand All @@ -257,15 +219,24 @@ class StartingStepStartWorkspace extends ProgressStep<Props, State> {
actionCallbacks: [
{
title: 'Restart',
callback: () => this.handleRestart(key, LoaderTab.Progress),
callback: () => {
applyRestartDefaultLocation(this.props.history.location);
this.handleRestart(key, LoaderTab.Progress);
},
},
{
title: 'Restart in Safe mode',
callback: () => this.handleRestartInSafeMode(key, LoaderTab.Progress),
callback: () => {
applyRestartInSafeModeLocation(this.props.history.location);
this.handleRestart(key, LoaderTab.Progress);
},
},
{
title: 'Restart in Debug mode',
callback: () => this.handleRestartInDebugMode(key, LoaderTab.Logs),
callback: () => {
applyRestartInDebugModeLocation(this.props.history.location);
this.handleRestart(key, LoaderTab.Logs);
},
},
],
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* 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 { Location } from 'history';
import {
DEBUG_WORKSPACE_START,
USE_DEFAULT_DEVFILE,
} from '../../../../services/helpers/factoryFlow/buildFactoryParams';
import { Workspace } from '../../../../services/workspace-adapter';
import { ResourceQueryParams } from '../../../../store/Workspaces';

export function applyRestartDefaultLocation(location: Location): void {
const searchParams = new URLSearchParams(location.search);
searchParams.delete(DEBUG_WORKSPACE_START);
searchParams.delete(USE_DEFAULT_DEVFILE);
location.search = searchParams.toString();
}

export function applyRestartInDebugModeLocation(location: Location): void {
const searchParams = new URLSearchParams(location.search);
searchParams.set(DEBUG_WORKSPACE_START, 'true');
searchParams.delete(USE_DEFAULT_DEVFILE);
location.search = searchParams.toString();
}

export function applyRestartInSafeModeLocation(location: Location): void {
const searchParams = new URLSearchParams(location.search);
searchParams.set(USE_DEFAULT_DEVFILE, 'true');
searchParams.delete(DEBUG_WORKSPACE_START);
location.search = searchParams.toString();
}

export function resetRestartInSafeModeLocation(location: Location): boolean {
const searchParams = new URLSearchParams(location.search);
const safeMode = searchParams.get(USE_DEFAULT_DEVFILE) === 'true';
if (safeMode) {
searchParams.delete(USE_DEFAULT_DEVFILE);
location.search = searchParams.toString();
}
return safeMode;
}

export async function applyStartWorkspace(
startCallback: (workspace: Workspace, params?: ResourceQueryParams | undefined) => Promise<void>,
workspace: Workspace,
location: Location,
): Promise<void> {
const searchParams = new URLSearchParams(location.search);
const params =
searchParams.get(DEBUG_WORKSPACE_START) === 'true'
? {
'debug-workspace-start': true,
}
: undefined;
await startCallback(workspace, params);
}
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,9 @@ export const actionCreators: ActionCreators = {
openVSXUrl,
clusterConsole,
);
if (!devWorkspaceResource.metadata.annotations) {
devWorkspaceResource.metadata.annotations = {};
}
devWorkspaceResource.spec.contributions = workspace.spec.contributions;

// add projects from the origin workspace
Expand All @@ -669,10 +672,10 @@ export const actionCreators: ActionCreators = {
if (devWorkspaceTemplateResource === undefined) {
throw new Error('Failed to find a DevWorkspaceTemplate in the fetched resources.');
}
if (editorYamlUrl && devWorkspaceTemplateResource.metadata) {
if (!devWorkspaceTemplateResource.metadata.annotations) {
devWorkspaceTemplateResource.metadata.annotations = {};
}
if (!devWorkspaceTemplateResource.metadata.annotations) {
devWorkspaceTemplateResource.metadata.annotations = {};
}
if (editorYamlUrl) {
devWorkspaceTemplateResource.metadata.annotations[COMPONENT_UPDATE_POLICY] = 'managed';
devWorkspaceTemplateResource.metadata.annotations[REGISTRY_URL] = editorYamlUrl;
}
Expand Down Expand Up @@ -721,9 +724,9 @@ export const actionCreators: ActionCreators = {
await DwtApi.patchTemplate(templateNamespace, templateName, targetTemplatePatch);

const targetWorkspacePatch: api.IPatch[] = [];
devWorkspaceResource.metadata.annotations![DEVWORKSPACE_UPDATING_TIMESTAMP_ANNOTATION] =
devWorkspaceResource.metadata.annotations[DEVWORKSPACE_UPDATING_TIMESTAMP_ANNOTATION] =
new Date().toISOString();
devWorkspaceResource.metadata.annotations![DEVWORKSPACE_CHE_EDITOR] = defaultsEditor;
devWorkspaceResource.metadata.annotations[DEVWORKSPACE_CHE_EDITOR] = defaultsEditor;
if (workspace.metadata.annotations) {
targetWorkspacePatch.push({
op: 'replace',
Expand Down

0 comments on commit 90f9794

Please sign in to comment.