fixed output and completed pod phase

Signed-off-by: Suleiman Dibirov <idsulik@gmail.com>
pull/13121/head
Suleiman Dibirov 2 weeks ago
parent 8a7581f03f
commit 56fc24668f

@ -19,7 +19,9 @@ package kube // import "helm.sh/helm/v3/pkg/kube"
import (
"context"
"fmt"
"strings"
"github.com/hashicorp/go-multierror"
appsv1 "k8s.io/api/apps/v1"
appsv1beta1 "k8s.io/api/apps/v1beta1"
appsv1beta2 "k8s.io/api/apps/v1beta2"
@ -38,13 +40,6 @@ import (
deploymentutil "helm.sh/helm/v3/internal/third_party/k8s.io/kubernetes/deployment/util"
)
type podError struct {
podName string
container string
reason string
message string
}
// ReadyCheckerOption is a function that configures a ReadyChecker.
type ReadyCheckerOption func(*ReadyChecker)
@ -100,12 +95,11 @@ func (c *ReadyChecker) IsReady(ctx context.Context, v *resource.Info) (bool, err
switch value := AsVersioned(v).(type) {
case *corev1.Pod:
pod, err := c.client.CoreV1().Pods(v.Namespace).Get(ctx, v.Name, metav1.GetOptions{})
if err != nil || !c.isPodReady(pod) {
if err == nil {
err = c.getPodFailedError(pod)
}
if err != nil {
return false, err
}
ready, err := c.isPodReady(pod)
return ready, err
case *batchv1.Job:
if c.checkJobs {
job, err := c.client.BatchV1().Jobs(v.Namespace).Get(ctx, v.Name, metav1.GetOptions{})
@ -215,7 +209,7 @@ func (c *ReadyChecker) IsReady(ctx context.Context, v *resource.Info) (bool, err
}
func (c *ReadyChecker) getPodFailedError(pod *corev1.Pod) error {
podErrors := make([]podError, 0)
var err error
if pod.Status.Phase == corev1.PodFailed {
containerStatuses := pod.Status.ContainerStatuses
if pod.Status.InitContainerStatuses != nil {
@ -224,28 +218,32 @@ func (c *ReadyChecker) getPodFailedError(pod *corev1.Pod) error {
for _, cs := range containerStatuses {
if cs.State.Terminated != nil {
podErrors = append(podErrors, podError{
podName: pod.Name,
container: cs.Name,
reason: cs.State.Terminated.Reason,
message: cs.State.Terminated.Message,
})
err = multierror.Append(
err,
fmt.Errorf(
"pod: %q, container: %q. reason: %q. message: %q",
pod.Name,
cs.Name,
cs.State.Terminated.Reason,
strings.TrimSpace(cs.State.Terminated.Message),
),
)
} else if cs.State.Waiting != nil {
podErrors = append(podErrors, podError{
podName: pod.Name,
container: cs.Name,
reason: cs.State.Waiting.Reason,
message: cs.State.Waiting.Message,
})
err = multierror.Append(
err,
fmt.Errorf(
"pod: %q, container: %q. reason: %q. message: %q",
pod.Name,
cs.Name,
cs.State.Waiting.Reason,
strings.TrimSpace(cs.State.Waiting.Message),
),
)
}
}
}
if len(podErrors) > 0 {
return fmt.Errorf("%+v", podErrors)
}
return nil
return err
}
func (c *ReadyChecker) podsReadyForObject(ctx context.Context, namespace string, obj runtime.Object) (bool, error) {
@ -254,8 +252,8 @@ func (c *ReadyChecker) podsReadyForObject(ctx context.Context, namespace string,
return false, err
}
for _, pod := range pods {
if !c.isPodReady(&pod) {
return false, nil
if isReady, err := c.isPodReady(&pod); !isReady {
return false, err
}
}
return true, nil
@ -270,15 +268,26 @@ func (c *ReadyChecker) podsforObject(ctx context.Context, namespace string, obj
return list, err
}
// isPodReady returns true if a pod is ready; false otherwise.
func (c *ReadyChecker) isPodReady(pod *corev1.Pod) bool {
for _, c := range pod.Status.Conditions {
if c.Type == corev1.PodReady && c.Status == corev1.ConditionTrue {
return true
// isPodReady returns true if the pod is ready, false if it is not ready, and an error if the pod is in a failed state.
func (c *ReadyChecker) isPodReady(pod *corev1.Pod) (bool, error) {
if pod.Status.Phase == corev1.PodSucceeded {
return true, nil
}
err := c.getPodFailedError(pod)
if err != nil {
c.log("Pod is failed: %s/%s", pod.GetNamespace(), pod.GetName())
return false, err
}
for _, condition := range pod.Status.Conditions {
if condition.Type == corev1.PodReady && condition.Status == corev1.ConditionTrue {
return true, nil
}
}
c.log("Pod is not ready: %s/%s", pod.GetNamespace(), pod.GetName())
return false
return false, nil
}
func (c *ReadyChecker) jobReady(job *batchv1.Job) (bool, error) {

Loading…
Cancel
Save