Skip to content

Commit f8edb19

Browse files
committed
[public-api] Draft more of the prebuild API
1 parent 46f5ab6 commit f8edb19

14 files changed

+4403
-1110
lines changed

components/public-api/README.md

Lines changed: 1 addition & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -3,99 +3,4 @@
33
# Example Flows
44
This section gives examples how clients would use this API.
55

6-
## Create Workspace
7-
8-
### Not prebuild aware
9-
```go
10-
workspaces.CreateWorkspace({
11-
idempotency_token: "<random_string>",
12-
context_url: "https://github.com/gitpod-io/gitpod",
13-
})
14-
```
15-
16-
### Prebuild aware but no log support
17-
```go
18-
workspaces.CreateWorkspace({
19-
idempotency_token: "<random_string>",
20-
context_url: "https://github.com/gitpod-io/gitpod",
21-
prebuild: {
22-
if_available: true,
23-
}
24-
})
25-
```
26-
27-
### Prebuild aware with log support
28-
```go
29-
contextURL := "https://github.com/gitpod-io/gitpod"
30-
prb := prebuilds.GetRunningPrebuild({ context_url: contextURL })
31-
logs := prebuilds.ListenToPrebuild({ context_url: contextURL, prebuild_id: prb.PrebuildID })
32-
33-
for logs.Recv() {
34-
// display logs
35-
}
36-
// once logs are done, prebuild is done (errors notwithstanding)
37-
38-
workspaces.CreateWorkspace({
39-
idempotency_token: "<random_string>",
40-
context_url: contextURL,
41-
prebuild: {
42-
prebuild_id: prb.PrebuildID,
43-
}
44-
})
45-
```
46-
47-
## Start Workspace
48-
49-
### Ignoring image-build logs
50-
```Go
51-
// Get ahold of a workspace ID, either by finding an existing workspace
52-
// or creating a new one.
53-
workspaceID := ...
54-
55-
// Start the workspace
56-
workspaces.StartWorkspace({
57-
idempotency_token: "<random_string>",
58-
workspace_id: workspaceID,
59-
})
60-
```
61-
62-
### With image build log support
63-
```Go
64-
// Get ahold of a workspace ID, either by finding an existing workspace
65-
// or creating a new one.
66-
workspaceID := ...
67-
68-
// Start the workspace
69-
resp := workspaces.StartWorkspace({
70-
idempotency_token: "<random_string>",
71-
workspace_id: workspaceID,
72-
})
73-
74-
// Listen to updates for the instance we just created
75-
updates := workspaces.ListenToWorkspaceInstance({
76-
instance_id: resp.InstanceId
77-
})
78-
var lastSeenVersion uint64
79-
for {
80-
update := updates.Recv()
81-
if lastSeenVersion == update.Version {
82-
continue
83-
}
84-
lastSeenVersion = update.Version
85-
86-
switch update.Phase {
87-
case ImageBuild:
88-
go showImageBuildLogs(instanceID)
89-
case Running:
90-
// do something with this running workspace
91-
}
92-
}
93-
94-
func showImageBuildLogs(instanceID string) {
95-
logs := workspaces.ListenToImageBuildLogs({instance_id: instanceID})
96-
for {
97-
resp := logs.Recv()
98-
fmt.Println(resp.Line)
99-
}
100-
}
101-
```
6+
https://github.com/gitpod-io/gitpod/blob/094dde356a04740500175e8797462a48c3153c89/components/public-api/go/v1/examples_test.go#L20-L103

components/public-api/gitpod/v1/prebuilds.proto

Lines changed: 91 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ syntax = "proto3";
22

33
package gitpod.v1;
44

5+
import "gitpod/v1/workspaces.proto";
56
import "google/rpc/status.proto";
67

78
option go_package = "github.com/gitpod-io/gitpod/public-api/v1";
@@ -10,19 +11,107 @@ option go_package = "github.com/gitpod-io/gitpod/public-api/v1";
1011

