github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/k8s/runtime.go (about)

     1  package k8s
     2  
     3  import (
     4  	"context"
     5  	"net/http"
     6  	"sync"
     7  
     8  	apiErrors "k8s.io/apimachinery/pkg/api/errors"
     9  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    10  	apiv1 "k8s.io/client-go/kubernetes/typed/core/v1"
    11  
    12  	"github.com/tilt-dev/tilt/internal/container"
    13  	"github.com/tilt-dev/tilt/pkg/logger"
    14  )
    15  
    16  type runtimeAsync struct {
    17  	core    apiv1.CoreV1Interface
    18  	runtime container.Runtime
    19  	once    sync.Once
    20  }
    21  
    22  func newRuntimeAsync(core apiv1.CoreV1Interface) *runtimeAsync {
    23  	return &runtimeAsync{
    24  		core:    core,
    25  		runtime: container.RuntimeUnknown,
    26  	}
    27  }
    28  
    29  func (r *runtimeAsync) Runtime(ctx context.Context) container.Runtime {
    30  	r.once.Do(func() {
    31  		nodeList, err := r.core.Nodes().List(ctx, metav1.ListOptions{
    32  			Limit: 1,
    33  		})
    34  		if err != nil {
    35  			logger.Get(ctx).Debugf("Error fetching nodes: %v", err)
    36  
    37  			statusErr, isStatusErr := err.(*apiErrors.StatusError)
    38  			if isStatusErr {
    39  				status := statusErr.ErrStatus
    40  				if status.Code == http.StatusForbidden {
    41  					logger.Get(ctx).Debugf(
    42  						"Tilt could not read your node configuration\n"+
    43  							"  Ask your Kubernetes admin for access to run `kubectl get nodes`.\n"+
    44  							"  Detail: %v", err)
    45  				}
    46  			}
    47  		}
    48  		if nodeList == nil || len(nodeList.Items) == 0 {
    49  			r.runtime = container.RuntimeReadFailure
    50  			return
    51  		}
    52  
    53  		node := nodeList.Items[0]
    54  		info := node.Status.NodeInfo
    55  		r.runtime = container.RuntimeFromVersionString(info.ContainerRuntimeVersion)
    56  	})
    57  	return r.runtime
    58  }
    59  
    60  func (c K8sClient) ContainerRuntime(ctx context.Context) container.Runtime {
    61  	return c.runtimeAsync.Runtime(ctx)
    62  }