Choose the editor for opening workspaces.
Early bird or night owl? Choose your side.
diff --git a/components/dashboard/src/settings/selectClass.tsx b/components/dashboard/src/settings/selectClass.tsx
index 2d3b397626c5cc..7c051da5290e51 100644
--- a/components/dashboard/src/settings/selectClass.tsx
+++ b/components/dashboard/src/settings/selectClass.tsx
@@ -37,7 +37,7 @@ export default function SelectWorkspaceClass(props: SelectWorkspaceClassProps) {
setSupportedClasses(classes);
if (!workspaceClass) {
- setWorkspaceClass(classes.find((c) => c.isSelected)?.id || "");
+ setWorkspaceClass(classes.find((c) => c.isDefault)?.id || "");
}
};
diff --git a/components/gitpod-protocol/src/teams-projects-protocol.ts b/components/gitpod-protocol/src/teams-projects-protocol.ts
index 7de2881894d47c..4dabf36e1fe751 100644
--- a/components/gitpod-protocol/src/teams-projects-protocol.ts
+++ b/components/gitpod-protocol/src/teams-projects-protocol.ts
@@ -15,7 +15,6 @@ export interface ProjectConfig {
export interface ProjectSettings {
useIncrementalPrebuilds?: boolean;
- usePersistentVolumeClaim?: boolean;
keepOutdatedPrebuildsRunning?: boolean;
// whether new workspaces can start on older prebuilds and incrementally update
allowUsingPreviousPrebuilds?: boolean;
diff --git a/components/gitpod-protocol/src/workspace-class.ts b/components/gitpod-protocol/src/workspace-class.ts
index 4d3ce713e4f2f1..3128db9da1060b 100644
--- a/components/gitpod-protocol/src/workspace-class.ts
+++ b/components/gitpod-protocol/src/workspace-class.ts
@@ -10,5 +10,5 @@ export interface SupportedWorkspaceClass {
displayName: string;
description: string;
powerups: number;
- isSelected: boolean;
+ isDefault: boolean;
}
diff --git a/components/server/src/config.ts b/components/server/src/config.ts
index 0d542d8f31b66a..bee13a32cd7fc8 100644
--- a/components/server/src/config.ts
+++ b/components/server/src/config.ts
@@ -16,7 +16,7 @@ import * as fs from "fs";
import * as yaml from "js-yaml";
import { log } from "@gitpod/gitpod-protocol/lib/util/logging";
import { filePathTelepresenceAware } from "@gitpod/gitpod-protocol/lib/env";
-import { WorkspaceClasses, WorkspaceClassesConfig } from "./workspace/workspace-classes";
+import { WorkspaceClassesConfig } from "./workspace/workspace-classes";
import { PrebuildRateLimiters } from "./workspace/prebuild-rate-limiter";
export const Config = Symbol("Config");
@@ -307,7 +307,12 @@ export namespace ConfigFile {
}
}
- WorkspaceClasses.validate(config.workspaceClasses);
+ if (config.workspaceClasses.filter((c) => c.isDefault).length !== 1) {
+ log.error(
+ "Exactly one default workspace class needs to be configured: " +
+ JSON.stringify(config.workspaceClasses),
+ );
+ }
let patSigningKey = "";
if (config.patSigningKeyFile) {
diff --git a/components/server/src/workspace/gitpod-server-impl.ts b/components/server/src/workspace/gitpod-server-impl.ts
index 513b27ae996c1d..7d70926982a80b 100644
--- a/components/server/src/workspace/gitpod-server-impl.ts
+++ b/components/server/src/workspace/gitpod-server-impl.ts
@@ -174,7 +174,6 @@ import { WorkspaceClusterImagebuilderClientProvider } from "./workspace-cluster-
import { VerificationService } from "../auth/verification-service";
import { BillingMode } from "@gitpod/gitpod-protocol/lib/billing-mode";
import { EntitlementService } from "../billing/entitlement-service";
-import { WorkspaceClasses } from "./workspace-classes";
import { formatPhoneNumber } from "../user/phone-numbers";
import { IDEService } from "../ide-service";
import { MessageBusIntegration } from "./messagebus-integration";
@@ -2947,25 +2946,15 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
}
async getSupportedWorkspaceClasses(ctx: TraceContext): Promise
{
- let user = this.checkAndBlockUser("getSupportedWorkspaceClasses");
- let selectedClass = await WorkspaceClasses.getConfiguredOrUpgradeFromLegacy(
- user,
- undefined,
- this.config.workspaceClasses,
- this.entitlementService,
- );
-
- let classes = this.config.workspaceClasses
- .filter((c) => !c.deprecated)
- .map((c) => ({
- id: c.id,
- category: c.category,
- displayName: c.displayName,
- description: c.description,
- powerups: c.powerups,
- isSelected: selectedClass === c.id,
- }));
-
+ this.checkAndBlockUser("getSupportedWorkspaceClasses");
+ const classes = this.config.workspaceClasses.map((c) => ({
+ id: c.id,
+ category: c.category,
+ displayName: c.displayName,
+ description: c.description,
+ powerups: c.powerups,
+ isDefault: c.isDefault,
+ }));
return classes;
}
diff --git a/components/server/src/workspace/workspace-classes.spec.ts b/components/server/src/workspace/workspace-classes.spec.ts
deleted file mode 100644
index 1d7e5fbd222134..00000000000000
--- a/components/server/src/workspace/workspace-classes.spec.ts
+++ /dev/null
@@ -1,91 +0,0 @@
-/**
- * Copyright (c) 2022 Gitpod GmbH. All rights reserved.
- * Licensed under the GNU Affero General Public License (AGPL).
- * See License-AGPL.txt in the project root for license information.
- */
-
-import { WorkspaceClassesConfig, WorkspaceClasses } from "./workspace-classes";
-import * as chai from "chai";
-const expect = chai.expect;
-
-let config: WorkspaceClassesConfig = [
- {
- id: "g1-standard",
- isDefault: true,
- category: "GENERAL PURPOSE",
- displayName: "Standard",
- description: "Up to 4 vCPU, 8 GB memory, 30GB storage",
- powerups: 1,
- deprecated: false,
- },
-];
-
-config.push({
- id: "g1-large",
- isDefault: false,
- category: "GENERAL PURPOSE",
- displayName: "Large",
- description: "Up to 8 vCPU, 16 GB memory, 50GB storage",
- powerups: 2,
- deprecated: false,
- marker: {
- moreResources: true,
- },
-});
-
-config.push({
- id: "g1-deprecated",
- isDefault: false,
- category: "GENERAL PURPOSE",
- displayName: "Large",
- description: "Up to 8 vCPU, 16 GB memory, 50GB storage",
- powerups: 2,
- deprecated: true,
- marker: {
- moreResources: true,
- },
-});
-
-describe("workspace-classes", function () {
- describe("can substitute", function () {
- it("classes are the same", function () {
- const classId = WorkspaceClasses.selectClassForRegular("g1-large", "g1-large", config);
- expect(classId).to.be.equal("g1-large");
- });
-
- it("prebuild has more resources, substitute has not", function () {
- const classId = WorkspaceClasses.selectClassForRegular("g1-large", "g1-standard", config);
- expect(classId).to.be.equal("g1-large");
- });
-
- it("prebuild has more resources, substitute also has more resources", function () {
- const classId = WorkspaceClasses.selectClassForRegular("g1-large", "g1-large", config);
- expect(classId).to.be.equal("g1-large");
- });
-
- it("prebuild has more resources, substitute has not, prebuild is deprecated", function () {
- const classId = WorkspaceClasses.selectClassForRegular("g1-deprecated", "g1-standard", config);
- expect(classId).to.be.equal("g1-large");
- });
-
- it("prebuild has more resources, substitute has not, prebuild not deprecated", function () {
- const classId = WorkspaceClasses.selectClassForRegular("g1-large", "g1-standard", config);
- expect(classId).to.be.equal("g1-large");
- });
-
- it("prebuild does not have more resources, return substitute", function () {
- const classId = WorkspaceClasses.selectClassForRegular("g1-standard", "g1-large", config);
- expect(classId).to.be.equal("g1-large");
- });
-
- it("prebuild does not have more resources, substitute unknown", function () {
- const classId = WorkspaceClasses.selectClassForRegular("g1-standard", "g1-unknown", config);
- expect(classId).to.be.equal("g1-standard");
- });
-
- it("substitute is not acceptable", function () {
- const classId = WorkspaceClasses.selectClassForRegular("g1-large", "g1-standard", config);
- expect(classId).to.be.equal("g1-large");
- });
- });
-});
diff --git a/components/server/src/workspace/workspace-classes.ts b/components/server/src/workspace/workspace-classes.ts
index 685f94123dcdd9..ad00998a890294 100644
--- a/components/server/src/workspace/workspace-classes.ts
+++ b/components/server/src/workspace/workspace-classes.ts
@@ -4,12 +4,6 @@
* See License-AGPL.txt in the project root for license information.
*/
-import { WorkspaceDB } from "@gitpod/gitpod-db/lib";
-import { Project, User, Workspace } from "@gitpod/gitpod-protocol";
-import { log } from "@gitpod/gitpod-protocol/lib/util/logging";
-import { TraceContext } from "@gitpod/gitpod-protocol/lib/util/tracing";
-import { EntitlementService } from "../billing/entitlement-service";
-
export type WorkspaceClassesConfig = [WorkspaceClassConfig];
export interface WorkspaceClassConfig {
@@ -31,191 +25,9 @@ export interface WorkspaceClassConfig {
// The "power level" of the workspace class
powerups: number;
- // Whether or not to:
- // - offer users this Workspace class for selection
- // - use this class to start workspaces with. If a user has a class marked like this configured and starts a workspace they get the default class instead.
- deprecated: boolean;
-
// Marks this class to have special semantics
marker?: {
// Marks this class as the one that users marked with "GetMoreResources" receive
moreResources: boolean;
};
}
-
-export namespace WorkspaceClasses {
- /**
- * @param workspaceClasses
- * @return The WorkspaceClass ID of the first class that is marked with "moreResources" (and not deprecated). Falls back to "getDefaultId()".
- */
- export function getMoreResourcesIdOrDefault(workspaceClasses: WorkspaceClassesConfig): string {
- const moreResources = workspaceClasses.filter((c) => !c.deprecated).find((c) => !!c.marker?.moreResources);
- if (moreResources) {
- return moreResources.id;
- }
-
- // fallback: default
- return getDefaultId(workspaceClasses);
- }
-
- /**
- * @param workspaceClasses
- * @return The WorkspaceClass ID of the "default" class
- */
- export function getDefaultId(workspaceClasses: WorkspaceClassesConfig): string {
- validate(workspaceClasses);
-
- return workspaceClasses.filter((c) => !c.deprecated).find((c) => c.isDefault)!.id;
- }
-
- /**
- * Checks that the given workspaceClass is:
- * - still configured
- * - not deprecated
- * If any of that is the case, it returns the default class
- *
- * @param workspaceClasses
- * @param previousWorkspaceClass
- */
- export function getPreviousOrDefault(
- workspaceClasses: WorkspaceClassesConfig,
- previousWorkspaceClass: string | undefined,
- ): string {
- if (!previousWorkspaceClass) {
- return getDefaultId(workspaceClasses);
- }
-
- // todo: remove this once pvc has been rolled out
- if (previousWorkspaceClass.endsWith("-pvc")) {
- return previousWorkspaceClass;
- }
-
- const config = workspaceClasses.find((c) => c.id === previousWorkspaceClass);
- if (!config) {
- log.error(
- `Found previous instance with workspace class '${previousWorkspaceClass}' which is no longer configured! Falling back to default class.`,
- { workspaceClasses },
- );
- return getDefaultId(workspaceClasses);
- }
- if (config.deprecated) {
- log.info(
- `Found previous instance with workspace class '${previousWorkspaceClass}' which is deprecated. Falling back to default class.`,
- { workspaceClasses },
- );
- return getDefaultId(workspaceClasses);
- }
- return config.id;
- }
-
- export function validate(workspaceClasses: WorkspaceClassesConfig): void {
- const defaultClasses = workspaceClasses
- .filter((c) => !c.deprecated)
- .map((c) => (c.isDefault ? 1 : 0))
- .reduce((acc: number, isDefault: number) => (acc + isDefault) as number, 0);
-
- if (defaultClasses !== 1) {
- throw new Error(
- "Exactly one default workspace class needs to be configured:" + JSON.stringify(defaultClasses),
- );
- }
- }
-
- /**
- * Gets the workspace class of the prebuild
- * If the class is not supported anymore undefined will be returned
- * @param ctx
- * @param workspace
- * @param db
- * @param classes
- */
- export async function getFromPrebuild(
- ctx: TraceContext,
- workspace: Workspace,
- db: WorkspaceDB,
- ): Promise {
- const span = TraceContext.startSpan("getFromPrebuild", ctx);
- try {
- if (!workspace.basedOnPrebuildId) {
- return undefined;
- }
-
- const prebuild = await db.findPrebuildByID(workspace.basedOnPrebuildId);
- if (!prebuild) {
- return undefined;
- }
-
- const buildWorkspaceInstance = await db.findCurrentInstance(prebuild.buildWorkspaceId);
- return buildWorkspaceInstance?.workspaceClass;
- } finally {
- span.finish();
- }
- }
-
- /**
- * @param user
- * @param classes
- * @param entitlementService
- */
- export async function getConfiguredOrUpgradeFromLegacy(
- user: User,
- project: Project | undefined,
- classes: WorkspaceClassesConfig,
- entitlementService: EntitlementService,
- ): Promise {
- if (project?.settings?.workspaceClasses?.regular) {
- return project?.settings?.workspaceClasses?.regular;
- }
- if (user.additionalData?.workspaceClasses?.regular) {
- return user.additionalData?.workspaceClasses?.regular;
- }
-
- let workspaceClass = WorkspaceClasses.getDefaultId(classes);
- if (await entitlementService.userGetsMoreResources(user)) {
- workspaceClass = WorkspaceClasses.getMoreResourcesIdOrDefault(classes);
- }
-
- return workspaceClass;
- }
-
- /**
- * @param currentClassId
- * @param substituteClassId
- * @param classes
- */
- export function selectClassForRegular(
- currentClassId: string,
- substituteClassId: string | undefined,
- classes: WorkspaceClassesConfig,
- ): string {
- if (currentClassId === substituteClassId) {
- return currentClassId;
- }
-
- const current = classes.find((c) => c.id === currentClassId);
- let substitute = classes.find((c) => c.id === substituteClassId);
-
- // todo: remove this once pvc has been rolled out
- if (currentClassId.endsWith("-pvc")) {
- return currentClassId;
- }
-
- if (current?.marker?.moreResources) {
- if (substitute?.marker?.moreResources) {
- return substitute?.id;
- } else {
- if (current.deprecated) {
- return getMoreResourcesIdOrDefault(classes);
- } else {
- return current.id;
- }
- }
- } else {
- if (substitute?.id) {
- return substitute.id;
- } else {
- return getDefaultId(classes);
- }
- }
- }
-}
diff --git a/components/server/src/workspace/workspace-starter.spec.ts b/components/server/src/workspace/workspace-starter.spec.ts
index 5226cc48600d6c..12fd1b290361ae 100644
--- a/components/server/src/workspace/workspace-starter.spec.ts
+++ b/components/server/src/workspace/workspace-starter.spec.ts
@@ -4,17 +4,10 @@
* See License-AGPL.txt in the project root for license information.
*/
-import { DBWithTracing, MaybeWorkspaceInstance, WorkspaceDB } from "@gitpod/gitpod-db/lib";
-import { WorkspaceClassesConfig } from "./workspace-classes";
-import { PrebuiltWorkspace, User, Workspace, WorkspaceInstance, WorkspaceType } from "@gitpod/gitpod-protocol";
+import { User } from "@gitpod/gitpod-protocol";
import { IDEOption, IDEOptions } from "@gitpod/gitpod-protocol/lib/ide-protocol";
import * as chai from "chai";
-import { migrationIDESettings, chooseIDE, getWorkspaceClassForInstance } from "./workspace-starter";
-import { MockTracer } from "opentracing";
-import { CustomTracerOpts, TraceContext, TracingManager } from "@gitpod/gitpod-protocol/lib/util/tracing";
-import { JaegerTracer } from "jaeger-client";
-import { EntitlementService } from "../billing/entitlement-service";
-import { EntitlementServiceChargebee } from "../../ee/src/billing/entitlement-service-chargebee";
+import { migrationIDESettings, chooseIDE } from "./workspace-starter";
const expect = chai.expect;
describe("workspace-starter", function () {
@@ -271,242 +264,4 @@ describe("workspace-starter", function () {
expect(result.ideImage).to.equal(ideOptions.options["code"].latestImage);
});
});
- describe("selectWorkspaceClass", function () {
- it("new regular workspace, without prebuild, regular class configured", async function () {
- const builder = new WorkspaceClassTestBuilder("regular").withRegularClassConfigured("g1-standard");
- await execute(builder, "g1-standard");
- });
- it("new regular workspace, without prebuild, class not configured, has more resources", async function () {
- const builder = new WorkspaceClassTestBuilder("regular").withHasMoreResources();
- await execute(builder, "g1-large");
- });
-
- it("new regular workspace, without prebuild, class not configured, does not have more resources", async function () {
- const builder = new WorkspaceClassTestBuilder("regular");
- await execute(builder, "g1-standard");
- });
-
- it("restarted workspace", async function () {
- const builder = new WorkspaceClassTestBuilder("regular").withPreviousInstance("g1-large");
- await execute(builder, "g1-large");
- });
-
- it("restarted workspace, class does not exist, fallback to default class", async function () {
- const builder = new WorkspaceClassTestBuilder("regular").withPreviousInstance("g1-unknown");
- await execute(builder, "g1-standard");
- });
-
- it("restarted workspace, class is deprecated, fallback to default class", async function () {
- const builder = new WorkspaceClassTestBuilder("regular").withPreviousInstance("g1-deprecated");
- await execute(builder, "g1-standard");
- });
-
- it("new prebuild workspace, prebuild class configured", async function () {
- const builder = new WorkspaceClassTestBuilder("prebuild").withPrebuildClassConfigured("g1-large");
- await execute(builder, "g1-large");
- });
-
- it("new prebuild workspace, prebuild class not configured, has more resources", async function () {
- const builder = new WorkspaceClassTestBuilder("prebuild").withHasMoreResources();
- await execute(builder, "g1-large");
- });
-
- it("new prebuild workspace, prebuild class not configured, does not have more resources", async function () {
- const builder = new WorkspaceClassTestBuilder("prebuild");
- await execute(builder, "g1-standard");
- });
- });
});
-
-async function execute(builder: WorkspaceClassTestBuilder, expectedClass: string) {
- let [ctx, workspace, previousInstance, user, entitlementService, config, workspaceDb] = builder.build();
-
- let actualClass = await getWorkspaceClassForInstance(
- ctx,
- workspace,
- previousInstance,
- user,
- undefined,
- entitlementService,
- config,
- workspaceDb,
- );
- expect(actualClass).to.equal(expectedClass);
-}
-
-class WorkspaceClassTestBuilder {
- // Type of the workspace that is being created e.g. regular or prebuild
- workspaceType: WorkspaceType;
-
- // The workspace class of the previous instance of the workspace
- previousInstanceClass: string;
-
- // The class configured by the user for a regular workspace
- configuredRegularClass: string;
-
- // The class configured by the user for a prebuild workspace
- configuredPrebuildClass: string;
-
- // Workspace is based on a prebuild
- basedOnPrebuild: string;
-
- // User has more resources
- hasMoreResources: boolean;
-
- constructor(workspaceType: WorkspaceType) {
- this.workspaceType = workspaceType;
- }
-
- public withPreviousInstance(classId: string): WorkspaceClassTestBuilder {
- this.previousInstanceClass = classId;
- return this;
- }
-
- public withPrebuild(): WorkspaceClassTestBuilder {
- this.basedOnPrebuild = "0kaks09j";
- return this;
- }
-
- public withRegularClassConfigured(classId: string): WorkspaceClassTestBuilder {
- this.configuredRegularClass = classId;
- return this;
- }
-
- public withPrebuildClassConfigured(classId: string): WorkspaceClassTestBuilder {
- this.configuredPrebuildClass = classId;
- return this;
- }
-
- public withHasMoreResources(): WorkspaceClassTestBuilder {
- this.hasMoreResources = true;
- return this;
- }
-
- public build(): [
- TraceContext,
- Workspace,
- WorkspaceInstance,
- User,
- EntitlementService,
- WorkspaceClassesConfig,
- DBWithTracing,
- ] {
- const tracer = new MockTracer();
- const span = tracer.startSpan("testspan");
- const ctx = {
- span,
- };
-
- const workspace: Workspace = {
- basedOnPrebuildId: this.basedOnPrebuild,
- type: this.workspaceType,
- } as Workspace;
-
- const previousInstance: WorkspaceInstance = {
- workspaceClass: this.previousInstanceClass,
- } as WorkspaceInstance;
-
- let user: User = {
- id: "string",
- creationDate: "string",
- identities: [],
- additionalData: {
- workspaceClasses: {
- regular: this.configuredRegularClass,
- prebuild: this.configuredPrebuildClass,
- },
- },
- };
-
- const entitlementService: EntitlementService = new MockEntitlementService(this.hasMoreResources);
-
- let config: WorkspaceClassesConfig = [
- {
- id: "g1-standard",
- isDefault: true,
- category: "GENERAL PURPOSE",
- displayName: "Standard",
- description: "Up to 4 vCPU, 8 GB memory, 30GB storage",
- powerups: 1,
- deprecated: false,
- },
- ];
-
- config.push({
- id: "g1-large",
- isDefault: false,
- category: "GENERAL PURPOSE",
- displayName: "Large",
- description: "Up to 8 vCPU, 16 GB memory, 50GB storage",
- powerups: 2,
- deprecated: false,
- marker: {
- moreResources: this.hasMoreResources,
- },
- });
-
- config.push({
- id: "g1-deprecated",
- isDefault: false,
- category: "GENERAL PURPOSE",
- displayName: "Large",
- description: "Up to 8 vCPU, 16 GB memory, 50GB storage",
- powerups: 2,
- deprecated: true,
- });
-
- const workspaceDb = new MockWorkspaceDb(!!this.basedOnPrebuild);
- const workspaceDbWithTracing: DBWithTracing = new DBWithTracing(
- workspaceDb,
- new MockTracingManager(),
- );
-
- return [ctx, workspace, previousInstance, user, entitlementService, config, workspaceDbWithTracing];
- }
-}
-
-class MockEntitlementService extends EntitlementServiceChargebee {
- constructor(protected hasMoreResources: boolean) {
- super();
- }
-
- userGetsMoreResources(user: User): Promise {
- return new Promise((resolve) => {
- resolve(this.hasMoreResources);
- });
- }
-}
-
-class MockWorkspaceDb {
- constructor(protected hasPrebuild: boolean) {}
-
- findPrebuildByID(pwsid: string): Promise {
- return new Promise((resolve) => {
- if (this.hasPrebuild) {
- resolve({
- buildWorkspaceId: "string",
- } as PrebuiltWorkspace);
- } else {
- resolve(undefined);
- }
- });
- }
-
- findCurrentInstance(workspaceId: string): Promise {
- return new Promise((resolve) => {
- if (this.hasPrebuild) {
- resolve({
- id: "string",
- } as MaybeWorkspaceInstance);
- } else {
- resolve(undefined);
- }
- });
- }
-}
-
-class MockTracingManager extends TracingManager {
- getTracerForService(serviceName: string, opts?: CustomTracerOpts | undefined): JaegerTracer {
- return {} as JaegerTracer;
- }
-}
diff --git a/components/server/src/workspace/workspace-starter.ts b/components/server/src/workspace/workspace-starter.ts
index 2be9fc14e1765b..ee5355a3b30c58 100644
--- a/components/server/src/workspace/workspace-starter.ts
+++ b/components/server/src/workspace/workspace-starter.ts
@@ -121,11 +121,10 @@ import {
import { ContextParser } from "./context-parser-service";
import { WorkspaceClusterImagebuilderClientProvider } from "./workspace-cluster-imagebuilder-client-provider";
import { getExperimentsClientForBackend } from "@gitpod/gitpod-protocol/lib/experiments/configcat-server";
-import { WorkspaceClasses, WorkspaceClassesConfig } from "./workspace-classes";
+import { WorkspaceClassesConfig } from "./workspace-classes";
import { EntitlementService } from "../billing/entitlement-service";
import { BillingModes } from "../../ee/src/billing/billing-mode";
import { AttributionId } from "@gitpod/gitpod-protocol/lib/attribution";
-import { BillingMode } from "@gitpod/gitpod-protocol/lib/billing-mode";
import { LogContext } from "@gitpod/gitpod-protocol/lib/util/logging";
import { repeat } from "@gitpod/gitpod-protocol/lib/util/repeat";
@@ -203,51 +202,29 @@ export const chooseIDE = (
export async function getWorkspaceClassForInstance(
ctx: TraceContext,
workspace: Workspace,
- previousInstance: WorkspaceInstance | undefined,
user: User,
project: Project | undefined,
entitlementService: EntitlementService,
config: WorkspaceClassesConfig,
- workspaceDb: DBWithTracing,
): Promise {
const span = TraceContext.startSpan("getWorkspaceClassForInstance", ctx);
try {
- let workspaceClass = "";
- if (!previousInstance?.workspaceClass) {
- if (workspace.type == "regular") {
- const prebuildClass = await WorkspaceClasses.getFromPrebuild(ctx, workspace, workspaceDb.trace(ctx));
- if (prebuildClass) {
- const userClass = await WorkspaceClasses.getConfiguredOrUpgradeFromLegacy(
- user,
- project,
- config,
- entitlementService,
- );
- workspaceClass = WorkspaceClasses.selectClassForRegular(prebuildClass, userClass, config);
- } else if (project?.settings?.workspaceClasses?.regular) {
- workspaceClass = project?.settings?.workspaceClasses?.regular;
- } else if (user.additionalData?.workspaceClasses?.regular) {
- workspaceClass = user.additionalData?.workspaceClasses?.regular;
- }
- }
-
- if (workspace.type === "prebuild") {
- if (project?.settings?.workspaceClasses?.prebuild) {
- workspaceClass = project?.settings?.workspaceClasses?.prebuild;
- }
- }
-
- if (!workspaceClass) {
- workspaceClass = WorkspaceClasses.getDefaultId(config);
- if (await entitlementService.userGetsMoreResources(user)) {
- workspaceClass = WorkspaceClasses.getMoreResourcesIdOrDefault(config);
- }
- }
- } else {
- workspaceClass = WorkspaceClasses.getPreviousOrDefault(config, previousInstance.workspaceClass);
+ let workspaceClass: string | undefined;
+ switch (workspace.type) {
+ case "prebuild":
+ workspaceClass = project?.settings?.workspaceClasses?.prebuild;
+ break;
+ case "regular":
+ workspaceClass = project?.settings?.workspaceClasses?.regular;
+ break;
}
-
- return workspaceClass;
+ if (!workspaceClass && (await entitlementService.userGetsMoreResources(user))) {
+ workspaceClass = config.find((c) => !!c.marker?.moreResources)?.id;
+ }
+ if (!workspaceClass) {
+ workspaceClass = config.find((c) => !!c.isDefault)?.id;
+ }
+ return workspaceClass!;
} finally {
span.finish();
}
@@ -918,41 +895,16 @@ export class WorkspaceStarter {
await this.tryEnablePSI(featureFlags, user, billingTier);
const usageAttributionId = await this.userService.getWorkspaceUsageAttributionId(user, workspace.projectId);
- const billingMode = await this.billingModes.getBillingMode(usageAttributionId, new Date());
-
- let workspaceClass = "";
- if (BillingMode.canSetWorkspaceClass(billingMode)) {
- // this is either the first time we start the workspace or the workspace was started
- // before workspace classes and does not have a class yet
- workspaceClass = await getWorkspaceClassForInstance(
- ctx,
- workspace,
- previousInstance,
- user,
- project,
- this.entitlementService,
- this.config.workspaceClasses,
- this.workspaceDb,
- );
+ let workspaceClass = await getWorkspaceClassForInstance(
+ ctx,
+ workspace,
+ user,
+ project,
+ this.entitlementService,
+ this.config.workspaceClasses,
+ );
- featureFlags = featureFlags.concat(["workspace_class_limiting"]);
- } else {
- // todo: remove this once pvc has been rolled out
- const prebuildClass = await WorkspaceClasses.getFromPrebuild(
- ctx,
- workspace,
- this.workspaceDb.trace(ctx),
- );
- if (prebuildClass?.endsWith("-pvc")) {
- workspaceClass = prebuildClass;
- // ####
- } else {
- workspaceClass = "default";
- if (await this.entitlementService.userGetsMoreResources(user)) {
- workspaceClass = "gitpodio-internal-xl";
- }
- }
- }
+ featureFlags = featureFlags.concat(["workspace_class_limiting"]);
if (!!featureFlags) {
// only set feature flags if there actually are any. Otherwise we waste the
diff --git a/dev/preview/workflow/preview/deploy-gitpod.sh b/dev/preview/workflow/preview/deploy-gitpod.sh
index 9081a58a7a6d82..8e9d7726630d20 100755
--- a/dev/preview/workflow/preview/deploy-gitpod.sh
+++ b/dev/preview/workflow/preview/deploy-gitpod.sh
@@ -274,7 +274,6 @@ yq w -i "${INSTALLER_CONFIG_PATH}" experimental.webapp.workspaceClasses[0].displ
yq w -i "${INSTALLER_CONFIG_PATH}" experimental.webapp.workspaceClasses[0].description "Default workspace class (30GB disk)"
yq w -i "${INSTALLER_CONFIG_PATH}" experimental.webapp.workspaceClasses[0].powerups "1"
yq w -i "${INSTALLER_CONFIG_PATH}" experimental.webapp.workspaceClasses[0].isDefault "true"
-yq w -i "${INSTALLER_CONFIG_PATH}" experimental.webapp.workspaceClasses[0].deprecated "false"
yq w -i "${INSTALLER_CONFIG_PATH}" experimental.webapp.workspaceClasses[0].credits.perMinute "0.3333333333"
yq w -i "${INSTALLER_CONFIG_PATH}" experimental.webapp.workspaceClasses[+].id "small"
@@ -282,8 +281,6 @@ yq w -i "${INSTALLER_CONFIG_PATH}" experimental.webapp.workspaceClasses[1].categ
yq w -i "${INSTALLER_CONFIG_PATH}" experimental.webapp.workspaceClasses[1].displayName "Small"
yq w -i "${INSTALLER_CONFIG_PATH}" experimental.webapp.workspaceClasses[1].description "Small workspace class (20GB disk)"
yq w -i "${INSTALLER_CONFIG_PATH}" experimental.webapp.workspaceClasses[1].powerups "2"
-yq w -i "${INSTALLER_CONFIG_PATH}" experimental.webapp.workspaceClasses[1].isDefault "false"
-yq w -i "${INSTALLER_CONFIG_PATH}" experimental.webapp.workspaceClasses[1].deprecated "false"
yq w -i "${INSTALLER_CONFIG_PATH}" experimental.webapp.workspaceClasses[1].credits.perMinute "0.1666666667"
yq w -i "${INSTALLER_CONFIG_PATH}" experimental.webapp.workspaceClasses[1].marker.moreResources "true"
diff --git a/install/installer/pkg/components/server/configmap.go b/install/installer/pkg/components/server/configmap.go
index 43f70a00637286..c5670b80f65c95 100644
--- a/install/installer/pkg/components/server/configmap.go
+++ b/install/installer/pkg/components/server/configmap.go
@@ -139,7 +139,6 @@ func configmap(ctx *common.RenderContext) ([]runtime.Object, error) {
Description: "Default workspace class",
PowerUps: 1,
IsDefault: true,
- Deprecated: false,
},
}
ctx.WithExperimental(func(cfg *experimental.Config) error {
@@ -153,7 +152,6 @@ func configmap(ctx *common.RenderContext) ([]runtime.Object, error) {
Description: cl.Description,
PowerUps: cl.PowerUps,
IsDefault: cl.IsDefault,
- Deprecated: cl.Deprecated,
Marker: cl.Marker,
}
diff --git a/install/installer/pkg/components/slowserver/configmap.go b/install/installer/pkg/components/slowserver/configmap.go
index 604d13b24a3a45..37bd09e61a0431 100644
--- a/install/installer/pkg/components/slowserver/configmap.go
+++ b/install/installer/pkg/components/slowserver/configmap.go
@@ -126,7 +126,6 @@ func configmap(ctx *common.RenderContext) ([]runtime.Object, error) {
Description: "Default workspace class",
PowerUps: 1,
IsDefault: true,
- Deprecated: false,
},
}
ctx.WithExperimental(func(cfg *experimental.Config) error {
@@ -140,7 +139,6 @@ func configmap(ctx *common.RenderContext) ([]runtime.Object, error) {
Description: cl.Description,
PowerUps: cl.PowerUps,
IsDefault: cl.IsDefault,
- Deprecated: cl.Deprecated,
Marker: cl.Marker,
}