1112
service PrebuildsService {
1213

14+
// GetPrebuild retrieves a single rebuild.
15+
// Errors:
16+
// NOT_FOUND if the prebuild_id does not exist
17+
rpc GetPrebuild(GetPrebuildRequest) returns (GetPrebuildResponse) {}
18+
1319
// GetRunningPrebuild returns the prebuild ID of a running prebuild,
1420
// or NOT_FOUND if there is no prebuild running for the content_url.
1521
rpc GetRunningPrebuild(GetRunningPrebuildRequest) returns (GetRunningPrebuildResponse) {}
1622

23+
// ListenToPrebuildStatus streams status updates for a prebuild. If the prebuild is already
24+
// in the Done phase, only that single status is streamed.
25+
rpc ListenToPrebuildStatus(ListenToPrebuildStatusRequest) returns (stream ListenToPrebuildStatusResponse) {}
26+
27+
// ListenToPrebuildLogs returns the log output of a prebuild.
28+
// This does NOT include an image build if one happened.
29+
rpc ListenToPrebuildLogs(ListenToPrebuildLogsRequest) returns (stream ListenToPrebuildLogsResponse) {}
30+
31+
}
32+
33+
message GetPrebuildRequest {
34+
string prebuild_id = 1;
35+
}
36+
message GetPrebuildResponse {
37+
google.rpc.Status response_status = 1;
38+
39+
Prebuild prebuild = 2;
1740
}
1841

1942
message GetRunningPrebuildRequest {
2043
string context_url = 1;
2144
}
22-
2345
message GetRunningPrebuildResponse {
2446
google.rpc.Status response_status = 1;
2547

26-
string prebuild_id = 2;
48+
Prebuild prebuild = 2;
49+
}
50+
51+
message ListenToPrebuildStatusRequest{
52+
string prebuild_id = 1;
2753
}
54+
message ListenToPrebuildStatusResponse {
55+
google.rpc.Status response_status = 1;
2856

57+
PrebuildStatus status = 2;
58+
}
59+
60+
message ListenToPrebuildLogsRequest {
61+
string prebuild_id = 1;
62+
}
63+
message ListenToPrebuildLogsResponse {
64+
google.rpc.Status response_status = 1;
65+
66+
string line = 2;
67+
}
68+
69+
////////////////////////////////
70+
// Shared messages come here
71+
////////////////////////////////
72+
73+
// Prebuild describes a prebuild
74+
message Prebuild {
75+
string prebuild_id = 1;
76+
PrebuildSpec spec = 2;
77+
PrebuildStatus status = 3;
78+
}
79+
80+
// PrebuildSpec specifies the prebuild input.
81+
message PrebuildSpec {
82+
WorkspaceContext context = 1;
83+
84+
// Incremental prebuilds are based on other prebuilds. If this field is true,
85+
// expect the context detail to point to another prebuild.
86+
bool incremental = 2;
87+
}
88+
89+
// PrebuildStatus describes the prebuild status.
90+
message PrebuildStatus {
91+
enum Phase {
92+
PHASE_UNSPECIFIED = 0;
93+
PHASE_PENDING = 1;
94+
PHASE_RUNNING = 2;
95+
PHASE_DONE = 3;
96+
}
97+
enum Result {
98+
RESULT_UNSPECIFIED = 0;
99+
RESULT_SUCCESS = 1;
100+
RESULT_USER_CANCELED = 2;
101+
RESULT_SYSTEM_FAILURE = 3;
102+
RESULT_TASK_FAILURE = 4;
103+
}
104+
105+
// Phase is the prebuild phase we're in
106+
Phase phase = 1;
107+
108+
// Result indicates what result the prebuild produced, i.e. if it ran
109+
// successfully or failed for some reason. If phase != done, this field
110+
// will have RESULT_UNSPECIFIED as value.
111+
Result result = 2;
112+
113+
// result_message contains a human readable message describing the prebuild
114+
// result. E.g. if teh result is SYSTEM_FAILURE, the message describes what
115+
// that failure was.
116+
string result_message = 3;
117+
}

