Skip to content

Commit

Permalink
Merge pull request #45467 from ddysher/kubectl-describe-controllerRef
Browse files Browse the repository at this point in the history
Automatic merge from submit-queue

Fix kubectl describe for pods with controllerRef

**What this PR does / why we need it**:

kubectl describe doesn't take controllerRef into consideration, resulting confusing result. e.g. if we have two replicaset with the same selector, one with 1 replica and the other 2 replicase, then both replicaset will show 3 running pods.

```sh
$ kubectl describe rs replicaset-2
Name:           replicaset-2      
Namespace:      default
Selector:       environment=prod
Labels:         environment=prod
Annotations:    <none>
Replicas:       2 current / 2 desired
Pods Status:    3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:       environment=prod
  Containers:
   created-from-replicaset:
    Image:              nginx
    Port:               
    Environment:        <none>
    Mounts:             <none>
  Volumes:              <none>
Events:
  FirstSeen     LastSeen        Count   From                    SubObjectPath   Type            Reason                  Message
  ---------     --------        -----   ----                    -------------   --------        ------                  -------
  5m            5m              1       replicaset-controller                   Normal          SuccessfulCreate        Created pod: replicaset-2-39szb
  5m            5m              1       replicaset-controller                   Normal          SuccessfulCreate        Created pod: replicaset-2-470jr
```


**Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes #

xref #24946

**Special notes for your reviewer**:

**Release note**:

```release-note
Fix kubectl describe for pods with controllerRef 
```
  • Loading branch information
Kubernetes Submit Queue committed Jul 5, 2017
2 parents 8244d85 + c73b535 commit e16b59a
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 5 deletions.
15 changes: 10 additions & 5 deletions pkg/printers/internalversion/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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++
Expand Down
95 changes: 95 additions & 0 deletions pkg/printers/internalversion/describe_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}

0 comments on commit e16b59a

Please sign in to comment.