Skip to content

Commit b71f68f

Browse files
author
Christian Weichel
committed
[server] Map IDE image as part of workspace config
1 parent 7fc7fbd commit b71f68f

File tree

7 files changed

+42
-61
lines changed

7 files changed

+42
-61
lines changed

Diff for: chart/templates/server-deployment.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ spec:
125125
value: "{{ template "gitpod.comp.imageRepo" (dict "root" . "gp" $.Values "comp" .Values.components.workspace.codeImage) }}"
126126
- name: WORKSPACE_DEFAULT_IMAGE
127127
value: "{{ template "gitpod.comp.imageFull" (dict "root" . "gp" $.Values "comp" .Values.components.workspace.defaultImage) }}"
128+
- name: IDE_IMAGE_ALIASES
129+
value: {{ (dict "code" (include "gitpod.comp.imageFull" (dict "root" . "gp" $.Values "comp" .Values.components.workspace.codeImage))) | toJson | quote }}
128130
{{- if $comp.blockNewUsers }}
129131
- name: BLOCK_NEW_USERS
130132
value: {{ $comp.blockNewUsers | quote }}

Diff for: components/gitpod-protocol/src/protocol.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,7 @@ export interface WorkspaceConfig {
511511
gitConfig?: { [config: string]: string };
512512
github?: GithubAppConfig;
513513
vscode?: VSCodeConfig;
514-
ide?: 'theia' | 'code';
514+
ide?: 'theia' | 'code' | string;
515515

516516
/**
517517
* Where the config object originates from.

Diff for: components/server/src/dev/dev-data.ts

+3-32
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@
44
* See License-AGPL.txt in the project root for license information.
55
*/
66

7-
import { IssueContext, Workspace, User, PullRequestContext, Repository, Token } from "@gitpod/gitpod-protocol";
7+
import { IssueContext, User, PullRequestContext, Repository, Token } from "@gitpod/gitpod-protocol";
88
import { GitHubScope } from "../github/scopes";
99
import { GitLabScope } from "../gitlab/scopes";
10-
import { ConfigProvider } from "../workspace/config-provider";
1110
import { TokenService } from "../user/token-service";
1211

1312
export namespace DevData {
@@ -99,7 +98,7 @@ export namespace DevData {
9998
};
10099
}
101100

102-
function createPrContext(user: User): PullRequestContext {
101+
export function createPrContext(user: User): PullRequestContext {
103102
const repository: Repository = {
104103
host: 'github.com',
105104
owner: user.identities[0].authName,
@@ -119,21 +118,7 @@ export namespace DevData {
119118
}
120119
};
121120

122-
export function createTestWorkspacePR(user: User): Workspace {
123-
const config = ConfigProvider.defaultConfig()
124-
return {
125-
id: "a12-345",
126-
type: "regular",
127-
creationTime: new Date().toISOString(),
128-
contextURL: 'github.com/TypeFox/gitpod-test-repo',
129-
description: "Test Workspace, connecting to local Theia",
130-
ownerId: user.id,
131-
context: createPrContext(user),
132-
config
133-
}
134-
};
135-
136-
function createIssueContext(user: User): IssueContext {
121+
export function createIssueContext(user: User): IssueContext {
137122
const repository: Repository = {
138123
host: 'github.com',
139124
owner: user.identities[0].authName,
@@ -149,18 +134,4 @@ export namespace DevData {
149134
}
150135
};
151136

152-
export function createTestWorkspaceISSUE(user: User): Workspace {
153-
const config = ConfigProvider.defaultConfig();
154-
return {
155-
id: "a12-321",
156-
type: "regular",
157-
creationTime: new Date().toISOString(),
158-
contextURL: 'github.com/TypeFox/gitpod-test-repo',
159-
description: "Test Workspace, connecting to local Theia",
160-
ownerId: user.id,
161-
context: createIssueContext(user),
162-
config
163-
}
164-
};
165-
166137
}

Diff for: components/server/src/env.ts

+9-2
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,18 @@ export class Env extends AbstractComponentEnv {
3232
return envValue ? parseInt(envValue, 10) : 5 * this.theiaHeartbeatInterval;
3333
}
3434

35-
readonly codeImageRepo = process.env.CODE_IMAGE_REPO || 'unknown';
36-
3735
readonly theiaVersion = process.env.THEIA_VERSION || this.serverVersion;
3836
readonly theiaImageRepo = process.env.THEIA_IMAGE_REPO || 'unknown';
3937
readonly theiaMounted = process.env.THEIA_MOUNTED === "true";
38+
readonly ideDefaultImage = `${this.theiaImageRepo}:${this.theiaVersion}`;
39+
readonly workspaceDefaultImage = process.env.WORKSPACE_DEFAULT_IMAGE || "gitpod/workspace-full:latest";
40+
41+
readonly ideImageAliases: { [index: string]: string } = (() => {
42+
const envValue = process.env.IDE_IMAGE_ALIASES;
43+
let res = !!envValue ? JSON.parse(envValue) : {};
44+
res["theia"] = this.ideDefaultImage;
45+
return res;
46+
})()
4047

4148
readonly gitpodRegion: string = process.env.GITPOD_REGION || 'unknown';
4249

Diff for: components/server/src/workspace/config-inference-provider.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@
77
import { inject, injectable, postConstruct } from "inversify";
88
import { CommitContext, User, WorkspaceConfig } from "@gitpod/gitpod-protocol";
99
import { HostContextProvider } from "../auth/host-context-provider";
10-
import { ConfigProvider } from "./config-provider";
10+
import { Env } from "../env";
1111

1212
export type LanguageConfigProvider = (language: string, user: User, commit: CommitContext) => Promise<WorkspaceConfig | undefined>;
1313

1414
@injectable()
1515
export class ConfigInferenceProvider {
1616
@inject(HostContextProvider) protected readonly hostContextProvider: HostContextProvider;
17+
@inject(Env) protected readonly env: Env;
1718

1819
protected readonly languageConfigProvider = new Map<string, LanguageConfigProvider>();
1920

@@ -64,7 +65,7 @@ export class ConfigInferenceProvider {
6465
init: `test -f go.mod && go get -v ./...`
6566
}
6667
],
67-
image: ConfigProvider.DEFAULT_IMAGE
68+
image: this.env.workspaceDefaultImage
6869
} as WorkspaceConfig;
6970
}
7071

Diff for: components/server/src/workspace/config-provider.ts

+22-17
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { HostContextProvider } from "../auth/host-context-provider";
1818
import { AuthorizationService } from "../user/authorization-service";
1919
import { TheiaPluginService } from "../theia-plugin/theia-plugin-service";
2020
import { TraceContext } from "@gitpod/gitpod-protocol/lib/util/tracing";
21+
import { Env } from "../env";
2122

2223
const POD_PATH_WORKSPACE_BASE = "/workspace";
2324

@@ -35,6 +36,7 @@ export class ConfigProvider {
3536
@inject(HostContextProvider) protected readonly hostContextProvider: HostContextProvider;
3637
@inject(AuthorizationService) protected readonly authService: AuthorizationService;
3738
@inject(TheiaPluginService) protected readonly pluginService: TheiaPluginService;
39+
@inject(Env) protected readonly env: Env;
3840

3941
public async fetchConfig(ctx: TraceContext, user: User, commit: CommitContext): Promise<WorkspaceConfig> {
4042
const span = TraceContext.startSpan("fetchConfig", ctx);
@@ -93,7 +95,7 @@ export class ConfigProvider {
9395

9496
if (!customConfig) {
9597
log.debug(logContext, 'Config string undefined, using default config', { repoCloneUrl: commit.repository.cloneUrl, revision: commit.revision });
96-
const config = ConfigProvider.defaultConfig();
98+
const config = this.defaultConfig();
9799
if (!ImageConfigString.is(config.image)) {
98100
throw new Error(`Default config must contain a base image!`);
99101
}
@@ -103,7 +105,7 @@ export class ConfigProvider {
103105

104106
const config = customConfig;
105107
if (!config.image) {
106-
config.image = ConfigProvider.DEFAULT_IMAGE;
108+
config.image = this.env.workspaceDefaultImage;
107109
} else if (ImageConfigFile.is(config.image)) {
108110
let dockerfilePath = [configBasePath, config.image.file].filter(s => !!s).join('/');
109111
let repo = commit.repository;
@@ -137,6 +139,13 @@ export class ConfigProvider {
137139
config._featureFlags = workspacePersistedFlags.filter(f => (user.featureFlags!.permanentWSFeatureFlags || []).includes(f));
138140
}
139141

142+
if (!!config.ide) {
143+
const mapped = this.env.ideImageAliases[config.ide];
144+
if (!!mapped) {
145+
config.ide = mapped;
146+
}
147+
}
148+
140149
return config;
141150
} catch (e) {
142151
TraceContext.logError({span}, e);
@@ -146,6 +155,17 @@ export class ConfigProvider {
146155
}
147156
}
148157

158+
public defaultConfig(): WorkspaceConfig {
159+
return {
160+
ports: [{
161+
port: 3000
162+
}],
163+
tasks: [],
164+
ide: this.env.ideDefaultImage,
165+
image: this.env.workspaceDefaultImage
166+
};
167+
}
168+
149169
protected async fetchWorkspaceImageSourceDocker(ctx: TraceContext, repository: Repository, revisionOrTagOrBranch: string, user: User, dockerFilePath: string): Promise<Commit> {
150170
const span = TraceContext.startSpan("fetchWorkspaceImageSourceDocker", ctx);
151171
span.addTags({
@@ -279,18 +299,3 @@ export class ConfigProvider {
279299
}
280300

281301
}
282-
283-
export namespace ConfigProvider {
284-
export const DEFAULT_IMAGE = process.env.WORKSPACE_DEFAULT_IMAGE || "gitpod/workspace-full:latest";
285-
286-
export function defaultConfig(): WorkspaceConfig {
287-
return {
288-
ports: [{
289-
port: 3000
290-
}],
291-
tasks: [],
292-
image: DEFAULT_IMAGE
293-
};
294-
}
295-
296-
}

Diff for: components/server/src/workspace/workspace-starter.ts

+2-7
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import { UserService } from "../user/user-service";
2828
import { HeadlessLogEvent, HeadlessWorkspaceEventType } from "@gitpod/gitpod-protocol/lib/headless-workspace-log";
2929
import { TheiaPluginService } from "../theia-plugin/theia-plugin-service";
3030
import { OneTimeSecretServer } from "../one-time-secret-server";
31-
import { ConfigProvider } from "./config-provider";
3231

3332
@injectable()
3433
export class WorkspaceStarter {
@@ -65,7 +64,7 @@ export class WorkspaceStarter {
6564

6665
if (options.forceDefaultImage) {
6766
const req = new ResolveBaseImageRequest();
68-
req.setRef(ConfigProvider.DEFAULT_IMAGE);
67+
req.setRef(this.env.workspaceDefaultImage);
6968
const allowAll = new BuildRegistryAuthTotal();
7069
allowAll.setAllowAll(true);
7170
const auth = new BuildRegistryAuth();
@@ -534,11 +533,7 @@ export class WorkspaceStarter {
534533
spec.setGit(this.createGitSpec(workspace, user));
535534
spec.setPortsList(ports);
536535
spec.setInitializer(await initializerPromise);
537-
if (workspace.config.ide === 'code') {
538-
spec.setIdeImage(`${this.env.codeImageRepo}:${instance.configuration!.theiaVersion}`);
539-
} else {
540-
spec.setIdeImage(`${this.env.theiaImageRepo}:${instance.configuration!.theiaVersion}`);
541-
}
536+
spec.setIdeImage(workspace.config.ide || `${this.env.theiaImageRepo}:${instance.configuration!.theiaVersion}`);
542537
spec.setWorkspaceImage(instance.workspaceImage);
543538
spec.setWorkspaceLocation(workspace.config.workspaceLocation || spec.getCheckoutLocation());
544539
spec.setFeatureFlagsList(this.toWorkspaceFeatureFlags(instance.configuration!.featureFlags || []));

0 commit comments

Comments
 (0)