github.com/NVIDIA/aistore@v1.3.23-0.20240517131212-7df6609be51d/cmn/k8s/init.go (about) 1 // Package k8s: initialization, client, and misc. helpers 2 /* 3 * Copyright (c) 2018-2024, NVIDIA CORPORATION. All rights reserved. 4 */ 5 package k8s 6 7 import ( 8 "errors" 9 "os" 10 "strings" 11 12 "github.com/NVIDIA/aistore/api/env" 13 "github.com/NVIDIA/aistore/cmn/debug" 14 "github.com/NVIDIA/aistore/cmn/nlog" 15 v1 "k8s.io/api/core/v1" 16 ) 17 18 const ( 19 defaultPodNameEnv = "HOSTNAME" 20 defaultNamespaceEnv = "POD_NAMESPACE" 21 ) 22 23 const ( 24 Default = "default" 25 Pod = "pod" 26 Svc = "svc" 27 ) 28 29 const nonK8s = "non-Kubernetes deployment" 30 31 var ( 32 NodeName string // assign upon successful initialization 33 34 ErrK8sRequired = errors.New("the operation requires Kubernetes") 35 ) 36 37 func Init() { 38 _initClient() 39 client, err := GetClient() 40 if err != nil { 41 nlog.Infoln(nonK8s, "(init k8s-client returned:", _short(err)+")") 42 return 43 } 44 45 var ( 46 pod *v1.Pod 47 nodeName = os.Getenv(env.AIS.K8sNode) 48 podName = os.Getenv(env.AIS.K8sPod) 49 ) 50 if podName != "" { 51 debug.Func(func() { 52 pn := os.Getenv(defaultPodNameEnv) 53 debug.Assertf(pn == "" || pn == podName, "%q vs %q", pn, podName) 54 }) 55 } else { 56 podName = os.Getenv(defaultPodNameEnv) 57 } 58 nlog.Infof("Checking K8s pod: %q, node: %q", podName, nodeName) 59 60 // node name specified - proceed directly to check 61 if nodeName != "" { 62 goto checkNode 63 } 64 if podName == "" { 65 nlog.Infoln("K8s environment (above) not set =>", nonK8s) 66 return 67 } 68 69 // check POD 70 pod, err = client.Pod(podName) 71 if err != nil { 72 nlog.Errorf("Failed to get K8s pod %q: %v", podName, err) 73 return 74 } 75 nodeName = pod.Spec.NodeName 76 nlog.Infoln("K8s spec: NodeName", nodeName, "Hostname", pod.Spec.Hostname, "HostNetwork", pod.Spec.HostNetwork) 77 _ppvols(pod.Spec.Volumes) 78 79 checkNode: // always check Node 80 node, err := client.Node(nodeName) 81 if err != nil { 82 nlog.Errorf("Failed to get K8s node %q: %v", nodeName, err) 83 return 84 } 85 86 NodeName = node.Name 87 nlog.Infoln("K8s node: Name", NodeName, "Namespace", node.Namespace) 88 } 89 90 func _ppvols(volumes []v1.Volume) { 91 for i := range volumes { 92 name := " " + volumes[i].Name 93 if claim := volumes[i].VolumeSource.PersistentVolumeClaim; claim != nil { 94 nlog.Infof("%s (%v)", name, claim) 95 } else { 96 nlog.Infoln(name) 97 } 98 } 99 } 100 101 func IsK8s() bool { return NodeName != "" } 102 103 func _short(err error) string { 104 const sizeLimit = 20 105 msg := err.Error() 106 idx := strings.IndexByte(msg, ',') 107 switch { 108 case len(msg) < sizeLimit: 109 return msg 110 case idx > sizeLimit: 111 return msg[:idx] 112 default: 113 return msg[:sizeLimit] 114 } 115 }