diff --git a/components/operator/internal/handlers/reconciler.go b/components/operator/internal/handlers/reconciler.go index a6e079fa9..8ffe79905 100644 --- a/components/operator/internal/handlers/reconciler.go +++ b/components/operator/internal/handlers/reconciler.go @@ -203,6 +203,8 @@ func UpdateSessionFromPodStatus(ctx context.Context, session *unstructured.Unstr Reason: "Scheduled", Message: fmt.Sprintf("Scheduled on %s", pod.Spec.NodeName), }) + } else { + surfacePodSchedulingFailure(pod, statusPatch) } switch pod.Status.Phase { @@ -346,6 +348,24 @@ func EnsureFreshRunnerToken(ctx context.Context, session *unstructured.Unstructu return ensureFreshRunnerToken(ctx, session) } +// surfacePodSchedulingFailure checks pod conditions for scheduling failures +// and adds a PodScheduled=False condition to the status patch if found. +// This surfaces messages like "0/1 nodes are available: 1 Insufficient memory" +// so users can see why their session is stuck in Creating. +func surfacePodSchedulingFailure(pod *corev1.Pod, statusPatch *StatusPatch) { + for _, cond := range pod.Status.Conditions { + if cond.Type == corev1.PodScheduled && cond.Status == corev1.ConditionFalse { + statusPatch.AddCondition(conditionUpdate{ + Type: conditionPodScheduled, + Status: "False", + Reason: string(cond.Reason), + Message: cond.Message, + }) + return + } + } +} + // collectPodErrorMessage extracts detailed error information from a failed pod. func collectPodErrorMessage(pod *corev1.Pod) string { errorMsg := pod.Status.Message diff --git a/components/operator/internal/handlers/sessions.go b/components/operator/internal/handlers/sessions.go index 5183c13f6..b0fa77b2e 100644 --- a/components/operator/internal/handlers/sessions.go +++ b/components/operator/internal/handlers/sessions.go @@ -1755,6 +1755,8 @@ func monitorPod(podName, sessionName, sessionNamespace string) { if pod.Spec.NodeName != "" { statusPatch.AddCondition(conditionUpdate{Type: conditionPodScheduled, Status: "True", Reason: "Scheduled", Message: fmt.Sprintf("Scheduled on %s", pod.Spec.NodeName)}) + } else { + surfacePodSchedulingFailure(pod, statusPatch) } if pod.Status.Phase == corev1.PodSucceeded {