Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix load-factory redirection in case of policies.create='peruser' #14836

Merged
merged 1 commit into from
Oct 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 82 additions & 38 deletions dashboard/src/app/factories/load-factory/load-factory.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@
*/
'use strict';
import {CheAPI} from '../../../components/api/che-api.factory';
import {CheWorkspace} from '../../../components/api/workspace/che-workspace.factory';
import {CheWorkspace, WorkspaceStatus} from '../../../components/api/workspace/che-workspace.factory';
import {LoadFactoryService, FactoryLoadingStep} from './load-factory.service';
import {CheNotification} from '../../../components/notification/che-notification.factory';
import {RouteHistory} from '../../../components/routing/route-history.service';
import {CheJsonRpcApi} from '../../../components/api/json-rpc/che-json-rpc-api.factory';
import {CheJsonRpcMasterApi} from '../../../components/api/json-rpc/che-json-rpc-master-api';

const STARTING = WorkspaceStatus[WorkspaceStatus.STARTING];
const RUNNING = WorkspaceStatus[WorkspaceStatus.RUNNING];

const WS_AGENT_STEP: number = 4;

/**
Expand All @@ -29,7 +32,7 @@ export class LoadFactoryController {
static $inject = ['cheAPI', 'cheWorkspace','cheJsonRpcApi', '$route', '$timeout', '$mdDialog', 'loadFactoryService', 'lodash', 'cheNotification', '$location', 'routeHistory', '$window', 'loadFactoryService'];

private cheAPI: CheAPI;
cheWorkspace: CheWorkspace;
private cheWorkspace: CheWorkspace;
private $timeout: ng.ITimeoutService;
private $mdDialog: ng.material.IDialogService;
private loadFactoryService: LoadFactoryService;
Expand Down Expand Up @@ -242,9 +245,34 @@ export class LoadFactoryController {
case 'peruser' :
workspace = this.lodash.find(this.workspaces, (w: che.IWorkspace) => {
if (this.factory.id) {
return this.factory.id === (w.attributes as any).factoryId;
} else if (this.routeParams.url){
return this.routeParams.url === (w.attributes as any).factoryurl;
return this.factory.id === w.attributes.factoryId;
} else if (this.routeParams.url) {
const factoryUrl = w.attributes.factoryurl;
// compare factory URL and route params
if (angular.isDefined(factoryUrl)) {
const factoryUrlObj = new (window as any).URL(factoryUrl);
const isPathCorrect = `${factoryUrlObj.origin}${factoryUrlObj.pathname}` === this.routeParams.url;
if (isPathCorrect === false) {
return false;
}

let factoryUrlParamsNumber = 0;
let hasExtraKey = false;
for (const [key, value] of factoryUrlObj.searchParams) {
if (hasExtraKey) {
return false;
}
factoryUrlParamsNumber++;
hasExtraKey = this.routeParams[key] !== value;
}
if (hasExtraKey) {
return false;
}

// `routeParams` contains the `url` param which is not in `factoryUrl`
const paramsNumber = Object.keys(this.routeParams).length - 1;
return factoryUrlParamsNumber === paramsNumber;
}
}
return false;
});
Expand Down Expand Up @@ -296,8 +324,18 @@ export class LoadFactoryController {
creationPromise = this.cheAPI.getWorkspace().createWorkspaceFromConfig(null, config, attrs);
} else if (this.factory.devfile) {
let devfile = this.factory.devfile;
// set devfile attribute:
let attrs = {factoryurl: this.routeParams.url};
// set devfile attributes
let url = '';
let params = '';
for (const key in this.routeParams) {
if (key === 'url') {
url = this.routeParams[key];
} else {
params += `${!params ? '?' : '&'}${key}=${this.routeParams[key]}`;
}
}

const attrs = {factoryurl: `${url}${params}`};
creationPromise = this.cheAPI.getWorkspace().createWorkspaceFromDevfile(null, devfile, attrs);
}
creationPromise.then((data: any) => {
Expand Down Expand Up @@ -342,10 +380,14 @@ export class LoadFactoryController {
startWorkspace(workspace: che.IWorkspace): void {
this.workspace = workspace;

if (workspace.status === 'RUNNING') {
this.loadFactoryService.setCurrentProgressStep(4);
this.importProjects();
return;
if (workspace.status === RUNNING) {
if(workspace.config && workspace.config.projects) {
this.loadFactoryService.setCurrentProgressStep(4);
this.importProjects();
} else {
this.finish();
}
return;
}

this.subscribeOnEvents(workspace);
Expand All @@ -361,31 +403,34 @@ export class LoadFactoryController {
* @param workspace
*/
doStartWorkspace(workspace: che.IWorkspace): void {
let startWorkspacePromise = this.cheAPI.getWorkspace().startWorkspace(workspace.id);
this.loadFactoryService.goToNextStep();
this.cheAPI.getWorkspace().fetchWorkspaceDetails(workspace.id).then(() => {
const workspaceStatus = this.cheAPI.getWorkspace().getWorkspacesById().get(workspace.id).status;
if ((workspaceStatus !== RUNNING) && (workspaceStatus !== STARTING)) {
this.cheAPI.getWorkspace().startWorkspace(workspace.id).then((data: any) => {
console.log('Workspace started', data);
}, (error: any) => {
let errorMessage;

if (!error || !error.data) {
errorMessage = 'This factory is unable to start a new workspace.';
} else if (error.data.errorCode === 10000 && error.data.attributes) {
let attributes = error.data.attributes;

errorMessage = 'This factory is unable to start a new workspace.' +
' Your running workspaces are consuming ' +
attributes.used_ram + attributes.ram_unit + ' RAM.' +
' Your current RAM limit is ' + attributes.limit_ram + attributes.ram_unit +
'. This factory requested an additional ' +
attributes.required_ram + attributes.ram_unit + '.' +
' You can stop other workspaces to free resources.';
} else {
errorMessage = error.data.message;
}

startWorkspacePromise.then((data: any) => {
console.log('Workspace started', data);
}, (error: any) => {
let errorMessage;

if (!error || !error.data) {
errorMessage = 'This factory is unable to start a new workspace.';
} else if (error.data.errorCode === 10000 && error.data.attributes) {
let attributes = error.data.attributes;

errorMessage = 'This factory is unable to start a new workspace.' +
' Your running workspaces are consuming ' +
attributes.used_ram + attributes.ram_unit + ' RAM.' +
' Your current RAM limit is ' + attributes.limit_ram + attributes.ram_unit +
'. This factory requested an additional ' +
attributes.required_ram + attributes.ram_unit + '.' +
' You can stop other workspaces to free resources.';
} else {
errorMessage = error.data.message;
this.handleError({data: {message: errorMessage}});
});
}

this.handleError({data: {message: errorMessage}});
this.loadFactoryService.goToNextStep();
});
}

Expand Down Expand Up @@ -422,7 +467,6 @@ export class LoadFactoryController {
this.jsonRpcMasterApi.subscribeEnvironmentStatus(workspaceId, environmentStatusHandler);

let environmentOutputHandler = (message: any) => {
// skip displaying machine logs after workspace agent:
if (this.loadFactoryService.getCurrentProgressStep() === WS_AGENT_STEP) {
return;
}
Expand All @@ -449,7 +493,7 @@ export class LoadFactoryController {
this.getLoadingSteps()[this.getCurrentProgressStep()].hasError = true;
}

if (message.status === 'RUNNING' && message.workspaceId === workspaceId) {
if (message.status === RUNNING && message.workspaceId === workspaceId) {
this.finish();
}
};
Expand Down Expand Up @@ -597,8 +641,8 @@ export class LoadFactoryController {
// people should go back to the dashboard after factory is initialized
this.routeHistory.pushPath('/');

var ideParams = [];
if (this.routeParams) {
const ideParams = [];
if (this.routeParams && this.workspace.devfile) {
if (this.routeParams.id || (this.routeParams.name && this.routeParams.user)) {
ideParams.push('factory-id:' + this.factory.id);
} else {
Expand Down
4 changes: 2 additions & 2 deletions dashboard/src/app/factories/load-factory/load-factory.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
<che-steps-container class="load-factory-working-log"
che-all-steps="loadFactoryController.getLoadingSteps()"
che-current-step="loadFactoryController.getCurrentProgressStep()">
<che-description ng-hide="loadFactoryController.isSupportedVersion()" class="load-factory-warning-info">
This factory is using old workspace definition format which is not compatible anymore.
<che-description ng-show="loadFactoryController.factory && !loadFactoryController.isSupportedVersion()===true" class="load-factory-warning-info">
This factory is using old workspace definition format which is not compatible anymore.
Please follow the <a ng-href="{{branding.docs.workspace}}" target="_blank">documentation</a> to update the definition of the workspace and benefits from the latest capabilities.
</che-description>
</che-steps-container>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ export class CreateWorkspaceController {
* Hide progress loader if <code>true</code>.
*/
private hideLoader: boolean;

private stackName: string;

/**
* Default constructor that is using resource injection
*/
Expand Down Expand Up @@ -304,7 +307,7 @@ export class CreateWorkspaceController {
// update workspace name
let devfileSource = angular.copy(this.selectedDevfile);
devfileSource.metadata.name = this.workspaceName;
return this.createWorkspaceSvc.createWorkspaceFromDevfile(devfileSource, null);
return this.createWorkspaceSvc.createWorkspaceFromDevfile(devfileSource, {stackName: this.stackName});
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@

<che-label-container che-label-name="Select Stack"
che-label-description="Choose your workspace runtime environment used to build and run your projects.">
<devfile-selector on-devfile-select="createWorkspaceController.onDevfileSelected(devfile)">
<devfile-selector on-devfile-select="createWorkspaceController.onDevfileSelected(devfile)"
stack-name="createWorkspaceController.stackName">
</devfile-selector>
</che-label-container>
<!-- Project source selector -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export class DevfileSelectorController {
devfileOrderBy: string;
onDevfileSelect: Function;
selectedDevfile: any;
stackName: string;

/**
* Default constructor that is using resource injection
Expand Down Expand Up @@ -54,6 +55,7 @@ export class DevfileSelectorController {

devfileOnClick(devfile: any): void {
this.selectedDevfile = devfile;
this.stackName = devfile.displayName;

let location = this.cheWorkspace.getWorkspaceSettings().cheWorkspaceDevfileRegistryUrl;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export class DevfileSelector implements ng.IDirective {
*/
constructor() {
this.scope = {
devfileIdSelected: '=',
stackName: '=',
onDevfileSelect: '&'
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@
che-sort-value="listWorkspacesCtrl.workspaceOrderBy"
che-sort-item="config.name"
che-column-title="Name"></che-list-header-column>
<che-list-header-column flex-gt-xs="15"
<che-list-header-column flex-gt-xs="10"
che-sort-value="listWorkspacesCtrl.workspaceOrderBy"
che-sort-item="config.environments[0].machineConfigs[0].limits.ram"
che-column-title="RAM"></che-list-header-column>
<che-list-header-column flex-gt-xs="15"
<che-list-header-column flex-gt-xs="10"
che-sort-value="listWorkspacesCtrl.workspaceOrderBy"
che-sort-item="config.projects"
che-column-title="Projects"></che-list-header-column>
<che-list-header-column flex-gt-xs="30"
<che-list-header-column flex-gt-xs="40"
che-sort-value="listWorkspacesCtrl.workspaceOrderBy"
che-sort-item="attributes.stackId"
che-column-title="Stack"></che-list-header-column>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,27 @@ export class WorkspaceItemCtrl {
this.workspaceName = this.cheWorkspace.getWorkspaceDataManager().getName(this.workspace);
}

get stackDescription(): string {
const attributes = this.workspace.attributes;
let description = attributes.stackId ? attributes.stackId : attributes.stackName;
if (!description) {
description = attributes.factoryId ? attributes.factoryId : attributes.factoryurl;
}
return description;
}

/**
* Returns workspace projects.
*
* @returns {Array<che.IProject>}
*/
get projects(): Array<che.IProject> {
if (this.workspace.devfile) {
return this.workspace.devfile.projects || [];
}
return this.workspace.config.projects || [];
}

/**
* Returns `true` if supported.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,28 +52,32 @@
</div>

<!-- RAM -->
<div flex-gt-xs="15"
<div flex-gt-xs="10"
class="che-list-item-name workspace-item-ram"
ng-click="workspaceItemCtrl.redirectToWorkspaceDetails();">
<span class="che-xs-header noselect" hide-gt-xs>RAM</span>
<span class="workspace-consumed-value" name="workspace-ram-value">{{workspaceItemCtrl.getMemoryLimit(workspaceItemCtrl.workspace)}}</span>
</div>

<!-- Projects -->
<div flex-gt-xs="15"
<div flex-gt-xs="10"
class="che-list-item-name workspace-item-projects"
ng-click="workspaceItemCtrl.redirectToWorkspaceDetails();">
<span class="che-xs-header noselect" hide-gt-xs>Projects</span>
<span class="che-hover" name="workspace-projects-value">{{workspaceItemCtrl.workspace.config.projects.length}}
<span ng-if="workspaceItemCtrl.displayLabels"> project<span ng-if="workspaceItemCtrl.workspace.config.projects.length > 1">s</span></span></span>
<span class="che-hover" name="workspace-projects-value">
{{workspaceItemCtrl.projects.length > 0 ? workspaceItemCtrl.projects.length : '-'}}
<span ng-show="workspaceItemCtrl.displayLabels && (workspaceItemCtrl.projects.length > 0) === true">
project<span ng-if="workspaceItemCtrl.workspace.config.projects.length > 1">s</span>
</span>
</span>
</div>

<!-- Stack ID -->
<div flex-gt-xs="30"
<div flex-gt-xs="40"
class="che-list-item-name workspace-item-stack"
ng-click="workspaceItemCtrl.redirectToWorkspaceDetails();">
<span class="che-xs-header noselect" hide-gt-xs>Stack</span>
<span class="che-hover" name="workspace-stacks-name">{{workspaceItemCtrl.workspace.attributes.stackId}}</span>
<span class="che-hover" name="workspace-stacks-name">{{workspaceItemCtrl.stackDescription}}</span>
</div>

<!-- Actions -->
Expand Down
3 changes: 3 additions & 0 deletions dashboard/src/components/typings/che.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,9 @@ declare namespace che {
created: number;
updated?: number;
stackId?: string;
stackName?: string;
factoryId?: string;
factoryurl?: string;
errorMessage?: string;
[propName: string]: string | number;
}
Expand Down