Skip to content

Commit

Permalink
fix: get status of init containers in pods-info API call (#2371)
Browse files Browse the repository at this point in the history
  • Loading branch information
adarsh0728 authored Jan 29, 2025
1 parent 5d60431 commit d4e5859
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 6 deletions.
49 changes: 44 additions & 5 deletions server/apis/v1/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -1643,8 +1643,16 @@ func (h *handler) getPodDetails(pod corev1.Pod) (PodDetails, error) {
}

func (h *handler) getContainerDetails(pod corev1.Pod) map[string]ContainerDetails {
var containerDetailsMap = make(map[string]ContainerDetails)
for _, status := range pod.Status.ContainerStatuses {
totalContainers := len(pod.Spec.Containers) + len(pod.Spec.InitContainers)
containerDetailsMap := make(map[string]ContainerDetails, totalContainers)

// Helper function to process container statuses
processContainerStatus := func(status corev1.ContainerStatus, isInitContainer bool) {
// Skip init containers without Always restart policy
if isInitContainer && h.isNotSidecarContainer(status.Name, pod) {
return
}

containerName := status.Name
details := ContainerDetails{
Name: status.Name,
Expand All @@ -1666,13 +1674,25 @@ func (h *handler) getContainerDetails(pod corev1.Pod) map[string]ContainerDetail
containerDetailsMap[containerName] = details
}

// Get CPU/Memory requests and limits from Pod spec
for _, container := range pod.Spec.Containers {
for _, status := range pod.Status.InitContainerStatuses {
processContainerStatus(status, true)
}
for _, status := range pod.Status.ContainerStatuses {
processContainerStatus(status, false)
}

// Helper function to process container resources
processContainerResources := func(container corev1.Container, isInitContainer bool) {
// Skip init containers without Always restart policy
if isInitContainer && h.isNotSidecarContainer(container.Name, pod) {
return
}

cpuRequest := container.Resources.Requests.Cpu().MilliValue()
memRequest := container.Resources.Requests.Memory().Value() / (1024 * 1024)
cpuLimit := container.Resources.Limits.Cpu().MilliValue()
memLimit := container.Resources.Limits.Memory().Value() / (1024 * 1024)
// Get the existing ContainerDetails or create a new one

details, ok := containerDetailsMap[container.Name]
if !ok {
details = ContainerDetails{Name: container.Name} // Initialize if not found
Expand All @@ -1691,9 +1711,28 @@ func (h *handler) getContainerDetails(pod corev1.Pod) map[string]ContainerDetail
}
containerDetailsMap[container.Name] = details
}

for _, container := range pod.Spec.InitContainers {
processContainerResources(container, true)
}
for _, container := range pod.Spec.Containers {
processContainerResources(container, false)
}

return containerDetailsMap
}

// Helper function to check if container is an init container without "Always" restart policy
// for sidecar containers (eg: ud containers), we set "Always" restart policy in k8s >= 1.29
func (h *handler) isNotSidecarContainer(containerName string, pod corev1.Pod) bool {
for _, initContainer := range pod.Spec.InitContainers {
if initContainer.Name == containerName {
return initContainer.RestartPolicy == nil || *initContainer.RestartPolicy != corev1.ContainerRestartPolicyAlways
}
}
return true
}

func (h *handler) getContainerStatus(state corev1.ContainerState) string {
if state.Running != nil {
return "Running"
Expand Down
63 changes: 63 additions & 0 deletions server/apis/v1/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1028,3 +1028,66 @@ func TestHandler_GetContainerStatus(t *testing.T) {
})
}
}

func TestHandler_IsNotSidecarContainer(t *testing.T) {
handler := &handler{}

tests := []struct {
name string
containerName string
pod corev1.Pod
expected bool
}{
{
name: "Init container with Always restart policy",
containerName: "init-container-1",
pod: corev1.Pod{
Spec: corev1.PodSpec{
InitContainers: []corev1.Container{
{
Name: "init-container-1",
RestartPolicy: func() *corev1.ContainerRestartPolicy { p := corev1.ContainerRestartPolicyAlways; return &p }(),
},
},
},
},
expected: false,
},
{
name: "Container not in init containers",
containerName: "app-container",
pod: corev1.Pod{
Spec: corev1.PodSpec{
InitContainers: []corev1.Container{
{
Name: "init-container-1",
},
},
},
},
expected: true,
},
{
name: "Init container with nil RestartPolicy",
containerName: "init-container-3",
pod: corev1.Pod{
Spec: corev1.PodSpec{
InitContainers: []corev1.Container{
{
Name: "init-container-3",
RestartPolicy: nil,
},
},
},
},
expected: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := handler.isNotSidecarContainer(tt.containerName, tt.pod)
assert.Equal(t, tt.expected, result)
})
}
}
2 changes: 1 addition & 1 deletion ui/src/utils/fetcherHooks/podsViewFetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export const usePodsViewFetch = (
JSON.stringify(pod?.spec?.containers)
);
pod?.spec?.initContainers
?.filter((initContainer: any) => initContainer?.name !== "init")
?.filter((initContainer: any) => initContainer?.restartPolicy === "Always")
?.forEach((container: any) => containersList.push(container));

containersList?.forEach((container: any) => {
Expand Down

0 comments on commit d4e5859

Please sign in to comment.