diff --git a/agent/job_runner.go b/agent/job_runner.go index 2cd243a50f..17fa784fef 100644 --- a/agent/job_runner.go +++ b/agent/job_runner.go @@ -404,6 +404,18 @@ func (r *JobRunner) Run(ctx context.Context) error { exitStatus = "-1" signalReason = "process_run_error" } else { + // Intended to capture situations where the job-exec (aka bootstrap) container did not + // start. Normally such errors are hidden in the Kubernetes events. Let's feed them up + // to the user as they may be the caused by errors in the pipeline definition. + if r.cancelled && !r.stopped { + k8sProcess, ok := r.process.(*kubernetes.Runner) + if ok && k8sProcess.ClientStateUnknown() { + r.logStreamer.Process([]byte( + "Some containers had unknown exit statuses. Perhaps they were in ImagePullBackOff.", + )) + } + } + // Add the final output to the streamer r.logStreamer.Process(r.output.ReadAndTruncate()) diff --git a/kubernetes/kubernetes.go b/kubernetes/kubernetes.go index 3d64d59011..93e38dd564 100644 --- a/kubernetes/kubernetes.go +++ b/kubernetes/kubernetes.go @@ -159,17 +159,29 @@ func (w waitStatus) Signaled() bool { } func (r *Runner) WaitStatus() process.WaitStatus { - var ws process.WaitStatus + ws := waitStatus{} for _, client := range r.clients { if client.ExitStatus != 0 { return waitStatus{Code: client.ExitStatus} } - // just return any ExitStatus if we don't find any "interesting" ones - ws = waitStatus{Code: client.ExitStatus} + + // use an unusual status code to distinguish this unusual state + if client.State == stateUnknown { + ws.Code -= 10 + } } return ws } +func (r *Runner) ClientStateUnknown() bool { + for _, client := range r.clients { + if client.State == stateUnknown { + return true + } + } + return false +} + // ==== sidecar api ==== type Empty struct{}