mirror of https://github.com/k3s-io/k3s
Merge pull request #45467 from ddysher/kubectl-describe-controllerRef
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 ```pull/6/head
commit
e16b59aa0a
|
@ -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++
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue