mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-05 18:24:07 +00:00
Merge pull request #83899 from wojtek-t/describe_lease_in_node
Add information from Lease to kubectl describe node
This commit is contained in:
commit
4fa7d42301
@ -13,6 +13,7 @@ go_library(
|
|||||||
"//staging/src/k8s.io/api/batch/v1:go_default_library",
|
"//staging/src/k8s.io/api/batch/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/batch/v1beta1:go_default_library",
|
"//staging/src/k8s.io/api/batch/v1beta1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/certificates/v1beta1:go_default_library",
|
"//staging/src/k8s.io/api/certificates/v1beta1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/api/coordination/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/discovery/v1alpha1:go_default_library",
|
"//staging/src/k8s.io/api/discovery/v1alpha1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/extensions/v1beta1:go_default_library",
|
"//staging/src/k8s.io/api/extensions/v1beta1:go_default_library",
|
||||||
@ -63,6 +64,7 @@ go_test(
|
|||||||
"//staging/src/k8s.io/api/apps/v1:go_default_library",
|
"//staging/src/k8s.io/api/apps/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/autoscaling/v1:go_default_library",
|
"//staging/src/k8s.io/api/autoscaling/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/autoscaling/v2beta2:go_default_library",
|
"//staging/src/k8s.io/api/autoscaling/v2beta2:go_default_library",
|
||||||
|
"//staging/src/k8s.io/api/coordination/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/discovery/v1alpha1:go_default_library",
|
"//staging/src/k8s.io/api/discovery/v1alpha1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/networking/v1:go_default_library",
|
"//staging/src/k8s.io/api/networking/v1:go_default_library",
|
||||||
|
@ -39,6 +39,7 @@ import (
|
|||||||
batchv1 "k8s.io/api/batch/v1"
|
batchv1 "k8s.io/api/batch/v1"
|
||||||
batchv1beta1 "k8s.io/api/batch/v1beta1"
|
batchv1beta1 "k8s.io/api/batch/v1beta1"
|
||||||
certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
|
certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
|
||||||
|
coordinationv1 "k8s.io/api/coordination/v1"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
discoveryv1alpha1 "k8s.io/api/discovery/v1alpha1"
|
discoveryv1alpha1 "k8s.io/api/discovery/v1alpha1"
|
||||||
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||||
@ -3000,6 +3001,15 @@ func (d *NodeDescriber) Describe(namespace, name string, describerSettings descr
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lease, err := d.CoordinationV1().Leases(corev1.NamespaceNodeLease).Get(name, metav1.GetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
if !errors.IsNotFound(err) {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
// Corresponding Lease object doesn't exist - print it accordingly.
|
||||||
|
lease = nil
|
||||||
|
}
|
||||||
|
|
||||||
fieldSelector, err := fields.ParseSelector("spec.nodeName=" + name + ",status.phase!=" + string(corev1.PodSucceeded) + ",status.phase!=" + string(corev1.PodFailed))
|
fieldSelector, err := fields.ParseSelector("spec.nodeName=" + name + ",status.phase!=" + string(corev1.PodSucceeded) + ",status.phase!=" + string(corev1.PodFailed))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@ -3026,10 +3036,10 @@ func (d *NodeDescriber) Describe(namespace, name string, describerSettings descr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return describeNode(node, nodeNonTerminatedPodsList, events, canViewPods)
|
return describeNode(node, lease, nodeNonTerminatedPodsList, events, canViewPods)
|
||||||
}
|
}
|
||||||
|
|
||||||
func describeNode(node *corev1.Node, nodeNonTerminatedPodsList *corev1.PodList, events *corev1.EventList, canViewPods bool) (string, error) {
|
func describeNode(node *corev1.Node, lease *coordinationv1.Lease, nodeNonTerminatedPodsList *corev1.PodList, events *corev1.EventList, canViewPods bool) (string, error) {
|
||||||
return tabbedString(func(out io.Writer) error {
|
return tabbedString(func(out io.Writer) error {
|
||||||
w := NewPrefixWriter(out)
|
w := NewPrefixWriter(out)
|
||||||
w.Write(LEVEL_0, "Name:\t%s\n", node.Name)
|
w.Write(LEVEL_0, "Name:\t%s\n", node.Name)
|
||||||
@ -3043,6 +3053,24 @@ func describeNode(node *corev1.Node, nodeNonTerminatedPodsList *corev1.PodList,
|
|||||||
w.Write(LEVEL_0, "CreationTimestamp:\t%s\n", node.CreationTimestamp.Time.Format(time.RFC1123Z))
|
w.Write(LEVEL_0, "CreationTimestamp:\t%s\n", node.CreationTimestamp.Time.Format(time.RFC1123Z))
|
||||||
printNodeTaintsMultiline(w, "Taints", node.Spec.Taints)
|
printNodeTaintsMultiline(w, "Taints", node.Spec.Taints)
|
||||||
w.Write(LEVEL_0, "Unschedulable:\t%v\n", node.Spec.Unschedulable)
|
w.Write(LEVEL_0, "Unschedulable:\t%v\n", node.Spec.Unschedulable)
|
||||||
|
|
||||||
|
w.Write(LEVEL_0, "Lease:\n")
|
||||||
|
holderIdentity := "<unset>"
|
||||||
|
if lease != nil && lease.Spec.HolderIdentity != nil {
|
||||||
|
holderIdentity = *lease.Spec.HolderIdentity
|
||||||
|
}
|
||||||
|
w.Write(LEVEL_1, "HolderIdentity:\t%s\n", holderIdentity)
|
||||||
|
acquireTime := "<unset>"
|
||||||
|
if lease != nil && lease.Spec.AcquireTime != nil {
|
||||||
|
acquireTime = lease.Spec.AcquireTime.Time.Format(time.RFC1123Z)
|
||||||
|
}
|
||||||
|
w.Write(LEVEL_1, "AcquireTime:\t%s\n", acquireTime)
|
||||||
|
renewTime := "<unset>"
|
||||||
|
if lease != nil && lease.Spec.RenewTime != nil {
|
||||||
|
renewTime = lease.Spec.RenewTime.Time.Format(time.RFC1123Z)
|
||||||
|
}
|
||||||
|
w.Write(LEVEL_1, "RenewTime:\t%s\n", renewTime)
|
||||||
|
|
||||||
if len(node.Status.Conditions) > 0 {
|
if len(node.Status.Conditions) > 0 {
|
||||||
w.Write(LEVEL_0, "Conditions:\n Type\tStatus\tLastHeartbeatTime\tLastTransitionTime\tReason\tMessage\n")
|
w.Write(LEVEL_0, "Conditions:\n Type\tStatus\tLastHeartbeatTime\tLastTransitionTime\tReason\tMessage\n")
|
||||||
w.Write(LEVEL_1, "----\t------\t-----------------\t------------------\t------\t-------\n")
|
w.Write(LEVEL_1, "----\t------\t-----------------\t------------------\t------\t-------\n")
|
||||||
|
@ -28,6 +28,7 @@ import (
|
|||||||
appsv1 "k8s.io/api/apps/v1"
|
appsv1 "k8s.io/api/apps/v1"
|
||||||
autoscalingv1 "k8s.io/api/autoscaling/v1"
|
autoscalingv1 "k8s.io/api/autoscaling/v1"
|
||||||
autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2"
|
autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2"
|
||||||
|
coordinationv1 "k8s.io/api/coordination/v1"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
discoveryv1alpha1 "k8s.io/api/discovery/v1alpha1"
|
discoveryv1alpha1 "k8s.io/api/discovery/v1alpha1"
|
||||||
networkingv1 "k8s.io/api/networking/v1"
|
networkingv1 "k8s.io/api/networking/v1"
|
||||||
@ -3179,15 +3180,29 @@ Events: <none>` + "\n"
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDescribeNode(t *testing.T) {
|
func TestDescribeNode(t *testing.T) {
|
||||||
fake := fake.NewSimpleClientset(&corev1.Node{
|
holderIdentity := "holder"
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "bar",
|
fake := fake.NewSimpleClientset(
|
||||||
Namespace: "foo",
|
&corev1.Node{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "bar",
|
||||||
|
},
|
||||||
|
Spec: corev1.NodeSpec{
|
||||||
|
Unschedulable: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Spec: corev1.NodeSpec{
|
&coordinationv1.Lease{
|
||||||
Unschedulable: true,
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "bar",
|
||||||
|
Namespace: corev1.NamespaceNodeLease,
|
||||||
|
},
|
||||||
|
Spec: coordinationv1.LeaseSpec{
|
||||||
|
HolderIdentity: &holderIdentity,
|
||||||
|
AcquireTime: &metav1.MicroTime{Time: time.Now().Add(-time.Hour)},
|
||||||
|
RenewTime: &metav1.MicroTime{Time: time.Now()},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
)
|
||||||
c := &describeClient{T: t, Namespace: "foo", Interface: fake}
|
c := &describeClient{T: t, Namespace: "foo", Interface: fake}
|
||||||
d := NodeDescriber{c}
|
d := NodeDescriber{c}
|
||||||
out, err := d.Describe("foo", "bar", describe.DescriberSettings{ShowEvents: true})
|
out, err := d.Describe("foo", "bar", describe.DescriberSettings{ShowEvents: true})
|
||||||
@ -3195,13 +3210,12 @@ func TestDescribeNode(t *testing.T) {
|
|||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
expectedOut := []string{"Unschedulable", "true"}
|
expectedOut := []string{"Unschedulable", "true", "holder"}
|
||||||
for _, expected := range expectedOut {
|
for _, expected := range expectedOut {
|
||||||
if !strings.Contains(out, expected) {
|
if !strings.Contains(out, expected) {
|
||||||
t.Errorf("expected to find %q in output: %q", expected, out)
|
t.Errorf("expected to find %q in output: %q", expected, out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDescribeStatefulSet(t *testing.T) {
|
func TestDescribeStatefulSet(t *testing.T) {
|
||||||
|
Loading…
Reference in New Issue
Block a user