Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/gitpod-protocol/src/workspace-instance.ts
2498 views
1
/**
2
* Copyright (c) 2020 Gitpod GmbH. All rights reserved.
3
* Licensed under the GNU Affero General Public License (AGPL).
4
* See License.AGPL.txt in the project root for license information.
5
*/
6
7
import { EnvVar, NamedWorkspaceFeatureFlag, TaskConfig } from "./protocol";
8
import { WorkspaceRegion } from "./workspace-cluster";
9
10
// WorkspaceInstance describes a part of a workspace's lifetime, specifically a single running session of it
11
export interface WorkspaceInstance {
12
// ID is the unique identifier of this instance
13
id: string;
14
15
// workspaceId is the unique identifier of the workspace this is an instance of
16
workspaceId: string;
17
18
// The time an instance has been created in the backend (before DB!)
19
creationTime: string;
20
21
// The time an instance has switched phase to 'Pending'
22
deployedTime?: string;
23
24
// The time an instance has switched phase to 'Running'
25
startedTime?: string;
26
27
// The time an instance has switched phase to 'Stopping' */
28
stoppingTime?: string;
29
30
// The time an instance has switched phase to 'Stopped' */
31
stoppedTime?: string;
32
33
// ideUrl is the URL at which the workspace is available on the internet
34
// Note: this is initially empty, filled during starting process!
35
ideUrl: string;
36
37
// region is the name of the workspace cluster this instance runs in
38
// Note: this is initially empty, filled during starting process!
39
region: string;
40
41
// workspaceImage is the name of the Docker image this instance runs
42
// Note: this is initially empty, filled during starting process!
43
workspaceImage: string;
44
45
// status is the latest status of the instance that we're aware of
46
status: WorkspaceInstanceStatus;
47
48
// repo contains information about the Git working copy inside the workspace
49
gitStatus?: WorkspaceInstanceRepoStatus;
50
51
// configuration captures the per-instance configuration variance of a workspace
52
configuration: WorkspaceInstanceConfiguration;
53
54
// instance is hard-deleted on the database and about to be collected by periodic deleter
55
readonly deleted?: boolean;
56
57
/**
58
* Contains information about the image build, if there was any
59
*/
60
imageBuildInfo?: ImageBuildInfo;
61
62
/**
63
* workspace class, also known as workspace size, determines the type of
64
* resources that are provided to the workspace.
65
*/
66
workspaceClass?: string;
67
68
/**
69
* Identifies the team or user to which this instance's runtime should be attributed to
70
* (e.g. for usage analytics or billing purposes).
71
*/
72
usageAttributionId?: string;
73
}
74
75
// WorkspaceInstanceStatus describes the current state of a workspace instance
76
export interface WorkspaceInstanceStatus {
77
// version is the current version of the workspace instance status
78
// Note: consider this value opaque. The only guarantee given is that it imposes
79
// a partial order on status updates, i.e. a.version > b.version -> a newer than b.
80
version?: number;
81
82
// phase describes a high-level state of the workspace instance
83
phase: WorkspaceInstancePhase;
84
85
// conditions further specify the phase
86
conditions: WorkspaceInstanceConditions;
87
88
// message is a user-readable message containing information about the workspace
89
message?: string;
90
91
// exposedPorts is the list of currently exposed ports
92
exposedPorts?: WorkspaceInstancePort[];
93
94
// timeout is a non-default timeout value configured for a workspace
95
timeout?: string;
96
97
// nodeName is the name of the node the instance was scheduled onto
98
nodeName?: string;
99
100
// podName is the name of the pod of this instance
101
podName?: string;
102
103
// nodeIp is the IP of the node the workspace is running on
104
nodeIp?: string;
105
106
// ownerToken is the token one needs to access the workspace. Its presence is checked by ws-proxy.
107
ownerToken?: string;
108
109
// metrics contains metrics about the workspace instance
110
metrics?: WorkspaceInstanceMetrics;
111
}
112
113
// WorkspaceInstancePhase describes a high-level state of a workspace instance
114
export type WorkspaceInstancePhase =
115
// unknown indicates an issue within the system in that it cannot determine the actual phase of
116
// a workspace. This phase is usually accompanied by an error.
117
| "unknown"
118
119
// Preparing means that we haven't actually started the workspace instance just yet, but rather
120
// are still preparing for launch.
121
| "preparing"
122
123
// Building means that we are building the Docker image for the workspace. A workspace will enter this phase only
124
// if an image build is required for that workspace.
125
| "building"
126
127
// Pending means the workspace does not yet consume resources in the cluster, but rather is looking for
128
// some space within the cluster. If for example the cluster needs to scale up to accommodate the
129
// workspace, the workspace will be in Pending state until that happened.
130
| "pending"
131
132
// Creating means the workspace is currently being created. That includes downloading the images required
133
// to run the workspace over the network. The time spent in this phase varies widely and depends on the current
134
// network speed, image size and cache states.
135
| "creating"
136
137
// Initializing is the phase in which the workspace is executing the appropriate workspace initializer (e.g. Git
138
// clone or backup download). After this phase one can expect the workspace to either be Running or Failed.
139
| "initializing"
140
141
// Running means the workspace is able to actively perform work, either by serving a user through Theia,
142
// or as a headless workspace.
143
| "running"
144
145
// Interrupted is an exceptional state where the container should be running but is temporarily unavailable.
146
// When in this state, we expect it to become running or stopping anytime soon.
147
| "interrupted"
148
149
// Stopping means that the workspace is currently shutting down. It could go to stopped every moment.
150
| "stopping"
151
152
// Stopped means the workspace ended regularly because it was shut down.
153
| "stopped";
154
155
export interface WorkspaceInstanceConditions {
156
// Failed contains the reason the workspace failed to operate. If this field is empty, the workspace has not failed.
157
// failed contains technical details for the failure of the workspace.
158
failed?: string;
159
160
// timeout contains the reason the workspace has timed out. If this field is empty, the workspace has not timed out.
161
timeout?: string;
162
163
// PullingImages marks if the workspace is currently pulling its images. This condition can only be set during PhaseCreating
164
pullingImages?: boolean;
165
166
// deployed marks that a workspace instance was sent/deployed at a workspace manager
167
deployed?: boolean;
168
169
// Whether the workspace start triggered an image build
170
neededImageBuild?: boolean;
171
172
// ISO8601 timestamp when the first user activity was registered in the frontend. Only set if the workspace is running.
173
firstUserActivity?: string;
174
175
// headlessTaskFailed indicates that a headless workspace task failed
176
// headlessTaskFailed is only set if:
177
// * this workspace is headless
178
// * the task being run returned a non 0 exit status code
179
headlessTaskFailed?: string;
180
181
// stopped_by_request is true if the workspace was stopped using a StopWorkspace call
182
stoppedByRequest?: boolean;
183
}
184
185
// AdmissionLevel describes who can access a workspace instance and its ports.
186
export type AdmissionLevel = "owner_only" | "everyone";
187
188
// PortVisibility describes how a port can be accessed
189
export type PortVisibility = "public" | "private";
190
191
// PortProtocol
192
export type PortProtocol = "http" | "https";
193
194
// WorkspaceInstancePort describes a port exposed on a workspace instance
195
export interface WorkspaceInstancePort {
196
// The outward-facing port number
197
port: number;
198
199
// The visibility of this port. Optional for backwards compatibility.
200
visibility?: PortVisibility;
201
202
// Public, outward-facing URL where the port can be accessed on.
203
url?: string;
204
205
protocol?: PortProtocol;
206
}
207
208
// WorkspaceInstanceRepoStatus describes the status of th Git working copy of a workspace
209
export interface WorkspaceInstanceRepoStatus {
210
// branch is branch we're currently on
211
branch?: string;
212
213
// latestCommit is the last commit on the current branch
214
latestCommit?: string;
215
216
// uncommitedFiles is list of uncommitted files, possibly truncated
217
uncommitedFiles?: string[];
218
219
// the total number of uncommited files
220
totalUncommitedFiles?: number;
221
222
// untrackedFiles is the list of untracked files in the workspace, possibly truncated
223
untrackedFiles?: string[];
224
225
// the total number of untracked files
226
totalUntrackedFiles?: number;
227
228
// unpushedCommits is the list of unpushed changes in the workspace, possibly truncated
229
unpushedCommits?: string[];
230
231
// the total number of unpushed changes
232
totalUnpushedCommits?: number;
233
}
234
export namespace WorkspaceInstanceRepoStatus {
235
export function equals(
236
a: WorkspaceInstanceRepoStatus | undefined,
237
b: WorkspaceInstanceRepoStatus | undefined,
238
): boolean {
239
if (!a && !b) {
240
return true;
241
}
242
if (!a || !b) {
243
return false;
244
}
245
return (
246
a.branch === b.branch &&
247
a.latestCommit === b.latestCommit &&
248
a.totalUncommitedFiles === b.totalUncommitedFiles &&
249
a.totalUnpushedCommits === b.totalUnpushedCommits &&
250
a.totalUntrackedFiles === b.totalUntrackedFiles &&
251
stringArrayEquals(a.uncommitedFiles, b.uncommitedFiles) &&
252
stringArrayEquals(a.untrackedFiles, b.untrackedFiles) &&
253
stringArrayEquals(a.unpushedCommits, b.unpushedCommits)
254
);
255
}
256
function stringArrayEquals(a: string[] | undefined, b: string[] | undefined): boolean {
257
if (a === undefined && b === undefined) return true;
258
259
if (a === undefined || b === undefined) return false;
260
261
if (a.length !== b.length) return false;
262
263
for (let i = 0; i < a.length; i++) {
264
if (a[i] !== b[i]) return false;
265
}
266
267
return true;
268
}
269
}
270
271
// ConfigurationIdeConfig ide config of WorkspaceInstanceConfiguration
272
export interface ConfigurationIdeConfig {
273
useLatest?: boolean;
274
ide?: string;
275
preferToolbox?: boolean;
276
}
277
278
export interface IdeSetup {
279
tasks?: TaskConfig[];
280
envvars?: EnvVar[];
281
}
282
283
// WorkspaceInstanceConfiguration contains all per-instance configuration
284
export interface WorkspaceInstanceConfiguration {
285
// theiaVersion is the version of Theia this workspace instance uses
286
// @deprecated: replaced with the ideImage field
287
theiaVersion?: string;
288
289
// feature flags are the lowercase feature-flag names as passed to ws-manager
290
featureFlags?: NamedWorkspaceFeatureFlag[];
291
292
// ideImage is the ref of the IDE image this instance uses.
293
ideImage: string;
294
295
// ideImageLayers are images needed for the ide to run,
296
// including ide-desktop, desktop-plugin and so on
297
ideImageLayers?: string[];
298
299
// supervisorImage is the ref of the supervisor image this instance uses.
300
supervisorImage?: string;
301
302
// ideSetup contains all piece that are necessary to get the IDE running
303
// TODO(gpl) ideally also contains the fields above: ideImage, ideImageLayers and supervisorImage
304
ideSetup?: IdeSetup;
305
306
// ideConfig contains user-controlled IDE configuration
307
ideConfig?: ConfigurationIdeConfig;
308
309
// The region the user passed as a preference for this workspace
310
regionPreference?: WorkspaceRegion;
311
312
// Whether this instance is started from a backup
313
fromBackup?: boolean;
314
}
315
316
/**
317
* Holds information about the image build (if there was one) for this WorkspaceInstance
318
*/
319
export interface ImageBuildInfo {
320
log?: ImageBuildLogInfo;
321
}
322
323
/**
324
* Holds information about how to access logs for this an image build
325
*/
326
export interface ImageBuildLogInfo {
327
url: string;
328
headers: { [key: string]: string };
329
}
330
331
/**
332
* Holds metrics about the workspace instance
333
*/
334
export interface WorkspaceInstanceMetrics {
335
image?: ImageMetrics;
336
337
/**
338
* Metrics about the workspace initializer
339
*/
340
initializerMetrics?: InitializerMetrics;
341
}
342
343
export interface ImageMetrics {
344
/**
345
* the total size of the image in bytes (includes Gitpod-specific layers like IDE)
346
*/
347
totalSize?: number;
348
349
/**
350
* the size of the workspace image in bytes
351
*/
352
workspaceImageSize?: number;
353
}
354
355
export interface InitializerMetrics {
356
git?: InitializerMetric;
357
fileDownload?: InitializerMetric;
358
snapshot?: InitializerMetric;
359
backup?: InitializerMetric;
360
prebuild?: InitializerMetric;
361
composite?: InitializerMetric;
362
}
363
364
export interface InitializerMetric {
365
/**
366
* Duration in milliseconds
367
*/
368
duration: number;
369
370
/**
371
* Size in bytes
372
*/
373
size: number;
374
}
375
376