diff --git a/pkg/diag/validator/pod.go b/pkg/diag/validator/pod.go index 6a2614a9193..14717ee233d 100644 --- a/pkg/diag/validator/pod.go +++ b/pkg/diag/validator/pod.go @@ -38,6 +38,7 @@ const ( crashLoopBackOff = "CrashLoopBackOff" runContainerError = "RunContainerError" imagePullErr = "ErrImagePull" + imagePullBackOff = "ImagePullBackOff" errImagePullBackOff = "ErrImagePullBackOff" containerCreating = "ContainerCreating" podKind = "pod" @@ -202,14 +203,14 @@ func (p *podStatus) String() string { } func extractErrorMessageFromWaitingContainerStatus(c v1.ContainerStatus) (proto.StatusCode, error) { - // Extract meaning full error out of container statuses. switch c.State.Waiting.Reason { + // Extract meaning full error out of container statuses. case containerCreating: return proto.StatusCode_STATUSCHECK_CONTAINER_CREATING, fmt.Errorf("creating container %s", c.Name) case crashLoopBackOff: // TODO, in case of container restarting, return the original failure reason due to which container failed. return proto.StatusCode_STATUSCHECK_CONTAINER_RESTARTING, fmt.Errorf("restarting failed container %s", c.Name) - case imagePullErr, errImagePullBackOff: + case imagePullErr, imagePullBackOff, errImagePullBackOff: return proto.StatusCode_STATUSCHECK_IMAGE_PULL_ERR, fmt.Errorf("container %s is waiting to start: %s can't be pulled", c.Name, c.Image) case runContainerError: match := runContainerRe.FindStringSubmatch(c.State.Waiting.Message) diff --git a/pkg/diag/validator/pod_test.go b/pkg/diag/validator/pod_test.go index 48a8274edfa..4e34111b24e 100644 --- a/pkg/diag/validator/pod_test.go +++ b/pkg/diag/validator/pod_test.go @@ -75,6 +75,62 @@ func TestRun(t *testing.T) { fmt.Errorf("container foo-container is waiting to start: foo-image can't be pulled"), proto.StatusCode_STATUSCHECK_IMAGE_PULL_ERR)}, }, + { + description: "pod is Waiting condition due to ErrImageBackOffPullErr", + pods: []*v1.Pod{{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "test", + }, + Status: v1.PodStatus{ + Phase: v1.PodPending, + Conditions: []v1.PodCondition{{Type: v1.PodScheduled, Status: v1.ConditionTrue}}, + ContainerStatuses: []v1.ContainerStatus{ + { + Name: "foo-container", + Image: "foo-image", + State: v1.ContainerState{ + Waiting: &v1.ContainerStateWaiting{ + Reason: "ErrImagePullBackOff", + Message: "rpc error: code = Unknown desc = Error response from daemon: pull access denied for leeroy-web1, repository does not exist or may require 'docker login': denied: requested access to the resource is denied", + }, + }, + }, + }, + }, + }}, + expected: []Resource{NewResource("test", "pod", "foo", "Pending", + fmt.Errorf("container foo-container is waiting to start: foo-image can't be pulled"), + proto.StatusCode_STATUSCHECK_IMAGE_PULL_ERR)}, + }, + { + description: "pod is Waiting due to Image Backoff Pull error", + pods: []*v1.Pod{{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "test", + }, + Status: v1.PodStatus{ + Phase: v1.PodPending, + Conditions: []v1.PodCondition{{Type: v1.PodScheduled, Status: v1.ConditionTrue}}, + ContainerStatuses: []v1.ContainerStatus{ + { + Name: "foo-container", + Image: "foo-image", + State: v1.ContainerState{ + Waiting: &v1.ContainerStateWaiting{ + Reason: "ImagePullBackOff", + Message: "rpc error: code = Unknown desc = Error response from daemon: pull access denied for leeroy-web1, repository does not exist or may require 'docker login': denied: requested access to the resource is denied", + }, + }, + }, + }, + }, + }}, + expected: []Resource{NewResource("test", "pod", "foo", "Pending", + fmt.Errorf("container foo-container is waiting to start: foo-image can't be pulled"), + proto.StatusCode_STATUSCHECK_IMAGE_PULL_ERR)}, + }, { description: "pod is in Terminated State", pods: []*v1.Pod{{