Merge pull request #39240 from xingzhou/kube-39147

Automatic merge from submit-queue

Add three more columns to `kubectl get deploy -o wide` output.

Added CONTAINER(S), IMAGE(S) and SELECTOR fields to the output
of `kubectl get deploy -o wide`.

Fixed #39147
This commit is contained in:
Kubernetes Submit Queue 2016-12-28 06:06:19 -08:00 committed by GitHub
commit ebf679da96
2 changed files with 65 additions and 44 deletions

View File

@ -2075,13 +2075,29 @@ func printDeployment(deployment *extensions.Deployment, w io.Writer, options Pri
updatedReplicas := deployment.Status.UpdatedReplicas updatedReplicas := deployment.Status.UpdatedReplicas
availableReplicas := deployment.Status.AvailableReplicas availableReplicas := deployment.Status.AvailableReplicas
age := translateTimestamp(deployment.CreationTimestamp) age := translateTimestamp(deployment.CreationTimestamp)
containers := deployment.Spec.Template.Spec.Containers
selector, err := metav1.LabelSelectorAsSelector(deployment.Spec.Selector)
if err != nil {
// this shouldn't happen if LabelSelector passed validation
return err
}
if _, err := fmt.Fprintf(w, "%s\t%d\t%d\t%d\t%d\t%s", name, desiredReplicas, currentReplicas, updatedReplicas, availableReplicas, age); err != nil { if _, err := fmt.Fprintf(w, "%s\t%d\t%d\t%d\t%d\t%s", name, desiredReplicas, currentReplicas, updatedReplicas, availableReplicas, age); err != nil {
return err return err
} }
if options.Wide {
if err := layoutContainers(containers, w); err != nil {
return err
}
if _, err := fmt.Fprintf(w, "\t%s", selector.String()); err != nil {
return err
}
}
if _, err := fmt.Fprint(w, AppendLabels(deployment.Labels, options.ColumnLabels)); err != nil { if _, err := fmt.Fprint(w, AppendLabels(deployment.Labels, options.ColumnLabels)); err != nil {
return err return err
} }
_, err := fmt.Fprint(w, AppendAllLabels(options.ShowLabels, deployment.Labels)) _, err = fmt.Fprint(w, AppendAllLabels(options.ShowLabels, deployment.Labels))
return err return err
} }
@ -2352,6 +2368,9 @@ func formatWideHeaders(wide bool, t reflect.Type) []string {
if t.String() == "*extensions.DaemonSet" || t.String() == "*extensions.DaemonSetList" { if t.String() == "*extensions.DaemonSet" || t.String() == "*extensions.DaemonSetList" {
return []string{"CONTAINER(S)", "IMAGE(S)", "SELECTOR"} return []string{"CONTAINER(S)", "IMAGE(S)", "SELECTOR"}
} }
if t.String() == "*extensions.Deployment" || t.String() == "*extensions.DeploymentList" {
return []string{"CONTAINER(S)", "IMAGE(S)", "SELECTOR"}
}
if t.String() == "*extensions.ReplicaSet" || t.String() == "*extensions.ReplicaSetList" { if t.String() == "*extensions.ReplicaSet" || t.String() == "*extensions.ReplicaSetList" {
return []string{"CONTAINER(S)", "IMAGE(S)", "SELECTOR"} return []string{"CONTAINER(S)", "IMAGE(S)", "SELECTOR"}
} }

View File

@ -255,9 +255,7 @@ func ErrorPrintHandler(obj *TestPrintType, w io.Writer, options PrintOptions) er
func TestCustomTypePrinting(t *testing.T) { func TestCustomTypePrinting(t *testing.T) {
columns := []string{"Data"} columns := []string{"Data"}
printer := NewHumanReadablePrinter(PrintOptions{ printer := NewHumanReadablePrinter(PrintOptions{})
ColumnLabels: []string{},
})
printer.Handler(columns, PrintCustomType) printer.Handler(columns, PrintCustomType)
obj := TestPrintType{"test object"} obj := TestPrintType{"test object"}
@ -274,9 +272,7 @@ func TestCustomTypePrinting(t *testing.T) {
func TestCustomTypePrintingWithKind(t *testing.T) { func TestCustomTypePrintingWithKind(t *testing.T) {
columns := []string{"Data"} columns := []string{"Data"}
printer := NewHumanReadablePrinter(PrintOptions{ printer := NewHumanReadablePrinter(PrintOptions{})
ColumnLabels: []string{},
})
printer.Handler(columns, PrintCustomType) printer.Handler(columns, PrintCustomType)
printer.EnsurePrintWithKind("test") printer.EnsurePrintWithKind("test")
@ -294,9 +290,7 @@ func TestCustomTypePrintingWithKind(t *testing.T) {
func TestPrintHandlerError(t *testing.T) { func TestPrintHandlerError(t *testing.T) {
columns := []string{"Data"} columns := []string{"Data"}
printer := NewHumanReadablePrinter(PrintOptions{ printer := NewHumanReadablePrinter(PrintOptions{})
ColumnLabels: []string{},
})
printer.Handler(columns, ErrorPrintHandler) printer.Handler(columns, ErrorPrintHandler)
obj := TestPrintType{"test object"} obj := TestPrintType{"test object"}
buffer := &bytes.Buffer{} buffer := &bytes.Buffer{}
@ -307,9 +301,7 @@ func TestPrintHandlerError(t *testing.T) {
} }
func TestUnknownTypePrinting(t *testing.T) { func TestUnknownTypePrinting(t *testing.T) {
printer := NewHumanReadablePrinter(PrintOptions{ printer := NewHumanReadablePrinter(PrintOptions{})
ColumnLabels: []string{},
})
buffer := &bytes.Buffer{} buffer := &bytes.Buffer{}
err := printer.PrintObj(&TestUnknownType{}, buffer) err := printer.PrintObj(&TestUnknownType{}, buffer)
if err == nil { if err == nil {
@ -528,17 +520,14 @@ func TestPrinters(t *testing.T) {
printers := map[string]ResourcePrinter{ printers := map[string]ResourcePrinter{
"humanReadable": NewHumanReadablePrinter(PrintOptions{ "humanReadable": NewHumanReadablePrinter(PrintOptions{
NoHeaders: true, NoHeaders: true,
ColumnLabels: []string{},
}), }),
"humanReadableHeaders": NewHumanReadablePrinter(PrintOptions{ "humanReadableHeaders": NewHumanReadablePrinter(PrintOptions{}),
ColumnLabels: []string{}, "json": &JSONPrinter{},
}), "yaml": &YAMLPrinter{},
"json": &JSONPrinter{}, "template": templatePrinter,
"yaml": &YAMLPrinter{}, "template2": templatePrinter2,
"template": templatePrinter, "jsonpath": jsonpathPrinter,
"template2": templatePrinter2,
"jsonpath": jsonpathPrinter,
"name": &NamePrinter{ "name": &NamePrinter{
Typer: api.Scheme, Typer: api.Scheme,
Decoder: api.Codecs.UniversalDecoder(), Decoder: api.Codecs.UniversalDecoder(),
@ -576,9 +565,7 @@ func TestPrinters(t *testing.T) {
func TestPrintEventsResultSorted(t *testing.T) { func TestPrintEventsResultSorted(t *testing.T) {
// Arrange // Arrange
printer := NewHumanReadablePrinter(PrintOptions{ printer := NewHumanReadablePrinter(PrintOptions{})
ColumnLabels: []string{},
})
obj := api.EventList{ obj := api.EventList{
Items: []api.Event{ Items: []api.Event{
@ -622,9 +609,7 @@ func TestPrintEventsResultSorted(t *testing.T) {
} }
func TestPrintNodeStatus(t *testing.T) { func TestPrintNodeStatus(t *testing.T) {
printer := NewHumanReadablePrinter(PrintOptions{ printer := NewHumanReadablePrinter(PrintOptions{})
ColumnLabels: []string{},
})
table := []struct { table := []struct {
node api.Node node api.Node
status string status string
@ -744,8 +729,7 @@ func TestPrintNodeStatus(t *testing.T) {
func TestPrintNodeExternalIP(t *testing.T) { func TestPrintNodeExternalIP(t *testing.T) {
printer := NewHumanReadablePrinter(PrintOptions{ printer := NewHumanReadablePrinter(PrintOptions{
ColumnLabels: []string{}, Wide: true,
Wide: true,
}) })
table := []struct { table := []struct {
node api.Node node api.Node
@ -952,7 +936,7 @@ func TestPrintHumanReadableService(t *testing.T) {
for _, svc := range tests { for _, svc := range tests {
for _, wide := range []bool{false, true} { for _, wide := range []bool{false, true} {
buff := bytes.Buffer{} buff := bytes.Buffer{}
printService(&svc, &buff, PrintOptions{false, false, false, wide, false, false, false, "", []string{}}) printService(&svc, &buff, PrintOptions{Wide: wide})
output := string(buff.Bytes()) output := string(buff.Bytes())
ip := svc.Spec.ClusterIP ip := svc.Spec.ClusterIP
if !strings.Contains(output, ip) { if !strings.Contains(output, ip) {
@ -1138,7 +1122,6 @@ func TestPrintHumanReadableWithNamespace(t *testing.T) {
// Expect output to include namespace when requested. // Expect output to include namespace when requested.
printer := NewHumanReadablePrinter(PrintOptions{ printer := NewHumanReadablePrinter(PrintOptions{
WithNamespace: true, WithNamespace: true,
ColumnLabels: []string{},
}) })
buffer := &bytes.Buffer{} buffer := &bytes.Buffer{}
err := printer.PrintObj(test.obj, buffer) err := printer.PrintObj(test.obj, buffer)
@ -1153,7 +1136,6 @@ func TestPrintHumanReadableWithNamespace(t *testing.T) {
// Expect error when trying to get all namespaces for un-namespaced object. // Expect error when trying to get all namespaces for un-namespaced object.
printer := NewHumanReadablePrinter(PrintOptions{ printer := NewHumanReadablePrinter(PrintOptions{
WithNamespace: true, WithNamespace: true,
ColumnLabels: []string{},
}) })
buffer := &bytes.Buffer{} buffer := &bytes.Buffer{}
err := printer.PrintObj(test.obj, buffer) err := printer.PrintObj(test.obj, buffer)
@ -1250,7 +1232,7 @@ func TestPrintPod(t *testing.T) {
buf := bytes.NewBuffer([]byte{}) buf := bytes.NewBuffer([]byte{})
printer := HumanReadablePrinter{} printer := HumanReadablePrinter{}
for _, test := range tests { for _, test := range tests {
printer.printPod(&test.pod, buf, PrintOptions{false, false, false, false, true, false, false, "", []string{}}) printer.printPod(&test.pod, buf, PrintOptions{ShowAll: true})
// We ignore time // We ignore time
if !strings.HasPrefix(buf.String(), test.expect) { if !strings.HasPrefix(buf.String(), test.expect) {
t.Fatalf("Expected: %s, got: %s", test.expect, buf.String()) t.Fatalf("Expected: %s, got: %s", test.expect, buf.String())
@ -1344,7 +1326,7 @@ func TestPrintNonTerminatedPod(t *testing.T) {
buf := bytes.NewBuffer([]byte{}) buf := bytes.NewBuffer([]byte{})
printer := HumanReadablePrinter{} printer := HumanReadablePrinter{}
for _, test := range tests { for _, test := range tests {
printer.printPod(&test.pod, buf, PrintOptions{false, false, false, false, false, false, false, "", []string{}}) printer.printPod(&test.pod, buf, PrintOptions{})
// We ignore time // We ignore time
if !strings.HasPrefix(buf.String(), test.expect) { if !strings.HasPrefix(buf.String(), test.expect) {
t.Fatalf("Expected: %s, got: %s", test.expect, buf.String()) t.Fatalf("Expected: %s, got: %s", test.expect, buf.String())
@ -1405,7 +1387,7 @@ func TestPrintPodWithLabels(t *testing.T) {
buf := bytes.NewBuffer([]byte{}) buf := bytes.NewBuffer([]byte{})
printer := HumanReadablePrinter{} printer := HumanReadablePrinter{}
for _, test := range tests { for _, test := range tests {
printer.printPod(&test.pod, buf, PrintOptions{false, false, false, false, false, false, false, "", test.labelColumns}) printer.printPod(&test.pod, buf, PrintOptions{ColumnLabels: test.labelColumns})
// We ignore time // We ignore time
if !strings.HasPrefix(buf.String(), test.startsWith) || !strings.HasSuffix(buf.String(), test.endsWith) { if !strings.HasPrefix(buf.String(), test.startsWith) || !strings.HasSuffix(buf.String(), test.endsWith) {
t.Fatalf("Expected to start with: %s and end with: %s, but got: %s", test.startsWith, test.endsWith, buf.String()) t.Fatalf("Expected to start with: %s and end with: %s, but got: %s", test.startsWith, test.endsWith, buf.String())
@ -1443,6 +1425,7 @@ func TestPrintDeployment(t *testing.T) {
tests := []struct { tests := []struct {
deployment extensions.Deployment deployment extensions.Deployment
expect string expect string
wideExpect string
}{ }{
{ {
extensions.Deployment{ extensions.Deployment{
@ -1453,8 +1436,20 @@ func TestPrintDeployment(t *testing.T) {
Spec: extensions.DeploymentSpec{ Spec: extensions.DeploymentSpec{
Replicas: 5, Replicas: 5,
Template: api.PodTemplateSpec{ Template: api.PodTemplateSpec{
Spec: api.PodSpec{Containers: make([]api.Container, 2)}, Spec: api.PodSpec{
Containers: []api.Container{
{
Name: "fake-container1",
Image: "fake-image1",
},
{
Name: "fake-container2",
Image: "fake-image2",
},
},
},
}, },
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
}, },
Status: extensions.DeploymentStatus{ Status: extensions.DeploymentStatus{
Replicas: 10, Replicas: 10,
@ -1464,16 +1459,23 @@ func TestPrintDeployment(t *testing.T) {
}, },
}, },
"test1\t5\t10\t2\t1\t0s\n", "test1\t5\t10\t2\t1\t0s\n",
"test1\t5\t10\t2\t1\t0s\tfake-container1,fake-container2\tfake-image1,fake-image2\tfoo=bar\n",
}, },
} }
buf := bytes.NewBuffer([]byte{}) buf := bytes.NewBuffer([]byte{})
for _, test := range tests { for _, test := range tests {
printDeployment(&test.deployment, buf, PrintOptions{false, false, false, false, true, false, false, "", []string{}}) printDeployment(&test.deployment, buf, PrintOptions{})
if buf.String() != test.expect { if buf.String() != test.expect {
t.Fatalf("Expected: %s, got: %s", test.expect, buf.String()) t.Fatalf("Expected: %s, got: %s", test.expect, buf.String())
} }
buf.Reset() buf.Reset()
// print deployment with '-o wide' option
printDeployment(&test.deployment, buf, PrintOptions{Wide: true})
if buf.String() != test.wideExpect {
t.Fatalf("Expected: %s, got: %s", test.wideExpect, buf.String())
}
buf.Reset()
} }
} }
@ -1505,7 +1507,7 @@ func TestPrintDaemonSet(t *testing.T) {
buf := bytes.NewBuffer([]byte{}) buf := bytes.NewBuffer([]byte{})
for _, test := range tests { for _, test := range tests {
printDaemonSet(&test.ds, buf, PrintOptions{false, false, false, false, false, false, false, "", []string{}}) printDaemonSet(&test.ds, buf, PrintOptions{})
if !strings.HasPrefix(buf.String(), test.startsWith) { if !strings.HasPrefix(buf.String(), test.startsWith) {
t.Fatalf("Expected to start with %s but got %s", test.startsWith, buf.String()) t.Fatalf("Expected to start with %s but got %s", test.startsWith, buf.String())
} }
@ -1553,7 +1555,7 @@ func TestPrintJob(t *testing.T) {
buf := bytes.NewBuffer([]byte{}) buf := bytes.NewBuffer([]byte{})
for _, test := range tests { for _, test := range tests {
printJob(&test.job, buf, PrintOptions{false, false, false, false, true, false, false, "", []string{}}) printJob(&test.job, buf, PrintOptions{})
if buf.String() != test.expect { if buf.String() != test.expect {
t.Fatalf("Expected: %s, got: %s", test.expect, buf.String()) t.Fatalf("Expected: %s, got: %s", test.expect, buf.String())
} }
@ -1614,7 +1616,7 @@ func TestPrintPodShowLabels(t *testing.T) {
printer := HumanReadablePrinter{} printer := HumanReadablePrinter{}
for _, test := range tests { for _, test := range tests {
printer.printPod(&test.pod, buf, PrintOptions{false, false, false, false, false, test.showLabels, false, "", []string{}}) printer.printPod(&test.pod, buf, PrintOptions{ShowLabels: test.showLabels})
// We ignore time // We ignore time
if !strings.HasPrefix(buf.String(), test.startsWith) || !strings.HasSuffix(buf.String(), test.endsWith) { if !strings.HasPrefix(buf.String(), test.startsWith) || !strings.HasSuffix(buf.String(), test.endsWith) {
t.Fatalf("Expected to start with: %s and end with: %s, but got: %s", test.startsWith, test.endsWith, buf.String()) t.Fatalf("Expected to start with: %s and end with: %s, but got: %s", test.startsWith, test.endsWith, buf.String())
@ -1664,7 +1666,7 @@ func TestPrintService(t *testing.T) {
buf := bytes.NewBuffer([]byte{}) buf := bytes.NewBuffer([]byte{})
for _, test := range tests { for _, test := range tests {
printService(&test.service, buf, PrintOptions{false, false, false, false, true, false, false, "", []string{}}) printService(&test.service, buf, PrintOptions{})
// We ignore time // We ignore time
if buf.String() != test.expect { if buf.String() != test.expect {
t.Fatalf("Expected: %s, got: %s %d", test.expect, buf.String(), strings.Compare(test.expect, buf.String())) t.Fatalf("Expected: %s, got: %s %d", test.expect, buf.String(), strings.Compare(test.expect, buf.String()))
@ -1697,7 +1699,7 @@ func TestPrintPodDisruptionBudget(t *testing.T) {
buf := bytes.NewBuffer([]byte{}) buf := bytes.NewBuffer([]byte{})
for _, test := range tests { for _, test := range tests {
printPodDisruptionBudget(&test.pdb, buf, PrintOptions{false, false, false, false, true, false, false, "", []string{}}) printPodDisruptionBudget(&test.pdb, buf, PrintOptions{})
if buf.String() != test.expect { if buf.String() != test.expect {
t.Fatalf("Expected: %s, got: %s", test.expect, buf.String()) t.Fatalf("Expected: %s, got: %s", test.expect, buf.String())
} }