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

[server] Allow setting ws-class on project level #14535

Merged
merged 1 commit into from
Nov 10, 2022

Conversation

svenefftinge
Copy link
Member

@svenefftinge svenefftinge commented Nov 8, 2022

Description

Introduces a project settings to specify the workspace class.

Screenshot 2022-11-08 at 21 02 24

Related Issue(s)

Fixes #10963

How to test

Release Notes

Workspace classes can be set in the project settings

Documentation

Werft options:

  • /werft with-local-preview
    If enabled this will build install/preview
  • /werft with-preview
  • /werft with-large-vm
  • /werft with-integration-tests=all
    Valid options are all, workspace, webapp, ide

@svenefftinge svenefftinge requested a review from a team November 8, 2022 19:19
@werft-gitpod-dev-com
Copy link

started the job as gitpod-build-sefftinge-allow-specification-of-10963.1 because the annotations in the pull request description changed
(with .werft/ from main)

@roboquat roboquat added the size/M label Nov 8, 2022
@github-actions github-actions bot added the team: webapp Issue belongs to the WebApp team label Nov 8, 2022
@svenefftinge svenefftinge force-pushed the sefftinge/allow-specification-of-10963 branch from 2e8bf4a to a24635e Compare November 8, 2022 19:43
@roboquat roboquat added size/L and removed size/M labels Nov 8, 2022
@svenefftinge svenefftinge force-pushed the sefftinge/allow-specification-of-10963 branch from a24635e to 5ea3bfd Compare November 8, 2022 19:59
@svenefftinge svenefftinge force-pushed the sefftinge/allow-specification-of-10963 branch from 5ea3bfd to 8fe883a Compare November 9, 2022 07:36
@@ -8,29 +8,22 @@ import { useContext, useEffect, useState } from "react";
import { getGitpodService } from "../service/service";
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changes in this file are to extract the user-preference-specific code, making the component reusable in the project settings context.

@@ -46,8 +46,6 @@ import { ChargebeeService } from "./user/chargebee-service";
import { StripeService } from "./user/stripe-service";
import { EligibilityService } from "./user/eligibility-service";
import { AccountStatementProvider } from "./user/account-statement-provider";
import { WorkspaceStarterEE } from "./workspace/workspace-starter";
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WorkspaceStarterEE does no longer container any logic, so I deleted it and also removed the corresponding bindings.

