diff --git a/components/server/src/workspace/workspace-starter.ts b/components/server/src/workspace/workspace-starter.ts index 04d2fdec650e23..1dea0953403d5c 100644 --- a/components/server/src/workspace/workspace-starter.ts +++ b/components/server/src/workspace/workspace-starter.ts @@ -633,7 +633,9 @@ export class WorkspaceStarter { spec.setWorkspaceImage(instance.workspaceImage); spec.setWorkspaceLocation(workspace.config.workspaceLocation || spec.getCheckoutLocation()); spec.setFeatureFlagsList(this.toWorkspaceFeatureFlags(featureFlags)); - spec.setTimeout(await userTimeoutPromise); + if (workspace.type === 'regular') { + spec.setTimeout(await userTimeoutPromise); + } spec.setAdmission(admissionLevel); return spec; } diff --git a/components/ws-manager/pkg/manager/status.go b/components/ws-manager/pkg/manager/status.go index 52a2b7db1f6ccc..cfb2be5e918ba5 100644 --- a/components/ws-manager/pkg/manager/status.go +++ b/components/ws-manager/pkg/manager/status.go @@ -709,7 +709,7 @@ func (m *Manager) isWorkspaceTimedOut(wso workspaceObjects) (reason string, err return "", nil } - return fmt.Sprintf("workspace timed out after %s took longer than %s", activity, formatDuration(inactivity)), nil + return fmt.Sprintf("workspace timed out after %s (%s) took longer than %s", activity, formatDuration(inactivity), formatDuration(td)), nil } start := wso.Pod.ObjectMeta.CreationTimestamp.Time @@ -731,24 +731,26 @@ func (m *Manager) isWorkspaceTimedOut(wso workspaceObjects) (reason string, err return decide(start, m.Config.Timeouts.TotalStartup, activity) case api.WorkspacePhase_RUNNING: + timeout := m.Config.Timeouts.RegularWorkspace + activity := activityNone if wso.IsWorkspaceHeadless() { - return decide(start, m.Config.Timeouts.HeadlessWorkspace, activityRunningHeadless) + timeout = m.Config.Timeouts.HeadlessWorkspace + lastActivity = &start + activity = activityRunningHeadless } else if lastActivity == nil { // the workspace is up and running, but the user has never produced any activity return decide(start, m.Config.Timeouts.TotalStartup, activityNone) } else if isClosed { return decide(*lastActivity, m.Config.Timeouts.AfterClose, activityClosed) } - timeout := m.Config.Timeouts.RegularWorkspace if ctv, ok := wso.Pod.Annotations[customTimeoutAnnotation]; ok { - if ct, err := time.ParseDuration(ctv); err != nil { - 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.") - timeout = m.Config.Timeouts.RegularWorkspace - } else { + if ct, err := time.ParseDuration(ctv); err == nil { timeout = util.Duration(ct) + } else { + 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.") } } - return decide(*lastActivity, timeout, activityNone) + return decide(*lastActivity, timeout, activity) case api.WorkspacePhase_INTERRUPTED: if lastActivity == nil { diff --git a/components/ws-manager/pkg/manager/testdata/timeout_customTimeout_invalidValue.golden b/components/ws-manager/pkg/manager/testdata/timeout_customTimeout_invalidValue.golden index 95ca611c363491..a8ec852cbff538 100644 --- a/components/ws-manager/pkg/manager/testdata/timeout_customTimeout_invalidValue.golden +++ b/components/ws-manager/pkg/manager/testdata/timeout_customTimeout_invalidValue.golden @@ -1,3 +1,3 @@ { - "reason": "workspace timed out after period of inactivity took longer than 01h10m" + "reason": "workspace timed out after period of inactivity (01h10m) took longer than 00h45m" } \ No newline at end of file diff --git a/components/ws-manager/pkg/manager/testdata/timeout_interrupted_noActivity.golden b/components/ws-manager/pkg/manager/testdata/timeout_interrupted_noActivity.golden index bc184435a48c88..7994238eedb29c 100644 --- a/components/ws-manager/pkg/manager/testdata/timeout_interrupted_noActivity.golden +++ b/components/ws-manager/pkg/manager/testdata/timeout_interrupted_noActivity.golden @@ -1,3 +1,3 @@ { - "reason": "workspace timed out after workspace interruption took longer than 00h10m" + "reason": "workspace timed out after workspace interruption (00h10m) took longer than 00h05m" } \ No newline at end of file diff --git a/components/ws-manager/pkg/manager/testdata/timeout_interrupted_withActivity.golden b/components/ws-manager/pkg/manager/testdata/timeout_interrupted_withActivity.golden index bc184435a48c88..7994238eedb29c 100644 --- a/components/ws-manager/pkg/manager/testdata/timeout_interrupted_withActivity.golden +++ b/components/ws-manager/pkg/manager/testdata/timeout_interrupted_withActivity.golden @@ -1,3 +1,3 @@ { - "reason": "workspace timed out after workspace interruption took longer than 00h10m" + "reason": "workspace timed out after workspace interruption (00h10m) took longer than 00h05m" } \ No newline at end of file diff --git a/components/ws-manager/pkg/manager/testdata/timeout_prebuild_Creating00.golden b/components/ws-manager/pkg/manager/testdata/timeout_prebuild_Creating00.golden index 3a50c2307c6347..0d32a506162025 100644 --- a/components/ws-manager/pkg/manager/testdata/timeout_prebuild_Creating00.golden +++ b/components/ws-manager/pkg/manager/testdata/timeout_prebuild_Creating00.golden @@ -1,3 +1,3 @@ { - "reason": "workspace timed out after pulling images took longer than 00h50m" + "reason": "workspace timed out after pulling images (00h50m) took longer than 00h45m" } \ No newline at end of file diff --git a/components/ws-manager/pkg/manager/testdata/timeout_prebuild_Pending00.golden b/components/ws-manager/pkg/manager/testdata/timeout_prebuild_Pending00.golden index 8e1b4eb756aa52..078c2520d5eae9 100644 --- a/components/ws-manager/pkg/manager/testdata/timeout_prebuild_Pending00.golden +++ b/components/ws-manager/pkg/manager/testdata/timeout_prebuild_Pending00.golden @@ -1,3 +1,3 @@ { - "reason": "workspace timed out after initialization took longer than 00h50m" + "reason": "workspace timed out after initialization (00h50m) took longer than 00h30m" } \ No newline at end of file diff --git a/components/ws-manager/pkg/manager/testdata/timeout_prebuild_customTimeout.golden b/components/ws-manager/pkg/manager/testdata/timeout_prebuild_customTimeout.golden new file mode 100644 index 00000000000000..9e26dfeeb6e641 --- /dev/null +++ b/components/ws-manager/pkg/manager/testdata/timeout_prebuild_customTimeout.golden @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/components/ws-manager/pkg/manager/testdata/timeout_prebuild_customTimeout.json b/components/ws-manager/pkg/manager/testdata/timeout_prebuild_customTimeout.json new file mode 100644 index 00000000000000..7435e98a6d1256 --- /dev/null +++ b/components/ws-manager/pkg/manager/testdata/timeout_prebuild_customTimeout.json @@ -0,0 +1,303 @@ +{ + "creationDelta": "100m", + "wso": { + "pod": { + "metadata": { + "name": "ws-foobas", + "namespace": "default", + "selfLink": "/api/v1/namespaces/default/pods/ws-foobas", + "uid": "486e5f88-4354-11e9-aee4-080027861af1", + "resourceVersion": "64956", + "creationTimestamp": "2019-03-10T16:48:08Z", + "labels": { + "gpwsman": "true", + "headless": "true", + "owner": "foobar", + "metaID": "metameta", + "workspaceID": "foobas", + "workspaceType": "prebuild" + }, + "annotations": { + "gitpod/id": "foobas", + "gitpod/ready": "true", + "gitpod/servicePrefix": "foobas", + "gitpod/url": "http://10.0.0.114:8082", + "gitpod/customTimeout": "2h", + "prometheus.io/path": "/metrics", + "prometheus.io/port": "23000", + "prometheus.io/scrape": "true" + } + }, + "spec": { + "volumes": [ + { + "name": "vol-this-workspace", + "hostPath": { + "path": "/tmp/workspaces/foobas", + "type": "DirectoryOrCreate" + } + }, + { + "name": "vol-this-theia", + "hostPath": { + "path": "/tmp/theia/theia-xyz", + "type": "Directory" + } + }, + { + "name": "vol-sync-tmp", + "hostPath": { + "path": "/tmp/workspaces/sync-tmp", + "type": "DirectoryOrCreate" + } + }, + { + "name": "default-token-6qnvx", + "secret": { + "secretName": "default-token-6qnvx", + "defaultMode": 420 + } + } + ], + "containers": [ + { + "name": "workspace", + "image": "nginx:latest", + "ports": [ + { + "containerPort": 23000, + "protocol": "TCP" + } + ], + "env": [ + { + "name": "THEIA_WORKSPACE_ROOT", + "value": "/workspace" + }, + { + "name": "GITPOD_THEIA_PORT", + "value": "23000" + }, + { + "name": "GITPOD_HOST", + "value": "gitpod.io" + }, + { + "name": "GITPOD_INTERVAL", + "value": "30" + }, + { + "name": "GITPOD_WSSYNC_APITOKEN", + "value": "c17a7eaf-e5de-4e9d-815a-7919379e2bf8" + }, + { + "name": "GITPOD_WSSYNC_APIPORT", + "value": "44444" + }, + { + "name": "GITPOD_REPO_ROOT", + "value": "/workspace" + }, + { + "name": "GITPOD_CLI_APITOKEN", + "value": "690516e2-c416-4a28-ba74-e36f125922aa" + }, + { + "name": "GITPOD_WORKSPACE_ID", + "value": "foobas" + }, + { + "name": "GITPOD_GIT_USER_NAME", + "value": "usernameGoesHere" + }, + { + "name": "GITPOD_GIT_USER_EMAIL", + "value": "some@user.com" + } + ], + "resources": { + "limits": { + "cpu": "100m", + "memory": "100Mi" + }, + "requests": { + "cpu": "100m", + "memory": "100Mi" + } + }, + "volumeMounts": [ + { + "name": "vol-this-workspace", + "mountPath": "/workspace" + }, + { + "name": "vol-this-theia", + "readOnly": true, + "mountPath": "/theia" + }, + { + "name": "default-token-6qnvx", + "readOnly": true, + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount" + } + ], + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "imagePullPolicy": "Always" + } + ], + "restartPolicy": "Always", + "terminationGracePeriodSeconds": 30, + "dnsPolicy": "ClusterFirst", + "serviceAccountName": "default", + "serviceAccount": "default", + "nodeName": "minikube", + "securityContext": {}, + "schedulerName": "default-scheduler", + "tolerations": [ + { + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "effect": "NoExecute", + "tolerationSeconds": 300 + }, + { + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "effect": "NoExecute", + "tolerationSeconds": 300 + } + ] + }, + "status": { + "phase": "Running", + "conditions": [ + { + "type": "Initialized", + "status": "True", + "lastProbeTime": null, + "lastTransitionTime": "2019-03-10T16:48:08Z" + }, + { + "type": "Ready", + "status": "True", + "lastProbeTime": null, + "lastTransitionTime": "2019-03-10T16:48:13Z" + }, + { + "type": "PodScheduled", + "status": "True", + "lastProbeTime": null, + "lastTransitionTime": "2019-03-10T16:48:08Z" + } + ], + "hostIP": "10.0.2.15", + "podIP": "172.17.0.5", + "startTime": "2019-03-10T16:48:08Z", + "containerStatuses": [ + { + "name": "sync", + "state": { + "running": { + "startedAt": "2019-03-10T16:48:13Z" + } + }, + "lastState": {}, + "ready": true, + "restartCount": 0, + "image": "csweichel/noop:latest", + "imageID": "docker-pullable://csweichel/noop@sha256:aaa6b993f4c853fac7101aa7fc087926f829004e62cbce6e1852e5a3aac87c52", + "containerID": "docker://9961f75ea72f36bb0ba1e42b3b2da98eb44a9dc12e7c7e8edfb52512b3b04016" + }, + { + "name": "workspace", + "state": { + "running": { + "startedAt": "2019-03-10T16:48:12Z" + } + }, + "lastState": {}, + "ready": true, + "restartCount": 0, + "image": "nginx:latest", + "imageID": "docker-pullable://nginx@sha256:98efe605f61725fd817ea69521b0eeb32bef007af0e3d0aeb6258c6e6fe7fc1a", + "containerID": "docker://e7080b843a47db414d6c94cfda7f657b99d8aa5bbf7c9c118ec98c0eefb6c0df" + } + ], + "qosClass": "Guaranteed" + } + }, + "theiaService": { + "metadata": { + "name": "foobas-theia", + "namespace": "default", + "selfLink": "/api/v1/namespaces/default/services/foobas-theia", + "uid": "48687212-4354-11e9-aee4-080027861af1", + "resourceVersion": "64923", + "creationTimestamp": "2019-03-10T16:48:08Z", + "labels": { + "gpwsman": "true", + "headless": "false", + "owner": "foobar", + "metaID": "metameta", + "workspaceID": "foobas" + } + }, + "spec": { + "ports": [ + { + "name": "theia", + "protocol": "TCP", + "port": 23000, + "targetPort": 23000 + } + ], + "selector": { + "gpwsman": "true", + "headless": "false", + "owner": "foobar", + "workspaceID": "foobas" + }, + "clusterIP": "10.103.194.121", + "type": "ClusterIP", + "sessionAffinity": "None" + }, + "status": { + "loadBalancer": {} + } + }, + "portsService": { + "metadata": { + "name": "foobas-ports", + "namespace": "default", + "selfLink": "/api/v1/namespaces/default/services/foobas-ports", + "uid": "486cb304-4354-11e9-aee4-080027861af1", + "resourceVersion": "64926", + "creationTimestamp": "2019-03-10T16:48:08Z", + "labels": { + "gpwsman": "true", + "workspaceID": "foobas" + } + }, + "spec": { + "ports": [ + { + "protocol": "TCP", + "port": 8080, + "targetPort": 8080 + } + ], + "selector": { + "gpwsman": "true", + "workspaceID": "foobas" + }, + "clusterIP": "10.110.184.222", + "type": "ClusterIP", + "sessionAffinity": "None" + }, + "status": { + "loadBalancer": {} + } + } + } +} \ No newline at end of file diff --git a/components/ws-manager/pkg/manager/testdata/timeout_prebuild_overdue.golden b/components/ws-manager/pkg/manager/testdata/timeout_prebuild_overdue.golden index 47ac38a1e9af1c..2465272fb2851c 100644 --- a/components/ws-manager/pkg/manager/testdata/timeout_prebuild_overdue.golden +++ b/components/ws-manager/pkg/manager/testdata/timeout_prebuild_overdue.golden @@ -1,3 +1,3 @@ { - "reason": "workspace timed out after running the headless workspace took longer than 01h40m" + "reason": "workspace timed out after running the headless workspace (01h40m) took longer than 01h30m" } \ No newline at end of file diff --git a/components/ws-manager/pkg/manager/testdata/timeout_probe_Creating00.golden b/components/ws-manager/pkg/manager/testdata/timeout_probe_Creating00.golden index 3a50c2307c6347..0d32a506162025 100644 --- a/components/ws-manager/pkg/manager/testdata/timeout_probe_Creating00.golden +++ b/components/ws-manager/pkg/manager/testdata/timeout_probe_Creating00.golden @@ -1,3 +1,3 @@ { - "reason": "workspace timed out after pulling images took longer than 00h50m" + "reason": "workspace timed out after pulling images (00h50m) took longer than 00h45m" } \ No newline at end of file diff --git a/components/ws-manager/pkg/manager/testdata/timeout_regular_closed.golden b/components/ws-manager/pkg/manager/testdata/timeout_regular_closed.golden index 4098c818305f23..1420ec41506b34 100644 --- a/components/ws-manager/pkg/manager/testdata/timeout_regular_closed.golden +++ b/components/ws-manager/pkg/manager/testdata/timeout_regular_closed.golden @@ -1,3 +1,3 @@ { - "reason": "workspace timed out after after being closed took longer than 00h10m" + "reason": "workspace timed out after after being closed (00h10m) took longer than 00h01m" } \ No newline at end of file diff --git a/components/ws-manager/pkg/manager/testdata/timeout_regular_noActivity.golden b/components/ws-manager/pkg/manager/testdata/timeout_regular_noActivity.golden index 95ca611c363491..a8ec852cbff538 100644 --- a/components/ws-manager/pkg/manager/testdata/timeout_regular_noActivity.golden +++ b/components/ws-manager/pkg/manager/testdata/timeout_regular_noActivity.golden @@ -1,3 +1,3 @@ { - "reason": "workspace timed out after period of inactivity took longer than 01h10m" + "reason": "workspace timed out after period of inactivity (01h10m) took longer than 00h45m" } \ No newline at end of file