...

Source file src/sigs.k8s.io/cli-utils/pkg/kstatus/watcher/unschedulable.go

Documentation: sigs.k8s.io/cli-utils/pkg/kstatus/watcher

     1  // Copyright 2022 The Kubernetes Authors.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package watcher
     5  
     6  import (
     7  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
     8  	"k8s.io/apimachinery/pkg/runtime/schema"
     9  	"sigs.k8s.io/cli-utils/pkg/kstatus/polling/event"
    10  	"sigs.k8s.io/cli-utils/pkg/kstatus/status"
    11  	"sigs.k8s.io/cli-utils/pkg/object"
    12  )
    13  
    14  // isObjectUnschedulable returns true if the object or any of its generated resources
    15  // is an unschedulable pod.
    16  //
    17  // This status is computed recursively, so it can handle objects that generate
    18  // objects that generate pods, as long as the input ResourceStatus has those
    19  // GeneratedResources computed.
    20  func isObjectUnschedulable(rs *event.ResourceStatus) bool {
    21  	if rs.Error != nil {
    22  		return false
    23  	}
    24  	if rs.Status != status.InProgressStatus {
    25  		return false
    26  	}
    27  	if isPodUnschedulable(rs.Resource) {
    28  		return true
    29  	}
    30  	// recurse through generated resources
    31  	for _, subRS := range rs.GeneratedResources {
    32  		if isObjectUnschedulable(subRS) {
    33  			return true
    34  		}
    35  	}
    36  	return false
    37  }
    38  
    39  // isPodUnschedulable returns true if the object is a pod and is unschedulable
    40  // according to a False PodScheduled condition.
    41  func isPodUnschedulable(obj *unstructured.Unstructured) bool {
    42  	if obj == nil {
    43  		return false
    44  	}
    45  	gk := obj.GroupVersionKind().GroupKind()
    46  	if gk != (schema.GroupKind{Kind: "Pod"}) {
    47  		return false
    48  	}
    49  	icnds, found, err := object.NestedField(obj.Object, "status", "conditions")
    50  	if err != nil || !found {
    51  		return false
    52  	}
    53  	cnds, ok := icnds.([]interface{})
    54  	if !ok {
    55  		return false
    56  	}
    57  	for _, icnd := range cnds {
    58  		cnd, ok := icnd.(map[string]interface{})
    59  		if !ok {
    60  			return false
    61  		}
    62  		if cnd["type"] == "PodScheduled" &&
    63  			cnd["status"] == "False" &&
    64  			cnd["reason"] == "Unschedulable" {
    65  			return true
    66  		}
    67  	}
    68  	return false
    69  }
    70  

View as plain text