diff --git a/pkg/cmd/run/run.go b/pkg/cmd/run/run.go index 1b370f2b5..62820995c 100644 --- a/pkg/cmd/run/run.go +++ b/pkg/cmd/run/run.go @@ -381,17 +381,21 @@ func (o *RunOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e } var pod *corev1.Pod - leaveStdinOpen := o.LeaveStdinOpen - waitForExitCode := !leaveStdinOpen && restartPolicy == corev1.RestartPolicyNever + waitForExitCode := !o.LeaveStdinOpen && (restartPolicy == corev1.RestartPolicyNever || restartPolicy == corev1.RestartPolicyOnFailure) if waitForExitCode { - pod, err = waitForPod(clientset.CoreV1(), attachablePod.Namespace, attachablePod.Name, opts.GetPodTimeout, podCompleted) + // we need different exit condition depending on restart policy + // for Never it can either fail or succeed, for OnFailure only + // success matters + exitCondition := podCompleted + if restartPolicy == corev1.RestartPolicyOnFailure { + exitCondition = podSucceeded + } + pod, err = waitForPod(clientset.CoreV1(), attachablePod.Namespace, attachablePod.Name, opts.GetPodTimeout, exitCondition) if err != nil { return err } - } - - // after removal is done, return successfully if we are not interested in the exit code - if !waitForExitCode { + } else { + // after removal is done, return successfully if we are not interested in the exit code return nil } @@ -691,6 +695,20 @@ func podCompleted(event watch.Event) (bool, error) { return false, nil } +// podSucceeded returns true if the pod has run to completion, false if the pod has not yet +// reached running state, or an error in any other case. +func podSucceeded(event watch.Event) (bool, error) { + switch event.Type { + case watch.Deleted: + return false, errors.NewNotFound(schema.GroupResource{Resource: "pods"}, "") + } + switch t := event.Object.(type) { + case *corev1.Pod: + return t.Status.Phase == corev1.PodSucceeded, nil + } + return false, nil +} + // podRunningAndReady returns true if the pod is running and ready, false if the pod has not // yet reached those states, returns ErrPodCompleted if the pod has run to completion, or // an error in any other case.