Skip to content
This repository has been archived by the owner on Jul 11, 2023. It is now read-only.

Support multicontainer pods for status and crash reports #81

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 32 additions & 12 deletions k8s/informers/event/crash_report_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,20 @@ func (DefaultCrashReportGenerator) Generate(pod *v1.Pod, clientset kubernetes.In
return events.CrashReport{}, false
}

terminated := pod.Status.ContainerStatuses[0].State.Terminated
if terminated != nil && terminated.ExitCode != 0 {
return generateReportForTerminatedPod(pod, clientset, logger)
if status := getTerminatedContainerStatusIfAny(pod.Status.ContainerStatuses); status != nil {
return generateReportForTerminatedPod(pod, status, clientset, logger)
}

waiting := pod.Status.ContainerStatuses[0].State.Waiting
if waiting != nil && waiting.Reason == CrashLoopBackOff {
container := pod.Status.ContainerStatuses[0]
if container := getCrashedContainerStatusIfAny(pod.Status.ContainerStatuses); container != nil {
exitStatus := int(container.LastTerminationState.Terminated.ExitCode)
exitDescription := container.LastTerminationState.Terminated.Reason
crashTimestamp := int64(container.LastTerminationState.Terminated.StartedAt.Second())
return generateReport(pod, waiting.Reason, exitStatus, exitDescription, crashTimestamp)
return generateReport(pod, container.State.Waiting.Reason, exitStatus, exitDescription, crashTimestamp, int(container.RestartCount))
}
return events.CrashReport{}, false
}

func generateReportForTerminatedPod(pod *v1.Pod, clientset kubernetes.Interface, logger lager.Logger) (events.CrashReport, bool) {
func generateReportForTerminatedPod(pod *v1.Pod, status *v1.ContainerStatus, clientset kubernetes.Interface, logger lager.Logger) (events.CrashReport, bool) {
podEvents, err := k8s.GetEvents(clientset.CoreV1().Events(pod.Namespace), *pod)
if err != nil {
logger.Error("failed-to-get-k8s-events", err, lager.Data{"guid": pod.Annotations[k8s.AnnotationProcessGUID]})
Expand All @@ -50,8 +47,9 @@ func generateReportForTerminatedPod(pod *v1.Pod, clientset kubernetes.Interface,
return events.CrashReport{}, false
}

terminated := pod.Status.ContainerStatuses[0].State.Terminated
return generateReport(pod, terminated.Reason, int(terminated.ExitCode), terminated.Reason, int64(terminated.StartedAt.Second()))
terminated := status.State.Terminated

return generateReport(pod, terminated.Reason, int(terminated.ExitCode), terminated.Reason, int64(terminated.StartedAt.Second()), int(status.RestartCount))
}

func generateReport(
Expand All @@ -60,9 +58,9 @@ func generateReport(
exitStatus int,
exitDescription string,
crashTimestamp int64,
restartCount int,
) (events.CrashReport, bool) {
index, _ := util.ParseAppIndex(pod.Name)
container := pod.Status.ContainerStatuses[0]

return events.CrashReport{
ProcessGUID: pod.Annotations[k8s.AnnotationProcessGUID],
Expand All @@ -73,7 +71,29 @@ func generateReport(
ExitStatus: exitStatus,
ExitDescription: exitDescription,
CrashTimestamp: crashTimestamp,
CrashCount: int(container.RestartCount),
CrashCount: restartCount,
},
}, true
}

func getTerminatedContainerStatusIfAny(statuses []v1.ContainerStatus) *v1.ContainerStatus {
for _, status := range statuses {
terminated := status.State.Terminated
if terminated != nil && terminated.ExitCode != 0 {
return &status
}
}

return nil
}

func getCrashedContainerStatusIfAny(statuses []v1.ContainerStatus) *v1.ContainerStatus {
for _, status := range statuses {
waiting := status.State.Waiting
if waiting != nil && waiting.Reason == CrashLoopBackOff {
return &status
}
}

return nil
}
Loading