Skip to content

Commit 7f8e557

Browse files
committed
[server][ws-manager] Allow setting customTimeoutAnnotation for headless workspace pods
1 parent c997daf commit 7f8e557

File tree

4 files changed

+316
-8
lines changed

4 files changed

+316
-8
lines changed

components/server/src/workspace/workspace-starter.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,9 @@ export class WorkspaceStarter {
633633
spec.setWorkspaceImage(instance.workspaceImage);
634634
spec.setWorkspaceLocation(workspace.config.workspaceLocation || spec.getCheckoutLocation());
635635
spec.setFeatureFlagsList(this.toWorkspaceFeatureFlags(featureFlags));
636-
spec.setTimeout(await userTimeoutPromise);
636+
if (workspace.type === 'regular') {
637+
spec.setTimeout(await userTimeoutPromise);
638+
}
637639
spec.setAdmission(admissionLevel);
638640
return spec;
639641
}

components/ws-manager/pkg/manager/status.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -731,24 +731,26 @@ func (m *Manager) isWorkspaceTimedOut(wso workspaceObjects) (reason string, err
731731
return decide(start, m.Config.Timeouts.TotalStartup, activity)
732732

733733
case api.WorkspacePhase_RUNNING:
734+
timeout := m.Config.Timeouts.RegularWorkspace
735+
activity := activityNone
734736
if wso.IsWorkspaceHeadless() {
735-
return decide(start, m.Config.Timeouts.HeadlessWorkspace, activityRunningHeadless)
737+
timeout = m.Config.Timeouts.HeadlessWorkspace
738+
lastActivity = &start
739+
activity = activityRunningHeadless
736740
} else if lastActivity == nil {
737741
// the workspace is up and running, but the user has never produced any activity
738742
return decide(start, m.Config.Timeouts.TotalStartup, activityNone)
739743
} else if isClosed {
740744
return decide(*lastActivity, m.Config.Timeouts.AfterClose, activityClosed)
741745
}
742-
timeout := m.Config.Timeouts.RegularWorkspace
743746
if ctv, ok := wso.Pod.Annotations[customTimeoutAnnotation]; ok {
744-
if ct, err := time.ParseDuration(ctv); err != nil {
745-
log.WithError(err).WithField("customTimeout", ctv).WithFields(wsk8s.GetOWIFromObject(&wso.Pod.ObjectMeta)).Warn("pod had custom timeout annotation set, but could not parse its value. Defaulting to ws-manager config.")
746-
timeout = m.Config.Timeouts.RegularWorkspace
747-
} else {
747+
if ct, err := time.ParseDuration(ctv); err == nil {
748748
timeout = util.Duration(ct)
749+
} else {
750+
log.WithError(err).WithField("customTimeout", ctv).WithFields(wsk8s.GetOWIFromObject(&wso.Pod.ObjectMeta)).Warn("pod had custom timeout annotation set, but could not parse its value. Defaulting to ws-manager config.")
749751
}
750752
}
751-
return decide(*lastActivity, timeout, activityNone)
753+
return decide(*lastActivity, timeout, activity)
752754

753755
case api.WorkspacePhase_INTERRUPTED:
754756
if lastActivity == nil {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}
Lines changed: 303 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,303 @@
1+
{
2+
"creationDelta": "100m",
3+
"wso": {
4+
"pod": {
5+
"metadata": {
6+
"name": "ws-foobas",
7+
"namespace": "default",
8+
"selfLink": "/api/v1/namespaces/default/pods/ws-foobas",
9+
"uid": "486e5f88-4354-11e9-aee4-080027861af1",
10+
"resourceVersion": "64956",
11+
"creationTimestamp": "2019-03-10T16:48:08Z",
12+
"labels": {
13+
"gpwsman": "true",
14+
"headless": "true",
15+
"owner": "foobar",
16+
"metaID": "metameta",
17+
"workspaceID": "foobas",
18+
"workspaceType": "prebuild"
19+
},
20+
"annotations": {
21+
"gitpod/id": "foobas",
22+
"gitpod/ready": "true",
23+
"gitpod/servicePrefix": "foobas",
24+
"gitpod/url": "http://10.0.0.114:8082",
25+
"gitpod/customTimeout": "2h",
26+
"prometheus.io/path": "/metrics",
27+
"prometheus.io/port": "23000",
28+
"prometheus.io/scrape": "true"
29+
}
30+
},
31+
"spec": {
32+
"volumes": [
33+
{
34+
"name": "vol-this-workspace",
35+
"hostPath": {
36+
"path": "/tmp/workspaces/foobas",
37+
"type": "DirectoryOrCreate"
38+
}
39+
},
40+
{
41+
"name": "vol-this-theia",
42+
"hostPath": {
43+
"path": "/tmp/theia/theia-xyz",
44+
"type": "Directory"
45+
}
46+
},
47+
{
48+
"name": "vol-sync-tmp",
49+
"hostPath": {
50+
"path": "/tmp/workspaces/sync-tmp",
51+
"type": "DirectoryOrCreate"
52+
}
53+
},
54+
{
55+
"name": "default-token-6qnvx",
56+
"secret": {
57+
"secretName": "default-token-6qnvx",
58+
"defaultMode": 420
59+
}
60+
}
61+
],
62+
"containers": [
63+
{
64+
"name": "workspace",
65+
"image": "nginx:latest",
66+
"ports": [
67+
{
68+
"containerPort": 23000,
69+
"protocol": "TCP"
70+
}
71+
],
72+
"env": [
73+
{
74+
"name": "THEIA_WORKSPACE_ROOT",
75+
"value": "/workspace"
76+
},
77+
{
78+
"name": "GITPOD_THEIA_PORT",
79+
"value": "23000"
80+
},
81+
{
82+
"name": "GITPOD_HOST",
83+
"value": "gitpod.io"
84+
},
85+
{
86+
"name": "GITPOD_INTERVAL",
87+
"value": "30"
88+
},
89+
{
90+
"name": "GITPOD_WSSYNC_APITOKEN",
91+
"value": "c17a7eaf-e5de-4e9d-815a-7919379e2bf8"
92+
},
93+
{
94+
"name": "GITPOD_WSSYNC_APIPORT",
95+
"value": "44444"
96+
},
97+
{
98+
"name": "GITPOD_REPO_ROOT",
99+
"value": "/workspace"
100+
},
101+
{
102+
"name": "GITPOD_CLI_APITOKEN",
103+
"value": "690516e2-c416-4a28-ba74-e36f125922aa"
104+
},
105+
{
106+
"name": "GITPOD_WORKSPACE_ID",
107+
"value": "foobas"
108+
},
109+
{
110+
"name": "GITPOD_GIT_USER_NAME",
111+
"value": "usernameGoesHere"
112+
},
113+
{
114+
"name": "GITPOD_GIT_USER_EMAIL",
115+
"value": "[email protected]"
116+
}
117+
],
118+
"resources": {
119+
"limits": {
120+
"cpu": "100m",
121+
"memory": "100Mi"
122+
},
123+
"requests": {
124+
"cpu": "100m",
125+
"memory": "100Mi"
126+
}
127+
},
128+
"volumeMounts": [
129+
{
130+
"name": "vol-this-workspace",
131+
"mountPath": "/workspace"
132+
},
133+
{
134+
"name": "vol-this-theia",
135+
"readOnly": true,
136+
"mountPath": "/theia"
137+
},
138+
{
139+
"name": "default-token-6qnvx",
140+
"readOnly": true,
141+
"mountPath": "/var/run/secrets/kubernetes.io/serviceaccount"
142+
}
143+
],
144+
"terminationMessagePath": "/dev/termination-log",
145+
"terminationMessagePolicy": "File",
146+
"imagePullPolicy": "Always"
147+
}
148+
],
149+
"restartPolicy": "Always",
150+
"terminationGracePeriodSeconds": 30,
151+
"dnsPolicy": "ClusterFirst",
152+
"serviceAccountName": "default",
153+
"serviceAccount": "default",
154+
"nodeName": "minikube",
155+
"securityContext": {},
156+
"schedulerName": "default-scheduler",
157+
"tolerations": [
158+
{
159+
"key": "node.kubernetes.io/not-ready",
160+
"operator": "Exists",
161+
"effect": "NoExecute",
162+
"tolerationSeconds": 300
163+
},
164+
{
165+
"key": "node.kubernetes.io/unreachable",
166+
"operator": "Exists",
167+
"effect": "NoExecute",
168+
"tolerationSeconds": 300
169+
}
170+
]
171+
},
172+
"status": {
173+
"phase": "Running",
174+
"conditions": [
175+
{
176+
"type": "Initialized",
177+
"status": "True",
178+
"lastProbeTime": null,
179+
"lastTransitionTime": "2019-03-10T16:48:08Z"
180+
},
181+
{
182+
"type": "Ready",
183+
"status": "True",
184+
"lastProbeTime": null,
185+
"lastTransitionTime": "2019-03-10T16:48:13Z"
186+
},
187+
{
188+
"type": "PodScheduled",
189+
"status": "True",
190+
"lastProbeTime": null,
191+
"lastTransitionTime": "2019-03-10T16:48:08Z"
192+
}
193+
],
194+
"hostIP": "10.0.2.15",
195+
"podIP": "172.17.0.5",
196+
"startTime": "2019-03-10T16:48:08Z",
197+
"containerStatuses": [
198+
{
199+
"name": "sync",
200+
"state": {
201+
"running": {
202+
"startedAt": "2019-03-10T16:48:13Z"
203+
}
204+
},
205+
"lastState": {},
206+
"ready": true,
207+
"restartCount": 0,
208+
"image": "csweichel/noop:latest",
209+
"imageID": "docker-pullable://csweichel/noop@sha256:aaa6b993f4c853fac7101aa7fc087926f829004e62cbce6e1852e5a3aac87c52",
210+
"containerID": "docker://9961f75ea72f36bb0ba1e42b3b2da98eb44a9dc12e7c7e8edfb52512b3b04016"
211+
},
212+
{
213+
"name": "workspace",
214+
"state": {
215+
"running": {
216+
"startedAt": "2019-03-10T16:48:12Z"
217+
}
218+
},
219+
"lastState": {},
220+
"ready": true,
221+
"restartCount": 0,
222+
"image": "nginx:latest",
223+
"imageID": "docker-pullable://nginx@sha256:98efe605f61725fd817ea69521b0eeb32bef007af0e3d0aeb6258c6e6fe7fc1a",
224+
"containerID": "docker://e7080b843a47db414d6c94cfda7f657b99d8aa5bbf7c9c118ec98c0eefb6c0df"
225+
}
226+
],
227+
"qosClass": "Guaranteed"
228+
}
229+
},
230+
"theiaService": {
231+
"metadata": {
232+
"name": "foobas-theia",
233+
"namespace": "default",
234+
"selfLink": "/api/v1/namespaces/default/services/foobas-theia",
235+
"uid": "48687212-4354-11e9-aee4-080027861af1",
236+
"resourceVersion": "64923",
237+
"creationTimestamp": "2019-03-10T16:48:08Z",
238+
"labels": {
239+
"gpwsman": "true",
240+
"headless": "false",
241+
"owner": "foobar",
242+
"metaID": "metameta",
243+
"workspaceID": "foobas"
244+
}
245+
},
246+
"spec": {
247+
"ports": [
248+
{
249+
"name": "theia",
250+
"protocol": "TCP",
251+
"port": 23000,
252+
"targetPort": 23000
253+
}
254+
],
255+
"selector": {
256+
"gpwsman": "true",
257+
"headless": "false",
258+
"owner": "foobar",
259+
"workspaceID": "foobas"
260+
},
261+
"clusterIP": "10.103.194.121",
262+
"type": "ClusterIP",
263+
"sessionAffinity": "None"
264+
},
265+
"status": {
266+
"loadBalancer": {}
267+
}
268+
},
269+
"portsService": {
270+
"metadata": {
271+
"name": "foobas-ports",
272+
"namespace": "default",
273+
"selfLink": "/api/v1/namespaces/default/services/foobas-ports",
274+
"uid": "486cb304-4354-11e9-aee4-080027861af1",
275+
"resourceVersion": "64926",
276+
"creationTimestamp": "2019-03-10T16:48:08Z",
277+
"labels": {
278+
"gpwsman": "true",
279+
"workspaceID": "foobas"
280+
}
281+
},
282+
"spec": {
283+
"ports": [
284+
{
285+
"protocol": "TCP",
286+
"port": 8080,
287+
"targetPort": 8080
288+
}
289+
],
290+
"selector": {
291+
"gpwsman": "true",
292+
"workspaceID": "foobas"
293+
},
294+
"clusterIP": "10.110.184.222",
295+
"type": "ClusterIP",
296+
"sessionAffinity": "None"
297+
},
298+
"status": {
299+
"loadBalancer": {}
300+
}
301+
}
302+
}
303+
}

0 commit comments

Comments
 (0)