From c73b535d164eba11e93b99a02a8b1a54c0746526 Mon Sep 17 00:00:00 2001 From: Deyuan Deng Date: Mon, 8 May 2017 09:42:11 +0800 Subject: [PATCH] Fix kubectl describe for controllerRef --- pkg/printers/internalversion/describe.go | 15 ++- pkg/printers/internalversion/describe_test.go | 95 +++++++++++++++++++ 2 files changed, 105 insertions(+), 5 deletions(-) diff --git a/pkg/printers/internalversion/describe.go b/pkg/printers/internalversion/describe.go index 677018dd9fc..a32413f0463 100644 --- a/pkg/printers/internalversion/describe.go +++ b/pkg/printers/internalversion/describe.go @@ -1421,7 +1421,7 @@ func (d *ReplicationControllerDescriber) Describe(namespace, name string, descri return "", err } - running, waiting, succeeded, failed, err := getPodStatusForController(pc, labels.SelectorFromSet(controller.Spec.Selector)) + running, waiting, succeeded, failed, err := getPodStatusForController(pc, labels.SelectorFromSet(controller.Spec.Selector), controller.UID) if err != nil { return "", err } @@ -1498,7 +1498,7 @@ func (d *ReplicaSetDescriber) Describe(namespace, name string, describerSettings return "", err } - running, waiting, succeeded, failed, getPodErr := getPodStatusForController(pc, selector) + running, waiting, succeeded, failed, getPodErr := getPodStatusForController(pc, selector, rs.UID) var events *api.EventList if describerSettings.ShowEvents { @@ -1698,7 +1698,7 @@ func (d *DaemonSetDescriber) Describe(namespace, name string, describerSettings if err != nil { return "", err } - running, waiting, succeeded, failed, err := getPodStatusForController(pc, selector) + running, waiting, succeeded, failed, err := getPodStatusForController(pc, selector, daemon.UID) if err != nil { return "", err } @@ -2452,7 +2452,7 @@ func (p *StatefulSetDescriber) Describe(namespace, name string, describerSetting return "", err } - running, waiting, succeeded, failed, err := getPodStatusForController(pc, selector) + running, waiting, succeeded, failed, err := getPodStatusForController(pc, selector, ps.UID) if err != nil { return "", err } @@ -2837,13 +2837,18 @@ func printReplicaSetsByLabels(matchingRSs []*versionedextension.ReplicaSet) stri return list } -func getPodStatusForController(c coreclient.PodInterface, selector labels.Selector) (running, waiting, succeeded, failed int, err error) { +func getPodStatusForController(c coreclient.PodInterface, selector labels.Selector, uid types.UID) (running, waiting, succeeded, failed int, err error) { options := metav1.ListOptions{LabelSelector: selector.String()} rcPods, err := c.List(options) if err != nil { return } for _, pod := range rcPods.Items { + controllerRef := controller.GetControllerOf(&pod) + // Skip pods that are orphans or owned by other controllers. + if controllerRef == nil || controllerRef.UID != uid { + continue + } switch pod.Status.Phase { case api.PodRunning: running++ diff --git a/pkg/printers/internalversion/describe_test.go b/pkg/printers/internalversion/describe_test.go index 7e028755813..f1c67dde9f8 100644 --- a/pkg/printers/internalversion/describe_test.go +++ b/pkg/printers/internalversion/describe_test.go @@ -1492,3 +1492,98 @@ func TestDescribeResourceQuota(t *testing.T) { } } } + +// boolPtr returns a pointer to a bool +func boolPtr(b bool) *bool { + o := b + return &o +} + +func TestControllerRef(t *testing.T) { + f := fake.NewSimpleClientset( + &api.ReplicationController{ + ObjectMeta: metav1.ObjectMeta{ + Name: "bar", + Namespace: "foo", + UID: "123456", + }, + TypeMeta: metav1.TypeMeta{ + Kind: "ReplicationController", + }, + Spec: api.ReplicationControllerSpec{ + Replicas: 1, + Selector: map[string]string{"abc": "xyz"}, + Template: &api.PodTemplateSpec{ + Spec: api.PodSpec{ + Containers: []api.Container{ + {Image: "mytest-image:latest"}, + }, + }, + }, + }, + }, + &api.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "barpod", + Namespace: "foo", + Labels: map[string]string{"abc": "xyz"}, + OwnerReferences: []metav1.OwnerReference{{Name: "bar", UID: "123456", Controller: boolPtr(true)}}, + }, + TypeMeta: metav1.TypeMeta{ + Kind: "Pod", + }, + Spec: api.PodSpec{ + Containers: []api.Container{ + {Image: "mytest-image:latest"}, + }, + }, + Status: api.PodStatus{ + Phase: api.PodRunning, + }, + }, + &api.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "orphan", + Namespace: "foo", + Labels: map[string]string{"abc": "xyz"}, + }, + TypeMeta: metav1.TypeMeta{ + Kind: "Pod", + }, + Spec: api.PodSpec{ + Containers: []api.Container{ + {Image: "mytest-image:latest"}, + }, + }, + Status: api.PodStatus{ + Phase: api.PodRunning, + }, + }, + &api.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "buzpod", + Namespace: "foo", + Labels: map[string]string{"abc": "xyz"}, + OwnerReferences: []metav1.OwnerReference{{Name: "buz", UID: "654321", Controller: boolPtr(true)}}, + }, + TypeMeta: metav1.TypeMeta{ + Kind: "Pod", + }, + Spec: api.PodSpec{ + Containers: []api.Container{ + {Image: "mytest-image:latest"}, + }, + }, + Status: api.PodStatus{ + Phase: api.PodRunning, + }, + }) + d := ReplicationControllerDescriber{f} + out, err := d.Describe("foo", "bar", printers.DescriberSettings{ShowEvents: false}) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if !strings.Contains(out, "1 Running") { + t.Errorf("unexpected out: %s", out) + } +}