diff --git a/components/dashboard/src/components/PrebuildLogs.tsx b/components/dashboard/src/components/PrebuildLogs.tsx index e0b1530f04fbd3..7930a18f4e1d17 100644 --- a/components/dashboard/src/components/PrebuildLogs.tsx +++ b/components/dashboard/src/components/PrebuildLogs.tsx @@ -82,8 +82,10 @@ export default function PrebuildLogs(props: PrebuildLogsProps) { useEffect(() => { switch (workspaceInstance?.status.phase) { // Preparing means that we haven't actually started the workspace instance just yet, but rather - // are still preparing for launch. This means we're building the Docker image for the workspace. + // are still preparing for launch. case "preparing": + // Building means we're building the Docker image for the workspace so the workspace hasn't started yet. + case "building": case "stopped": getGitpodService().server.watchWorkspaceImageBuildLogs(workspace!.id); break; diff --git a/components/dashboard/src/start/StartWorkspace.tsx b/components/dashboard/src/start/StartWorkspace.tsx index 940517e530ae70..0bf31ccfda946b 100644 --- a/components/dashboard/src/start/StartWorkspace.tsx +++ b/components/dashboard/src/start/StartWorkspace.tsx @@ -340,7 +340,7 @@ export default class StartWorkspace extends React.Component; // Pending means the workspace does not yet consume resources in the cluster, but rather is looking for diff --git a/components/gitpod-protocol/src/gitpod-service.ts b/components/gitpod-protocol/src/gitpod-service.ts index 5cf3454c8e1cbb..003744e21d53f8 100644 --- a/components/gitpod-protocol/src/gitpod-service.ts +++ b/components/gitpod-protocol/src/gitpod-service.ts @@ -530,13 +530,14 @@ const hasWindow = typeof window !== "undefined"; const phasesOrder: Record = { unknown: 0, preparing: 1, - pending: 2, - creating: 3, - initializing: 4, - running: 5, - interrupted: 6, - stopping: 7, - stopped: 8, + building: 2, + pending: 3, + creating: 4, + initializing: 5, + running: 6, + interrupted: 7, + stopping: 8, + stopped: 9, }; export class WorkspaceInstanceUpdateListener { private readonly onDidChangeEmitter = new Emitter(); diff --git a/components/gitpod-protocol/src/workspace-instance.ts b/components/gitpod-protocol/src/workspace-instance.ts index 3c06c0e22f2a0c..7992f656986f9a 100644 --- a/components/gitpod-protocol/src/workspace-instance.ts +++ b/components/gitpod-protocol/src/workspace-instance.ts @@ -98,9 +98,13 @@ export type WorkspaceInstancePhase = | "unknown" // Preparing means that we haven't actually started the workspace instance just yet, but rather - // are still preparing for launch. This means we're building the Docker image for the workspace. + // are still preparing for launch. | "preparing" + // Building means that we are building the Docker image for the workspace. A workspace will enter this phase only + // if an image build is required for that workspace. + | "building" + // Pending means the workspace does not yet consume resources in the cluster, but rather is looking for // some space within the cluster. If for example the cluster needs to scale up to accomodate the // workspace, the workspace will be in Pending state until that happened. diff --git a/components/ide/jetbrains/gateway-plugin/src/main/kotlin/io/gitpod/jetbrains/gateway/GitpodConnectionProvider.kt b/components/ide/jetbrains/gateway-plugin/src/main/kotlin/io/gitpod/jetbrains/gateway/GitpodConnectionProvider.kt index 063549b3f1c392..3c92e212a313a6 100644 --- a/components/ide/jetbrains/gateway-plugin/src/main/kotlin/io/gitpod/jetbrains/gateway/GitpodConnectionProvider.kt +++ b/components/ide/jetbrains/gateway-plugin/src/main/kotlin/io/gitpod/jetbrains/gateway/GitpodConnectionProvider.kt @@ -164,6 +164,10 @@ class GitpodConnectionProvider : GatewayConnectionProvider { when (update.status.phase) { "preparing" -> { phaseMessage.text = "Preparing" + statusMessage.text = "Preparing workspace..." + } + "building" -> { + phaseMessage.text = "Building" statusMessage.text = "Building workspace image..." } "pending" -> { diff --git a/components/server/src/workspace/gitpod-server-impl.ts b/components/server/src/workspace/gitpod-server-impl.ts index c68c5f2fcc8e27..027495bb95e527 100644 --- a/components/server/src/workspace/gitpod-server-impl.ts +++ b/components/server/src/workspace/gitpod-server-impl.ts @@ -1541,8 +1541,8 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable { await new Promise((resolve) => setTimeout(resolve, 2000)); const wsi = await this.workspaceDb.trace(ctx).findInstanceById(instance.id); - if (!wsi || wsi.status.phase !== "preparing") { - log.debug(logCtx, `imagebuild logs: instance is not/no longer in 'preparing' state`, { + if (!wsi || (wsi.status.phase !== "preparing" && wsi.status.phase !== "building")) { + log.debug(logCtx, `imagebuild logs: instance is not/no longer in 'building' state`, { phase: wsi?.status.phase, }); return; diff --git a/components/server/src/workspace/headless-log-service.ts b/components/server/src/workspace/headless-log-service.ts index 609ae62ba8df5d..fbd5b69d36cbd1 100644 --- a/components/server/src/workspace/headless-log-service.ts +++ b/components/server/src/workspace/headless-log-service.ts @@ -416,6 +416,7 @@ export class HeadlessLogService { function isSupervisorAvailableSoon(wsi: WorkspaceInstance): boolean { switch (wsi.status.phase) { case "creating": + case "building": case "preparing": case "initializing": case "pending": diff --git a/components/ws-manager-bridge/src/bridge.ts b/components/ws-manager-bridge/src/bridge.ts index a289b761da2008..da213e346942e0 100644 --- a/components/ws-manager-bridge/src/bridge.ts +++ b/components/ws-manager-bridge/src/bridge.ts @@ -106,7 +106,7 @@ export class WorkspaceManagerBridge implements Disposable { // Still, listen to all updates, generate/derive new state and distribute it locally! startStatusUpdateHandler(false); - // emulate WorkspaceInstance updates for all Workspaces in the "preparing" phase in this cluster + // emulate WorkspaceInstance updates for all Workspaces in the "preparing" or "building" phase in this cluster const updateEmulator = this.preparingUpdateEmulatorFactory() as PreparingUpdateEmulator; this.disposables.push(updateEmulator); updateEmulator.start(cluster.name); diff --git a/components/ws-manager-bridge/src/preparing-update-emulator.ts b/components/ws-manager-bridge/src/preparing-update-emulator.ts index e434d55ee29744..c4dda3ad14e0bd 100644 --- a/components/ws-manager-bridge/src/preparing-update-emulator.ts +++ b/components/ws-manager-bridge/src/preparing-update-emulator.ts @@ -42,7 +42,13 @@ export class PreparingUpdateEmulator implements Disposable { const span = TraceContext.startSpan("preparingUpdateEmulatorRun"); const ctx = { span }; try { - const instances = await this.workspaceDb.findInstancesByPhaseAndRegion("preparing", region); + const instances = ( + await Promise.all([ + this.workspaceDb.findInstancesByPhaseAndRegion("preparing", region), + this.workspaceDb.findInstancesByPhaseAndRegion("building", region), + ]) + ).flat(); + span.setTag("preparingUpdateEmulatorRun.nrOfInstances", instances.length); for (const instance of instances) { const hash = hasher(instance);