@@ -16,6 +16,7 @@ import (
16
16
"golang.org/x/xerrors"
17
17
corev1 "k8s.io/api/core/v1"
18
18
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
19
+ "k8s.io/apimachinery/pkg/types"
19
20
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
20
21
"sigs.k8s.io/controller-runtime/pkg/log"
21
22
)
@@ -91,7 +92,7 @@ func (r *WorkspaceReconciler) updateWorkspaceStatus(ctx context.Context, workspa
91
92
workspace .Status .OwnerToken = ownerToken
92
93
}
93
94
94
- failure , phase := extractFailure (workspace , pod )
95
+ failure , phase := r . extractFailure (ctx , workspace , pod )
95
96
if phase != nil {
96
97
workspace .Status .Phase = * phase
97
98
}
@@ -193,7 +194,7 @@ func isDisposalFinished(ws *workspacev1.Workspace) bool {
193
194
// extractFailure returns a pod failure reason and possibly a phase. If phase is nil then
194
195
// one should extract the phase themselves. If the pod has not failed, this function returns "", nil.
195
196
// This failure is then stored in the Failed condition on the workspace.
196
- func extractFailure (ws * workspacev1.Workspace , pod * corev1.Pod ) (string , * workspacev1.WorkspacePhase ) {
197
+ func ( r * WorkspaceReconciler ) extractFailure (ctx context. Context , ws * workspacev1.Workspace , pod * corev1.Pod ) (string , * workspacev1.WorkspacePhase ) {
197
198
// Check for content init failure.
198
199
if c := wsk8s .GetCondition (ws .Status .Conditions , string (workspacev1 .WorkspaceConditionContentReady )); c != nil {
199
200
if c .Status == metav1 .ConditionFalse && c .Reason == workspacev1 .ReasonInitializationFailure {
@@ -250,6 +251,18 @@ func extractFailure(ws *workspacev1.Workspace, pod *corev1.Pod) (string, *worksp
250
251
phase = workspacev1 .WorkspacePhaseRunning
251
252
}
252
253
254
+ if terminationState .ExitCode == containerKilledExitCode && terminationState .Reason == "ContainerStatusUnknown" {
255
+ // For some reason, the pod is killed with unknown container status and no taints on the underlying node.
256
+ // Therefore, we skip extracting the failure from the terminated message.
257
+ // ref: https://github.com/gitpod-io/gitpod/issues/12021
258
+ var node corev1.Node
259
+ if ws .Status .Runtime != nil && ws .Status .Runtime .NodeName != "" {
260
+ if err := r .Get (ctx , types.NamespacedName {Namespace : "" , Name : ws .Status .Runtime .NodeName }, & node ); err == nil && len (node .Spec .Taints ) == 0 {
261
+ return "" , nil
262
+ }
263
+ }
264
+ }
265
+
253
266
// the container itself told us why it was terminated - use that as failure reason
254
267
return extractFailureFromLogs ([]byte (terminationState .Message )), & phase
255
268
} else if terminationState .Reason == "Error" {
0 commit comments