From 2a53330700ac39ee61109c748fe665cf38581a5d Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Mon, 2 May 2016 18:08:15 -0400 Subject: [PATCH] Describe and get should show init containers --- pkg/api/resource_helpers.go | 23 +++++++++++++ pkg/kubectl/describe.go | 18 ++++++++--- pkg/kubectl/describe_test.go | 2 +- pkg/kubectl/resource_printer.go | 57 +++++++++++++++++++++++++-------- 4 files changed, 81 insertions(+), 19 deletions(-) diff --git a/pkg/api/resource_helpers.go b/pkg/api/resource_helpers.go index af1189b4fb3..74bc1720c93 100644 --- a/pkg/api/resource_helpers.go +++ b/pkg/api/resource_helpers.go @@ -163,5 +163,28 @@ func PodRequestsAndLimits(pod *Pod) (reqs map[ResourceName]resource.Quantity, li } } } + // init containers define the minimum of any resource + for _, container := range pod.Spec.InitContainers { + for name, quantity := range container.Resources.Requests { + value, ok := reqs[name] + if !ok { + reqs[name] = *quantity.Copy() + continue + } + if quantity.Cmp(value) > 0 { + reqs[name] = *quantity.Copy() + } + } + for name, quantity := range container.Resources.Limits { + value, ok := limits[name] + if !ok { + limits[name] = *quantity.Copy() + continue + } + if quantity.Cmp(value) > 0 { + limits[name] = *quantity.Copy() + } + } + } return } diff --git a/pkg/kubectl/describe.go b/pkg/kubectl/describe.go index c0189f56041..2b11114abe6 100644 --- a/pkg/kubectl/describe.go +++ b/pkg/kubectl/describe.go @@ -524,7 +524,10 @@ func describePod(pod *api.Pod, events *api.EventList) (string, error) { } fmt.Fprintf(out, "IP:\t%s\n", pod.Status.PodIP) fmt.Fprintf(out, "Controllers:\t%s\n", printControllers(pod.Annotations)) - describeContainers(pod.Spec.Containers, pod.Status.ContainerStatuses, EnvValueRetriever(pod), out, "") + if len(pod.Spec.InitContainers) > 0 { + describeContainers("Init Containers", pod.Spec.InitContainers, pod.Status.InitContainerStatuses, EnvValueRetriever(pod), out, "") + } + describeContainers("Containers", pod.Spec.Containers, pod.Status.ContainerStatuses, EnvValueRetriever(pod), out, "") if len(pod.Status.Conditions) > 0 { fmt.Fprint(out, "Conditions:\n Type\tStatus\n") for _, c := range pod.Status.Conditions { @@ -782,12 +785,16 @@ func (d *PersistentVolumeClaimDescriber) Describe(namespace, name string, descri } // TODO: Do a better job at indenting, maybe by using a prefix writer -func describeContainers(containers []api.Container, containerStatuses []api.ContainerStatus, resolverFn EnvVarResolverFunc, out io.Writer, space string) { +func describeContainers(label string, containers []api.Container, containerStatuses []api.ContainerStatus, resolverFn EnvVarResolverFunc, out io.Writer, space string) { statuses := map[string]api.ContainerStatus{} for _, status := range containerStatuses { statuses[status.Name] = status } - fmt.Fprintf(out, "%sContainers:\n", space) + if len(containers) == 0 { + fmt.Fprintf(out, "%s%s: \n", space, label) + } else { + fmt.Fprintf(out, "%s%s:\n", space, label) + } for _, container := range containers { status, ok := statuses[container.Name] nameIndent := "" @@ -1037,7 +1044,10 @@ func DescribePodTemplate(template *api.PodTemplateSpec, out io.Writer) { if len(template.Spec.ServiceAccountName) > 0 { fmt.Fprintf(out, " Service Account:\t%s\n", template.Spec.ServiceAccountName) } - describeContainers(template.Spec.Containers, nil, nil, out, " ") + if len(template.Spec.InitContainers) > 0 { + describeContainers("Init Containers", template.Spec.InitContainers, nil, nil, out, " ") + } + describeContainers("Containers", template.Spec.Containers, nil, nil, out, " ") describeVolumes(template.Spec.Volumes, out, " ") } diff --git a/pkg/kubectl/describe_test.go b/pkg/kubectl/describe_test.go index f073d3050cd..429216da92d 100644 --- a/pkg/kubectl/describe_test.go +++ b/pkg/kubectl/describe_test.go @@ -268,7 +268,7 @@ func TestDescribeContainers(t *testing.T) { ContainerStatuses: []api.ContainerStatus{testCase.status}, }, } - describeContainers(pod.Spec.Containers, pod.Status.ContainerStatuses, EnvValueRetriever(&pod), out, "") + describeContainers("Containers", pod.Spec.Containers, pod.Status.ContainerStatuses, EnvValueRetriever(&pod), out, "") output := out.String() for _, expected := range testCase.expectedElements { if !strings.Contains(output, expected) { diff --git a/pkg/kubectl/resource_printer.go b/pkg/kubectl/resource_printer.go index e29a952d27c..c0811806c60 100644 --- a/pkg/kubectl/resource_printer.go +++ b/pkg/kubectl/resource_printer.go @@ -594,22 +594,51 @@ func printPodBase(pod *api.Pod, w io.Writer, options PrintOptions) error { reason = pod.Status.Reason } - for i := len(pod.Status.ContainerStatuses) - 1; i >= 0; i-- { - container := pod.Status.ContainerStatuses[i] - - restarts += int(container.RestartCount) - if container.State.Waiting != nil && container.State.Waiting.Reason != "" { - reason = container.State.Waiting.Reason - } else if container.State.Terminated != nil && container.State.Terminated.Reason != "" { - reason = container.State.Terminated.Reason - } else if container.State.Terminated != nil && container.State.Terminated.Reason == "" { - if container.State.Terminated.Signal != 0 { - reason = fmt.Sprintf("Signal:%d", container.State.Terminated.Signal) + initializing := false + for i := range pod.Status.InitContainerStatuses { + container := pod.Status.InitContainerStatuses[i] + switch { + case container.State.Terminated != nil && container.State.Terminated.ExitCode == 0: + continue + case container.State.Terminated != nil: + // initialization is failed + if len(container.State.Terminated.Reason) == 0 { + if container.State.Terminated.Signal != 0 { + reason = fmt.Sprintf("Init:Signal:%d", container.State.Terminated.Signal) + } else { + reason = fmt.Sprintf("Init:ExitCode:%d", container.State.Terminated.ExitCode) + } } else { - reason = fmt.Sprintf("ExitCode:%d", container.State.Terminated.ExitCode) + reason = "Init:" + container.State.Terminated.Reason + } + initializing = true + case container.State.Waiting != nil && len(container.State.Waiting.Reason) > 0 && container.State.Waiting.Reason != "PodInitializing": + reason = "Init:" + container.State.Waiting.Reason + initializing = true + default: + reason = fmt.Sprintf("Init:%d/%d", i, len(pod.Spec.InitContainers)) + initializing = true + } + break + } + if !initializing { + for i := len(pod.Status.ContainerStatuses) - 1; i >= 0; i-- { + container := pod.Status.ContainerStatuses[i] + + restarts += int(container.RestartCount) + if container.State.Waiting != nil && container.State.Waiting.Reason != "" { + reason = container.State.Waiting.Reason + } else if container.State.Terminated != nil && container.State.Terminated.Reason != "" { + reason = container.State.Terminated.Reason + } else if container.State.Terminated != nil && container.State.Terminated.Reason == "" { + if container.State.Terminated.Signal != 0 { + reason = fmt.Sprintf("Signal:%d", container.State.Terminated.Signal) + } else { + reason = fmt.Sprintf("ExitCode:%d", container.State.Terminated.ExitCode) + } + } else if container.Ready && container.State.Running != nil { + readyContainers++ } - } else if container.Ready && container.State.Running != nil { - readyContainers++ } } if pod.DeletionTimestamp != nil {