components/public-api/gitpod/v1/workspaces.proto

Lines changed: 63 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,9 @@ message GetWorkspaceResponse {
7777
message CreateAndStartWorkspaceRequest {
7878
string idempotency_token = 1;
7979

80-
string context_url = 2;
81-
82-
oneof prebuild {
83-
// if true, and there's a prebuild available (not running), use that prebuild
84-
bool if_available = 3;
85-
// uses a particular prebuild - the prebuild ID is scoped by the context URL.
86-
// Use the PrebuildService to get ahold of the prebuild_id.
87-
string prebuild_id = 4;
80+
oneof source {
81+
string context_url = 2;
82+
string prebuild_id = 3;
8883
}
8984

9085
StartWorkspaceSpec start_spec = 5;
@@ -224,6 +219,64 @@ message WorkspaceInstance {
224219

225220
// WorkspaceStatus describes a workspace status
226221
message WorkspaceInstanceStatus {
222+
// Phase is a simple, high-level summary of where the workspace instance is in its lifecycle.
223+
// The phase is not intended to be a comprehensive rollup of observations of the workspace state,
224+
// nor is it intended to be a comprehensive state machine.
225+
// (based on https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase)
226+
enum Phase {
227+
// Unknown indicates an issue within the workspace manager in that it cannot determine the actual phase of
228+
// a workspace. This phase is usually accompanied by an error.
229+
PHASE_UNSPECIFIED = 0;
230+
231+
// ImageBuild indicates that there's an image build running for this workspace.
232+
PHASE_IMAGEBUILD = 1;
233+
234+
// Pending means the workspace does not yet consume resources in the cluster, but rather is looking for
235+
// some space within the cluster. If for example the cluster needs to scale up to accomodate the
236+
// workspace, the workspace will be in Pending state until that happened.
237+
PHASE_PENDING = 2;
238+
239+
// Creating means the workspace is currently being created. That includes downloading the images required
240+
// to run the workspace over the network. The time spent in this phase varies widely and depends on the current
241+
// network speed, image size and cache states.
242+
PHASE_CREATING = 3;
243+
244+
// Initializing is the phase in which the workspace is executing the appropriate workspace initializer (e.g. Git
245+
// clone or backup download). After this phase one can expect the workspace to either be Running or Failed.
246+
PHASE_INITIALIZING = 4;
247+
248+
// Running means the workspace is able to actively perform work, either by serving a user through Theia,
249+
// or as a headless workspace.
250+
PHASE_RUNNING = 5;
251+
252+
// Interrupted is an exceptional state where the container should be running but is temporarily unavailable.
253+
// When in this state, we expect it to become running or stopping anytime soon.
254+
PHASE_INTERRUPTED = 6;
255+
256+
// Stopping means that the workspace is currently shutting down. It could go to stopped every moment.
257+
PHASE_STOPPING = 7;
258+
259+
// Stopped means the workspace ended regularly because it was shut down.
260+
PHASE_STOPPED = 8;
261+
}
262+
263+
// Conditions gives more detailed information as to the state of the workspace. Which condition actually
264+
// has a value depends on the phase the workspace is in.
265+
message Conditions {
266+
// failed contains the reason the workspace failed to operate. If this field is empty, the workspace has not failed.
267+
// This field is filled exclusively when caused by system errors.
268+
string failed = 1;
269+
270+
// timeout contains the reason the workspace has timed out. If this field is empty, the workspace has not timed out.
271+
string timeout = 2;
272+
273+
// first_user_activity is the time when MarkActive was first called on the workspace
274+
google.protobuf.Timestamp first_user_activity = 9;
275+
276+
// stopped_by_request is true if the workspace was stopped using a StopWorkspace call
277+
optional bool stopped_by_request = 11;
278+
}
279+
227280
// version of the status update. Workspace instances themselves are unversioned,
228281
// but their statuus has different versions.
229282
// The value of this field has no semantic meaning (e.g. don't interpret it as
@@ -232,10 +285,10 @@ message WorkspaceInstanceStatus {
232285
uint64 status_version = 1;
233286

234287
// the phase of a workspace is a simple, high-level summary of where the workspace instance is in its lifecycle
235-
WorkspaceInstancePhase phase = 2;
288+
Phase phase = 2;
236289

237290
// conditions detail the current state of the workspace instance
238-
WorkspaceInstanceConditions conditions = 3;
291+
Conditions conditions = 3;
239292

240293
// message is an optional human-readable message detailing the current phase
241294
string message = 4;
@@ -252,65 +305,6 @@ message WorkspaceInstanceStatus {
252305
// contentservice.GitStatus repo = 7;
253306
}
254307

255-
256-
// WorkspaceInstancePhase is a simple, high-level summary of where the workspace instance is in its lifecycle.
257-
// The phase is not intended to be a comprehensive rollup of observations of the workspace state,
258-
// nor is it intended to be a comprehensive state machine.
259-
// (based on https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase)
260-
enum WorkspaceInstancePhase {
261-
// Unknown indicates an issue within the workspace manager in that it cannot determine the actual phase of
262-
// a workspace. This phase is usually accompanied by an error.
263-
WORKSPACE_INSTANCE_PHASE_UNSPECIFIED = 0;
264-
265-
// This will become IMAGE_BUILD
266-
reserved 1;
267-
268-
// Pending means the workspace does not yet consume resources in the cluster, but rather is looking for
269-
// some space within the cluster. If for example the cluster needs to scale up to accomodate the
270-
// workspace, the workspace will be in Pending state until that happened.
271-
WORKSPACE_INSTANCE_PHASE_PENDING = 2;
272-
273-
// Creating means the workspace is currently being created. That includes downloading the images required
274-
// to run the workspace over the network. The time spent in this phase varies widely and depends on the current
275-
// network speed, image size and cache states.
276-
WORKSPACE_INSTANCE_PHASE_CREATING = 3;
277-
278-
// Initializing is the phase in which the workspace is executing the appropriate workspace initializer (e.g. Git
279-
// clone or backup download). After this phase one can expect the workspace to either be Running or Failed.
280-
WORKSPACE_INSTANCE_PHASE_INITIALIZING = 4;
281-
282-
// Running means the workspace is able to actively perform work, either by serving a user through Theia,
283-
// or as a headless workspace.
284-
WORKSPACE_INSTANCE_PHASE_RUNNING = 5;
285-
286-
// Interrupted is an exceptional state where the container should be running but is temporarily unavailable.
287-
// When in this state, we expect it to become running or stopping anytime soon.
288-
WORKSPACE_INSTANCE_PHASE_INTERRUPTED = 6;
289-
290-
// Stopping means that the workspace is currently shutting down. It could go to stopped every moment.
291-
WORKSPACE_INSTANCE_PHASE_STOPPING = 7;
292-
293-
// Stopped means the workspace ended regularly because it was shut down.
294-
WORKSPACE_INSTANCE_PHASE_STOPPED = 8;
295-
}
296-
297-
// WorkspaceInstanceConditions gives more detailed information as to the state of the workspace. Which condition actually
298-
// has a value depends on the phase the workspace is in.
299-
message WorkspaceInstanceConditions {
300-
// failed contains the reason the workspace failed to operate. If this field is empty, the workspace has not failed.
301-
// This field is filled exclusively when caused by system errors.
302-
string failed = 1;
303-
304-
// timeout contains the reason the workspace has timed out. If this field is empty, the workspace has not timed out.
305-
string timeout = 2;
306-
307-
// first_user_activity is the time when MarkActive was first called on the workspace
308-
google.protobuf.Timestamp first_user_activity = 9;
309-
310-
// stopped_by_request is true if the workspace was stopped using a StopWorkspace call
311-
optional bool stopped_by_request = 11;
312-
}
313-
314308
// Admission level describes who can access a workspace instance and its ports.
315309
enum AdmissionLevel {
316310
ADMISSION_LEVEL_UNSPECIFIED = 0;

0 commit comments

Comments
 (0)