@@ -259,7 +259,7 @@ export class PrebuildManager {
} else {
span.setTag("starting", true);
const projectEnvVars = await projectEnvVarsPromise;
await this.workspaceStarter.startWorkspace({ span }, workspace, user, [], projectEnvVars, {
await this.workspaceStarter.startWorkspace({ span }, workspace, user, project, [], projectEnvVars, {
Copy link
Member Author

@svenefftinge svenefftinge Nov 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm adding the optional project to the call graph of workspace starts in various places, so that we fetch the project once and pass it down instead of repeatedly asking the DB.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is that important in the context of this PR?
Also, triggers "premature optimization?" reflex.

❓ Would the PR still work without this change?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not only because of reducing db queries but also a principle of good software design to explicitly pass what is needed as an argument rather than fetching data internally from a global state (the DB). I.e. more functional and easier to understand when you see the signature.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also a principle of good software design to explicitly pass what is needed as an argument rather than fetching data internally from a global state (the DB)

That is a bit too vague and general for my taste to count as an argument, honestly. Then we'd need to talk service/layer boundaries first IMO, and sometimes there are good arguments against it as well.

But let's not hold up this PR any longer, I think the change is good overall. If we disagree in style we should settle that outside of PRs. 🧘

classes: WorkspaceClassesConfig,
entitlementService: EntitlementService,
): Promise<string> {
if (project?.settings?.workspaceClasses?.regular) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(1/3) use of the new project setting (precedence over user setting)

config,
entitlementService,
);
workspaceClass = WorkspaceClasses.selectClassForRegular(prebuildClass, userClass, config);
} else if (project?.settings?.workspaceClasses?.regular) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(2/3) use of the new project setting (precedence over user setting)

} else if (user.additionalData?.workspaceClasses?.regular) {
workspaceClass = user.additionalData?.workspaceClasses?.regular;
}
}

if (workspace.type == "prebuild") {
if (user.additionalData?.workspaceClasses?.prebuild) {
if (project?.settings?.workspaceClasses?.prebuild) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(3/3) use of the new project setting (precedence over user setting)

@@ -326,6 +326,7 @@ async function execute(builder: WorkspaceClassTestBuilder, expectedClass: string
workspace,
previousInstance,
user,
undefined,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should there be also a test which does pass in a Project?

@@ -2980,6 +2985,7 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
let user = this.checkAndBlockUser("getSupportedWorkspaceClasses");
let selectedClass = await WorkspaceClasses.getConfiguredOrUpgradeFromLegacy(
user,
undefined,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we not passing the project here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't have a project context

Comment on lines +722 to +724
const projectPromise = workspace.projectId
? this.projectDB.findProjectById(workspace.projectId)
: Promise.resolve(undefined);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

await syntax?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an parallelization strategy.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I'm creating a promise here and await it below, especially after the mayStartPromise which takes the longest time.

@@ -21,6 +21,8 @@ export interface ProjectSettings {
allowUsingPreviousPrebuilds?: boolean;
// how many commits in the commit history a prebuild is good (undefined and 0 means every commit is prebuilt)
prebuildEveryNthCommit?: number;
// preferred workspace classes
workspaceClasses?: WorkspaceClasses;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is bit of a smell. Why is it plural workspaceClasses when we're not passing in a list?

Currently we look to only have a single preference, could we go with a list here (which is initially only 1 item long) and allow for the "preferences" to be a list?

I can imagine wanting to specify a priority list of classes I want to use. This also facilitates gradual migration away from one WS class to another over time - by changing the priorities (ordering)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it make senses to reuse the shape and naming we already have in place. Although I agree WorkspaceClassConfig or similar would have been a better choice in the first place.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Besides that I copied the shape from user settings, I don't think it is smelly. As it represents multiple (currently two) workspace classes.

@geropl
Copy link
Member

geropl commented Nov 9, 2022

Wanted to test, but noticed the build was failing.

@gtsiolis gtsiolis self-requested a review November 9, 2022 14:40
@svenefftinge svenefftinge force-pushed the sefftinge/allow-specification-of-10963 branch from 8fe883a to 984be6b Compare November 9, 2022 16:02
@gtsiolis
Copy link
Contributor

gtsiolis commented Nov 9, 2022

Looking at this now! 👀

@svenefftinge
Copy link
Member Author

Wanted to test, but noticed the build was failing.

Fixed and deployed it

Copy link
Contributor

@gtsiolis gtsiolis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UX LGTM! Thanks for the ping[1], @svenefftinge! 🏓

Left some non-blocking comments that can be tackled separately in follow-up issues if needed.

Also, good call on moving this to the workspace settings section.

Comment on lines +164 to +168
<SelectWorkspaceClass
workspaceClass={project.settings?.workspaceClasses?.regular}
enabled={BillingMode.canSetWorkspaceClass(teamBillingMode)}
setWorkspaceClass={setWorkspaceClass}
/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thought: It's a bit confusing that preview environments contain two quite different classes from what's on Gitpod.io and the order is also reversed, but that's out of the scope of these changes, see relevant discussion (internal).

@@ -142,8 +161,12 @@ export default function () {

{showPersistentVolumeClaimUI && (
<>
<br></br>
<h3 className="mt-12">Workspaces</h3>
<SelectWorkspaceClass
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

praise: Nice component reuse! 😁

@@ -142,8 +161,12 @@ export default function () {

{showPersistentVolumeClaimUI && (
<>
<br></br>
<h3 className="mt-12">Workspaces</h3>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: What do you think of moving the workspaces settings to the top of the general project settings here now that selecting a workspace class is a bit more prominent as it affects both workspaces and prebuilds?

BEFORE AFTER
Screenshot 2022-11-09 at 6 16 05 PM Screenshot 2022-11-09 at 6 15 57 PM

@@ -142,8 +161,12 @@ export default function () {

{showPersistentVolumeClaimUI && (
<>
<br></br>
<h3 className="mt-12">Workspaces</h3>
<SelectWorkspaceClass
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thought: Feels good to see we're working towards making Teams & Projects more useful.

Comment on lines +72 to +76
<SelectWorkspaceClass
workspaceClass={user?.additionalData?.workspaceClasses?.regular}
enabled={BillingMode.canSetWorkspaceClass(userBillingMode)}
setWorkspaceClass={setWorkspaceClass}
/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: The duplicate preference in user settings and project settings now poses a question on which preference overrides which. The workspace class scope could be something worth documenting if it's unclear but the project setting should override the user setting, correct?

Settings scope for workspace classes
Your project setting overrides the user setting.

Comment on lines +72 to +76
<SelectWorkspaceClass
workspaceClass={user?.additionalData?.workspaceClasses?.regular}
enabled={BillingMode.canSetWorkspaceClass(userBillingMode)}
setWorkspaceClass={setWorkspaceClass}
/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Once this is merged, it could be worth updating the existing and soon outdated docs.

You can configure the workspace class that should be used for your workspaces in your user preferences.

Copy link
Member

@geropl geropl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested and works.

👍 For George's comment about updating our docs

@roboquat roboquat merged commit 08be419 into main Nov 10, 2022
@roboquat roboquat deleted the sefftinge/allow-specification-of-10963 branch November 10, 2022 08:45
@roboquat roboquat added deployed: webapp Meta team change is running in production deployed Change is completely running in production labels Nov 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
deployed: webapp Meta team change is running in production deployed Change is completely running in production needs visual design release-note size/L team: webapp Issue belongs to the WebApp team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow specification of workspace class in project settings
5 participants