mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-28 14:07:14 +00:00
Merge pull request #9304 from jsdir/master
Show resource limits with describe
This commit is contained in:
commit
e44f61993b
@ -409,7 +409,7 @@ func describePod(pod *api.Pod, rcs []api.ReplicationController, events *api.Even
|
||||
fmt.Fprintf(out, "IP:\t%s\n", pod.Status.PodIP)
|
||||
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 {
|
||||
@ -473,39 +473,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) {
|
||||
|
Loading…
Reference in New Issue
Block a user