Skip to content
This repository has been archived by the owner on Apr 4, 2023. It is now read-only.

Commit

Permalink
feat(task-plugin): bump to devfile 2.0 API
Browse files Browse the repository at this point in the history
Change-Id: Ib64a9a1b8e4f15ffba869e79bfe7aa1aa0a87b00
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
  • Loading branch information
benoitf committed Mar 10, 2021
1 parent b8c5727 commit e10d579
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 188 deletions.
102 changes: 21 additions & 81 deletions plugins/task-plugin/src/che-workspace-client.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (c) 2019-2020 Red Hat, Inc.
* Copyright (c) 2019-2021 Red Hat, Inc.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
Expand All @@ -15,12 +15,7 @@ import { injectable } from 'inversify';

const TERMINAL_SERVER_TYPE = 'terminal';

export const RECIPE_CONTAINER_SOURCE = 'recipe';
export const CONTAINER_SOURCE_ATTRIBUTE = 'source';

export interface WorkspaceContainer extends cheApi.workspace.Machine {
name: string;
}
export interface WorkspaceContainer extends che.devfile.DevfileComponentStatus {}

@injectable()
export class CheWorkspaceClient {
Expand All @@ -30,57 +25,8 @@ export class CheWorkspaceClient {
return workspace.links;
}

/** Returns array of containers' names for the current workspace. */
async getContainersNames(): Promise<string[]> {
const containerNames: string[] = [];

try {
const containers = await this.getMachines();
for (const containerName in containers) {
if (containers.hasOwnProperty(containerName)) {
containerNames.push(containerName);
}
}
} catch (error) {
} finally {
return containerNames;
}
}

async getMachines(): Promise<{ [attrName: string]: cheApi.workspace.Machine }> {
const workspace = await this.getCurrentWorkspace();
const runtime = workspace.runtime;
if (!runtime) {
throw new Error('Workspace is not running.');
}

const machines = runtime.machines;
if (!machines) {
throw new Error('No machines for current workspace is found.');
}
return machines;
}

async getContainers(): Promise<WorkspaceContainer[]> {
const containers: WorkspaceContainer[] = [];
try {
const workspace = await this.getCurrentWorkspace();

if (workspace.runtime && workspace.runtime.machines) {
const machines = workspace.runtime.machines;
for (const machineName in machines) {
if (!machines.hasOwnProperty(machineName)) {
continue;
}
const container: WorkspaceContainer = { name: machineName, ...machines[machineName] };
containers.push(container);
}
}
} catch (e) {
throw new Error('Unable to get list workspace containers. Cause: ' + e);
}

return containers;
async getComponentStatuses(): Promise<che.devfile.DevfileComponentStatus[]> {
return che.devfile.getComponentStatuses();
}

async getCommands(): Promise<cheApi.workspace.Command[]> {
Expand All @@ -105,34 +51,28 @@ export class CheWorkspaceClient {
}

async getMachineExecServerURL(): Promise<string> {
const machineExecServer = await this.getMachineExecServer();
if (!machineExecServer) {
throw new Error(`No server with type ${TERMINAL_SERVER_TYPE} found.`);
const machineExecEndpoint = await this.getMachineExecEndpoint();
if (!machineExecEndpoint) {
throw new Error(`No endpoint with type ${TERMINAL_SERVER_TYPE} found.`);
}
if (!machineExecServer.attributes!.port) {
throw new Error('No machine-exec-server attributes.port found');
const port = machineExecEndpoint.attributes?.port || machineExecEndpoint.attributes?.targetPort;
if (!port) {
throw new Error(`No attribute port or targetPort found in endpoint ${JSON.stringify(machineExecEndpoint)}`);
}
return `ws://127.0.0.1:${machineExecServer.attributes!.port}`;
return `ws://127.0.0.1:${port}`;
}

protected async getMachineExecServer(): Promise<cheApi.workspace.Server | undefined> {
const machines = await this.getMachines();
for (const machineName in machines) {
if (!machines.hasOwnProperty(machineName)) {
continue;
}
const servers = machines[machineName].servers!;
for (const serverName in servers) {
if (!servers.hasOwnProperty(serverName)) {
continue;
}

const serverAttributes = servers[serverName].attributes;
if (serverAttributes && serverAttributes['type'] === TERMINAL_SERVER_TYPE) {
return servers[serverName];
protected async getMachineExecEndpoint(): Promise<che.devfile.DevfileComponentEndpoint | undefined> {
const devfile = await che.devfile.get();
if (devfile.components) {
devfile.components.forEach(component => {
if (component.container && component.container.endpoints) {
return Object.values(component.container.endpoints).find(
exposedEndpoint => exposedEndpoint.attributes && exposedEndpoint.attributes.type === TERMINAL_SERVER_TYPE
);
}
}
});
}
return undefined;
return;
}
}
23 changes: 5 additions & 18 deletions plugins/task-plugin/src/machine/machines-picker.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (c) 2019-2020 Red Hat, Inc.
* Copyright (c) 2019-2021 Red Hat, Inc.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
Expand All @@ -8,12 +8,7 @@
* SPDX-License-Identifier: EPL-2.0
***********************************************************************/

import {
CONTAINER_SOURCE_ATTRIBUTE,
CheWorkspaceClient,
RECIPE_CONTAINER_SOURCE,
WorkspaceContainer,
} from '../che-workspace-client';
import { CheWorkspaceClient, WorkspaceContainer } from '../che-workspace-client';
import { QuickPickItem, window } from '@theia/plugin';
import { inject, injectable } from 'inversify';

Expand Down Expand Up @@ -60,7 +55,7 @@ export class MachinesPicker {
}

private async pickContainerFromClient(): Promise<string> {
const containers = await this.cheWorkspaceClient.getContainers();
const containers = await this.cheWorkspaceClient.getComponentStatuses();

if (containers.length === 1) {
return Promise.resolve(containers[0].name);
Expand All @@ -74,8 +69,8 @@ export class MachinesPicker {
private toQuickPickItems(containers: WorkspaceContainer[]): QuickPickItem[] {
const items: QuickPickItem[] = [];

const devContainers = containers.filter(container => this.isDevContainer(container));
const toolingContainers = containers.filter(container => !this.isDevContainer(container));
const devContainers = containers.filter(container => container.isUser);
const toolingContainers = containers.filter(container => !container.isUser);

items.push(
...devContainers.map(
Expand Down Expand Up @@ -109,12 +104,4 @@ export class MachinesPicker {

return items;
}

private isDevContainer(container: WorkspaceContainer): boolean {
return (
container.attributes !== undefined &&
(!container.attributes[CONTAINER_SOURCE_ATTRIBUTE] ||
container.attributes[CONTAINER_SOURCE_ATTRIBUTE] === RECIPE_CONTAINER_SOURCE)
);
}
}
17 changes: 6 additions & 11 deletions plugins/task-plugin/src/task/backward-compatibility.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (c) 2019-2020 Red Hat, Inc.
* Copyright (c) 2019-2021 Red Hat, Inc.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
Expand All @@ -13,9 +13,7 @@ import * as che from '@eclipse-che/plugin';
import { inject, injectable } from 'inversify';

import { CHE_TASK_TYPE } from './task-protocol';
import { COMPONENT_ATTRIBUTE } from '../machine/machines-picker';
import { CheWorkspaceClient } from '../che-workspace-client';
import { getAttribute } from '../utils';

/** Contains logic to provide backward compatibility. */
@injectable()
Expand Down Expand Up @@ -61,7 +59,7 @@ export class BackwardCompatibilityResolver {
return configs;
}

const containers = await this.cheWorkspaceClient.getMachines();
const containers = await this.cheWorkspaceClient.getComponentStatuses();
for (const config of configs) {
if (config.type !== CHE_TASK_TYPE) {
continue;
Expand All @@ -76,14 +74,11 @@ export class BackwardCompatibilityResolver {
target.containerName = undefined;
target.component = '';

if (!containers.hasOwnProperty(containerName)) {
const matchingComponent = containers.find(component => component.name === containerName);
if (!matchingComponent) {
continue;
}

const container = containers[containerName];
const component = getAttribute(COMPONENT_ATTRIBUTE, container.attributes);
if (component) {
target.component = component;
} else {
target.component = matchingComponent.name;
}
}
return configs;
Expand Down
58 changes: 7 additions & 51 deletions plugins/task-plugin/src/task/che-task-provider.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (c) 2019-2020 Red Hat, Inc.
* Copyright (c) 2019-2021 Red Hat, Inc.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
Expand All @@ -11,13 +11,11 @@
import * as che from '@eclipse-che/plugin';

import { CHE_TASK_TYPE, CheTaskDefinition, Target } from './task-protocol';
import { COMPONENT_ATTRIBUTE, MachinesPicker } from '../machine/machines-picker';
import { ShellExecution, Task } from '@theia/plugin';
import { inject, injectable } from 'inversify';

import { CheWorkspaceClient } from '../che-workspace-client';
import { che as cheApi } from '@eclipse-che/api';
import { getAttribute } from '../utils';
import { MachinesPicker } from '../machine/machines-picker';

/** Reads the commands from the current Che workspace and provides it as Task Configurations. */
@injectable()
Expand Down Expand Up @@ -49,7 +47,11 @@ export class CheTaskProvider {
resultTarget.workspaceId = await this.cheWorkspaceClient.getWorkspaceId();
}

resultTarget.containerName = await this.getContainerName(target);
if (target && target.component) {
resultTarget.component = target.component;
} else {
resultTarget.component = await this.machinePicker.pick();
}

if (target && target.workingDir) {
resultTarget.workingDir = await che.variables.resolve(target.workingDir);
Expand All @@ -71,50 +73,4 @@ export class CheTaskProvider {
execution: execution,
};
}

private async getContainerName(target?: Target): Promise<string> {
if (!target) {
return this.machinePicker.pick();
}

const containers = await this.cheWorkspaceClient.getMachines();

const containerName = target.containerName;
if (containerName && containers.hasOwnProperty(containerName)) {
return containerName;
}

return (await this.getContainerNameByComponent(target.component, containers)) || this.machinePicker.pick();
}

private async getContainerNameByComponent(
targetComponent: string | undefined,
containers: { [attrName: string]: cheApi.workspace.Machine }
): Promise<string | undefined> {
if (!targetComponent) {
return undefined;
}

const names = [];
for (const containerName in containers) {
if (!containers.hasOwnProperty(containerName)) {
continue;
}

const container = containers[containerName];
const component = getAttribute(COMPONENT_ATTRIBUTE, container.attributes);
if (component && component === targetComponent) {
names.push(containerName);
}
}

if (names.length === 1) {
return names[0];
}

if (names.length > 1) {
return this.machinePicker.pick(names);
}
return undefined;
}
}
62 changes: 35 additions & 27 deletions plugins/task-plugin/src/variable/server-variable-resolver.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (c) 2019-2020 Red Hat, Inc.
* Copyright (c) 2019-2021 Red Hat, Inc.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
Expand All @@ -25,34 +25,42 @@ export class ServerVariableResolver {
protected readonly cheWorkspaceClient!: CheWorkspaceClient;

async registerVariables(): Promise<void> {
const machines = await this.cheWorkspaceClient.getMachines();
for (const machineName in machines) {
if (!machines.hasOwnProperty(machineName)) {
continue;
}

const servers = machines[machineName].servers!;

for (const serverName in servers) {
if (!servers.hasOwnProperty(serverName)) {
continue;
}

const url = servers[serverName].url;
if (url) {
const variableSubscription = await che.variables.registerVariable(this.createVariable(serverName, url));
startPoint.getSubscriptions().push(variableSubscription);
const componentStatuses = await this.cheWorkspaceClient.getComponentStatuses();
await Promise.all(
componentStatuses.map(async componentStatus => {
if (componentStatus.endpoints) {
for (const endpointName in componentStatus.endpoints) {
if (!componentStatus.endpoints.hasOwnProperty(endpointName)) {
continue;
}
const url = componentStatus.endpoints[endpointName].url;
if (url) {
const variables = this.createVariables(endpointName, url);
const variableSubscriptions = await Promise.all(
variables.map(variable => che.variables.registerVariable(variable))
);
variableSubscriptions.forEach(subscription => startPoint.getSubscriptions().push(subscription));
}
}
}
}
}
})
);
}

private createVariable(serverName: string, url: string): che.Variable {
return {
name: `server.${serverName}`,
description: url,
resolve: async () => url,
isResolved: true,
};
private createVariables(serverName: string, url: string): che.Variable[] {
return [
{
name: `server.${serverName}`,
description: url,
resolve: async () => url,
isResolved: true,
},
{
name: `endpoint.${serverName}`,
description: url,
resolve: async () => url,
isResolved: true,
},
];
}
}

0 comments on commit e10d579

Please sign in to comment.