Skip to content

Commit

Permalink
Bubble up the image related error reason to taskrun status
Browse files Browse the repository at this point in the history
When pod is pending because of failure of pulling image the users
can not get the clear reason or message from the taskrun status.

Now I will check the pod status and judge if the error is caused
by image if so the error reason and message will bubble up to
taskrun status. Then user can know what happend though the taskrun
status.

Related issue: tektoncd#4802

Signed-off-by: yuzhipeng <yuzp1996@qq.com>
  • Loading branch information
yuzp1996 committed May 18, 2022
1 parent f1ff83f commit a0df00c
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 0 deletions.
33 changes: 33 additions & 0 deletions pkg/pod/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ const (
// to resource constraints on the node
ReasonExceededNodeResources = "ExceededNodeResources"

// ReasonPullImageFailed indicates that the TaskRun's pod failed to pull image
ReasonPullImageFailed = "PullImageFailed"

// ReasonCreateContainerConfigError indicates that the TaskRun failed to create a pod due to
// config error of container
ReasonCreateContainerConfigError = "CreateContainerConfigError"
Expand Down Expand Up @@ -314,6 +317,8 @@ func updateIncompleteTaskRunStatus(trs *v1beta1.TaskRunStatus, pod *corev1.Pod)
markStatusRunning(trs, ReasonExceededNodeResources, "TaskRun Pod exceeded available resources")
case isPodHitConfigError(pod):
markStatusFailure(trs, ReasonCreateContainerConfigError, "Failed to create pod due to config error")
case isPullImageError(pod):
markStatusRunning(trs, ReasonPullImageFailed, getWaitingMessage(pod))
default:
markStatusRunning(trs, ReasonPending, getWaitingMessage(pod))
}
Expand Down Expand Up @@ -408,6 +413,34 @@ func isPodHitConfigError(pod *corev1.Pod) bool {
return false
}

// isPullImageError returns true if the Pod's status indicates there are any error when pulling image
func isPullImageError(pod *corev1.Pod) bool {
for _, containerStatus := range pod.Status.ContainerStatuses {
if containerStatus.State.Waiting != nil && isImageErrorReason(containerStatus.State.Waiting.Reason) {
return true
}
}
return false
}

func isImageErrorReason(reason string) bool {
// Reference from https://github.com/kubernetes/kubernetes/blob/a1c8e9386af844757333733714fa1757489735b3/pkg/kubelet/images/types.go#L26
imageErrorReasons := []string{
"ImagePullBackOff",
"ImageInspectError",
"ErrImagePull",
"ErrImageNeverPull",
"RegistryUnavailable",
"InvalidImageName",
}
for _, imageReason := range imageErrorReasons {
if imageReason == reason {
return true
}
}
return false
}

func getWaitingMessage(pod *corev1.Pod) string {
// First, try to surface reason for pending/unknown about the actual build step.
for _, status := range pod.Status.ContainerStatuses {
Expand Down
40 changes: 40 additions & 0 deletions pkg/pod/status_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -988,6 +988,46 @@ func TestMakeTaskRunStatus(t *testing.T) {
CompletionTime: &metav1.Time{Time: time.Now()},
},
},
}, {
desc: "when pod is pending because of pulling image then the error should bubble up to taskrun status",
pod: corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod",
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{{
Name: "step-first",
}},
},
Status: corev1.PodStatus{
Phase: corev1.PodPending,
ContainerStatuses: []corev1.ContainerStatus{{
Name: "step-first",
State: corev1.ContainerState{
Waiting: &corev1.ContainerStateWaiting{
Reason: "ImagePullBackOff",
Message: "Back-off pulling image xxxxxxx",
},
},
}},
},
},
want: v1beta1.TaskRunStatus{
Status: statusPending("PullImageFailed", `build step "step-first" is pending with reason "Back-off pulling image xxxxxxx"`),
TaskRunStatusFields: v1beta1.TaskRunStatusFields{
Steps: []v1beta1.StepState{{
ContainerState: corev1.ContainerState{
Waiting: &corev1.ContainerStateWaiting{
Reason: "ImagePullBackOff",
Message: "Back-off pulling image xxxxxxx",
},
},
Name: "first",
ContainerName: "step-first",
}},
Sidecars: []v1beta1.SidecarState{},
},
},
}} {
t.Run(c.desc, func(t *testing.T) {
now := metav1.Now()
Expand Down

0 comments on commit a0df00c

Please sign in to comment.