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 }