mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-11-04 07:49:35 +00:00 
			
		
		
		
	Show resource limits with describe
Signed-off-by: Jason Sommer <jsdirv@gmail.com>
This commit is contained in:
		@@ -274,7 +274,7 @@ func describePod(pod *api.Pod, rcs []api.ReplicationController, events *api.Even
 | 
			
		||||
		fmt.Fprintf(out, "Status:\t%s\n", string(pod.Status.Phase))
 | 
			
		||||
		fmt.Fprintf(out, "Replication Controllers:\t%s\n", printReplicationControllersByLabels(rcs))
 | 
			
		||||
		fmt.Fprintf(out, "Containers:\n")
 | 
			
		||||
		describeContainers(pod.Status.ContainerStatuses, out)
 | 
			
		||||
		describeContainers(pod, out)
 | 
			
		||||
		if len(pod.Status.Conditions) > 0 {
 | 
			
		||||
			fmt.Fprint(out, "Conditions:\n  Type\tStatus\n")
 | 
			
		||||
			for _, c := range pod.Status.Conditions {
 | 
			
		||||
@@ -336,39 +336,55 @@ func (d *PersistentVolumeClaimDescriber) Describe(namespace, name string) (strin
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func describeContainers(containers []api.ContainerStatus, out io.Writer) {
 | 
			
		||||
	for _, container := range containers {
 | 
			
		||||
func describeContainers(pod *api.Pod, out io.Writer) {
 | 
			
		||||
	statuses := map[string]api.ContainerStatus{}
 | 
			
		||||
	for _, status := range pod.Status.ContainerStatuses {
 | 
			
		||||
		statuses[status.Name] = status
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, container := range pod.Spec.Containers {
 | 
			
		||||
		status := statuses[container.Name]
 | 
			
		||||
		state := status.State
 | 
			
		||||
 | 
			
		||||
		fmt.Fprintf(out, "  %v:\n", container.Name)
 | 
			
		||||
		fmt.Fprintf(out, "    Image:\t%s\n", container.Image)
 | 
			
		||||
 | 
			
		||||
		if len(container.Resources.Limits) > 0 {
 | 
			
		||||
			fmt.Fprintf(out, "    Limits:\n")
 | 
			
		||||
		}
 | 
			
		||||
		for name, quantity := range container.Resources.Limits {
 | 
			
		||||
			fmt.Fprintf(out, "      %s:\t%s\n", name, quantity.String())
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		switch {
 | 
			
		||||
		case container.State.Running != nil:
 | 
			
		||||
		case state.Running != nil:
 | 
			
		||||
			fmt.Fprintf(out, "    State:\tRunning\n")
 | 
			
		||||
			fmt.Fprintf(out, "      Started:\t%v\n", container.State.Running.StartedAt.Time.Format(time.RFC1123Z))
 | 
			
		||||
		case container.State.Waiting != nil:
 | 
			
		||||
			fmt.Fprintf(out, "      Started:\t%v\n", state.Running.StartedAt.Time.Format(time.RFC1123Z))
 | 
			
		||||
		case state.Waiting != nil:
 | 
			
		||||
			fmt.Fprintf(out, "    State:\tWaiting\n")
 | 
			
		||||
			if container.State.Waiting.Reason != "" {
 | 
			
		||||
				fmt.Fprintf(out, "      Reason:\t%s\n", container.State.Waiting.Reason)
 | 
			
		||||
			if state.Waiting.Reason != "" {
 | 
			
		||||
				fmt.Fprintf(out, "      Reason:\t%s\n", state.Waiting.Reason)
 | 
			
		||||
			}
 | 
			
		||||
		case container.State.Terminated != nil:
 | 
			
		||||
		case state.Terminated != nil:
 | 
			
		||||
			fmt.Fprintf(out, "    State:\tTerminated\n")
 | 
			
		||||
			if container.State.Terminated.Reason != "" {
 | 
			
		||||
				fmt.Fprintf(out, "      Reason:\t%s\n", container.State.Terminated.Reason)
 | 
			
		||||
			if state.Terminated.Reason != "" {
 | 
			
		||||
				fmt.Fprintf(out, "      Reason:\t%s\n", state.Terminated.Reason)
 | 
			
		||||
			}
 | 
			
		||||
			if container.State.Terminated.Message != "" {
 | 
			
		||||
				fmt.Fprintf(out, "      Message:\t%s\n", container.State.Terminated.Message)
 | 
			
		||||
			if state.Terminated.Message != "" {
 | 
			
		||||
				fmt.Fprintf(out, "      Message:\t%s\n", state.Terminated.Message)
 | 
			
		||||
			}
 | 
			
		||||
			fmt.Fprintf(out, "      Exit Code:\t%d\n", container.State.Terminated.ExitCode)
 | 
			
		||||
			if container.State.Terminated.Signal > 0 {
 | 
			
		||||
				fmt.Fprintf(out, "      Signal:\t%d\n", container.State.Terminated.Signal)
 | 
			
		||||
			fmt.Fprintf(out, "      Exit Code:\t%d\n", state.Terminated.ExitCode)
 | 
			
		||||
			if state.Terminated.Signal > 0 {
 | 
			
		||||
				fmt.Fprintf(out, "      Signal:\t%d\n", state.Terminated.Signal)
 | 
			
		||||
			}
 | 
			
		||||
			fmt.Fprintf(out, "      Started:\t%s\n", container.State.Terminated.StartedAt.Time.Format(time.RFC1123Z))
 | 
			
		||||
			fmt.Fprintf(out, "      Finished:\t%s\n", container.State.Terminated.FinishedAt.Time.Format(time.RFC1123Z))
 | 
			
		||||
			fmt.Fprintf(out, "      Started:\t%s\n", state.Terminated.StartedAt.Time.Format(time.RFC1123Z))
 | 
			
		||||
			fmt.Fprintf(out, "      Finished:\t%s\n", state.Terminated.FinishedAt.Time.Format(time.RFC1123Z))
 | 
			
		||||
		default:
 | 
			
		||||
			fmt.Fprintf(out, "    State:\tWaiting\n")
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		fmt.Fprintf(out, "    Ready:\t%v\n", printBool(container.Ready))
 | 
			
		||||
		fmt.Fprintf(out, "    Restart Count:\t%d\n", container.RestartCount)
 | 
			
		||||
		fmt.Fprintf(out, "    Ready:\t%v\n", printBool(status.Ready))
 | 
			
		||||
		fmt.Fprintf(out, "    Restart Count:\t%d\n", status.RestartCount)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -25,6 +25,7 @@ import (
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
			
		||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
 | 
			
		||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
 | 
			
		||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/client/testclient"
 | 
			
		||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
 | 
			
		||||
@@ -119,12 +120,14 @@ func TestPodDescribeResultsSorted(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
func TestDescribeContainers(t *testing.T) {
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		input            api.ContainerStatus
 | 
			
		||||
		container        api.Container
 | 
			
		||||
		status           api.ContainerStatus
 | 
			
		||||
		expectedElements []string
 | 
			
		||||
	}{
 | 
			
		||||
		// Running state.
 | 
			
		||||
		{
 | 
			
		||||
			input: api.ContainerStatus{
 | 
			
		||||
			container: api.Container{Name: "test", Image: "image"},
 | 
			
		||||
			status: api.ContainerStatus{
 | 
			
		||||
				Name: "test",
 | 
			
		||||
				State: api.ContainerState{
 | 
			
		||||
					Running: &api.ContainerStateRunning{
 | 
			
		||||
@@ -133,13 +136,13 @@ func TestDescribeContainers(t *testing.T) {
 | 
			
		||||
				},
 | 
			
		||||
				Ready:        true,
 | 
			
		||||
				RestartCount: 7,
 | 
			
		||||
				Image:        "image",
 | 
			
		||||
			},
 | 
			
		||||
			expectedElements: []string{"test", "State", "Running", "Ready", "True", "Restart Count", "7", "Image", "image", "Started"},
 | 
			
		||||
		},
 | 
			
		||||
		// Waiting state.
 | 
			
		||||
		{
 | 
			
		||||
			input: api.ContainerStatus{
 | 
			
		||||
			container: api.Container{Name: "test", Image: "image"},
 | 
			
		||||
			status: api.ContainerStatus{
 | 
			
		||||
				Name: "test",
 | 
			
		||||
				State: api.ContainerState{
 | 
			
		||||
					Waiting: &api.ContainerStateWaiting{
 | 
			
		||||
@@ -148,13 +151,13 @@ func TestDescribeContainers(t *testing.T) {
 | 
			
		||||
				},
 | 
			
		||||
				Ready:        true,
 | 
			
		||||
				RestartCount: 7,
 | 
			
		||||
				Image:        "image",
 | 
			
		||||
			},
 | 
			
		||||
			expectedElements: []string{"test", "State", "Waiting", "Ready", "True", "Restart Count", "7", "Image", "image", "Reason", "potato"},
 | 
			
		||||
		},
 | 
			
		||||
		// Terminated state.
 | 
			
		||||
		{
 | 
			
		||||
			input: api.ContainerStatus{
 | 
			
		||||
			container: api.Container{Name: "test", Image: "image"},
 | 
			
		||||
			status: api.ContainerStatus{
 | 
			
		||||
				Name: "test",
 | 
			
		||||
				State: api.ContainerState{
 | 
			
		||||
					Terminated: &api.ContainerStateTerminated{
 | 
			
		||||
@@ -166,25 +169,52 @@ func TestDescribeContainers(t *testing.T) {
 | 
			
		||||
				},
 | 
			
		||||
				Ready:        true,
 | 
			
		||||
				RestartCount: 7,
 | 
			
		||||
				Image:        "image",
 | 
			
		||||
			},
 | 
			
		||||
			expectedElements: []string{"test", "State", "Terminated", "Ready", "True", "Restart Count", "7", "Image", "image", "Reason", "potato", "Started", "Finished", "Exit Code", "2"},
 | 
			
		||||
		},
 | 
			
		||||
		// No state defaults to waiting.
 | 
			
		||||
		{
 | 
			
		||||
			input: api.ContainerStatus{
 | 
			
		||||
			container: api.Container{Name: "test", Image: "image"},
 | 
			
		||||
			status: api.ContainerStatus{
 | 
			
		||||
				Name:         "test",
 | 
			
		||||
				Ready:        true,
 | 
			
		||||
				RestartCount: 7,
 | 
			
		||||
				Image:        "image",
 | 
			
		||||
			},
 | 
			
		||||
			expectedElements: []string{"test", "State", "Waiting", "Ready", "True", "Restart Count", "7", "Image", "image"},
 | 
			
		||||
		},
 | 
			
		||||
		// Using limits.
 | 
			
		||||
		{
 | 
			
		||||
			container: api.Container{
 | 
			
		||||
				Name:  "test",
 | 
			
		||||
				Image: "image",
 | 
			
		||||
				Resources: api.ResourceRequirements{
 | 
			
		||||
					Limits: api.ResourceList{
 | 
			
		||||
						api.ResourceName(api.ResourceCPU):     resource.MustParse("1000"),
 | 
			
		||||
						api.ResourceName(api.ResourceMemory):  resource.MustParse("4G"),
 | 
			
		||||
						api.ResourceName(api.ResourceStorage): resource.MustParse("20G"),
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			status: api.ContainerStatus{
 | 
			
		||||
				Name:         "test",
 | 
			
		||||
				Ready:        true,
 | 
			
		||||
				RestartCount: 7,
 | 
			
		||||
			},
 | 
			
		||||
			expectedElements: []string{"cpu", "1k", "memory", "4G", "storage", "20G"},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for i, testCase := range testCases {
 | 
			
		||||
		out := new(bytes.Buffer)
 | 
			
		||||
		describeContainers([]api.ContainerStatus{testCase.input}, out)
 | 
			
		||||
		pod := api.Pod{
 | 
			
		||||
			Spec: api.PodSpec{
 | 
			
		||||
				Containers: []api.Container{testCase.container},
 | 
			
		||||
			},
 | 
			
		||||
			Status: api.PodStatus{
 | 
			
		||||
				ContainerStatuses: []api.ContainerStatus{testCase.status},
 | 
			
		||||
			},
 | 
			
		||||
		}
 | 
			
		||||
		describeContainers(&pod, out)
 | 
			
		||||
		output := out.String()
 | 
			
		||||
		for _, expected := range testCase.expectedElements {
 | 
			
		||||
			if !strings.Contains(output, expected) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user