/
util.go
151 lines (124 loc) · 4.18 KB
/
util.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package utils
import (
"fmt"
"math"
"strconv"
"strings"
"unicode"
rayiov1alpha1 "github.com/ray-project/kuberay/ray-operator/api/v1alpha1"
"github.com/sirupsen/logrus"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// IsCreated returns true if pod has been created and is maintained by the API server
func IsCreated(pod *corev1.Pod) bool {
return pod.Status.Phase != ""
}
// CheckName makes sure the name does not start with a numeric value and the total length is < 63 char
func CheckName(s string) string {
maxLenght := 50 // 63 - (max(8,6) + 5 ) // 6 to 8 char are consumed at the end with "-head-" or -worker- + 5 generated.
if len(s) > maxLenght {
//shorten the name
offset := int(math.Abs(float64(maxLenght) - float64(len(s))))
fmt.Printf("pod name is too long: len = %v, we will shorten it by offset = %v\n", len(s), offset)
s = s[offset:]
}
// cannot start with a numeric value
if unicode.IsDigit(rune(s[0])) {
s = "r" + s[1:]
}
// cannot start with a punctuation
if unicode.IsPunct(rune(s[0])) {
fmt.Println(s)
s = "r" + s[1:]
}
return s
}
// CheckLabel makes sure the label value does not start with a punctuation and the total length is < 63 char
func CheckLabel(s string) string {
maxLenght := 63
if len(s) > maxLenght {
//shorten the name
offset := int(math.Abs(float64(maxLenght) - float64(len(s))))
fmt.Printf("label value is too long: len = %v, we will shorten it by offset = %v\n", len(s), offset)
s = s[offset:]
}
// cannot start with a punctuation
if unicode.IsPunct(rune(s[0])) {
fmt.Println(s)
s = "r" + s[1:]
}
return s
}
// Before Get substring before a string.
func Before(value string, a string) string {
pos := strings.Index(value, a)
if pos == -1 {
return ""
}
return value[0:pos]
}
// FormatInt returns the string representation of i in the given base,
// for 2 <= base <= 36. The result uses the lower-case letters 'a' to 'z'
// for digit values >= 10.
func FormatInt32(n int32) string {
return strconv.FormatInt(int64(n), 10)
}
// GetNamespace return namespace
func GetNamespace(metaData metav1.ObjectMeta) string {
if metaData.Namespace == "" {
return "default"
}
return metaData.Namespace
}
// GenerateServiceName generates a ray head service name from cluster name
func GenerateServiceName(clusterName string) string {
return fmt.Sprintf("%s-%s-%s", clusterName, rayiov1alpha1.HeadNode, "svc")
}
// GenerateIdentifier generates identifier of same group pods
func GenerateIdentifier(clusterName string, nodeType rayiov1alpha1.RayNodeType) string {
return fmt.Sprintf("%s-%s", clusterName, nodeType)
}
// TODO: find target container through name instead of using index 0.
// FindRayContainerIndex finds the ray head/worker container's index in the pod
func FindRayContainerIndex(spec corev1.PodSpec) (index int) {
// We only support one container at this moment. We definitely need a better way to filter out sidecar containers.
if len(spec.Containers) > 1 {
logrus.Warnf("Pod has multiple containers, we choose index=0 as Ray container")
}
return 0
}
// CalculateDesiredReplicas calculate desired worker replicas at the cluster level
func CalculateDesiredReplicas(cluster *rayiov1alpha1.RayCluster) int32 {
count := int32(0)
for _, nodeGroup := range cluster.Spec.WorkerGroupSpecs {
count += *nodeGroup.Replicas
}
return count
}
// CalculateDesiredReplicas calculate desired worker replicas at the cluster level
func CalculateMinReplicas(cluster *rayiov1alpha1.RayCluster) int32 {
count := int32(0)
for _, nodeGroup := range cluster.Spec.WorkerGroupSpecs {
count += *nodeGroup.MinReplicas
}
return count
}
// CalculateDesiredReplicas calculate desired worker replicas at the cluster level
func CalculateMaxReplicas(cluster *rayiov1alpha1.RayCluster) int32 {
count := int32(0)
for _, nodeGroup := range cluster.Spec.WorkerGroupSpecs {
count += *nodeGroup.MaxReplicas
}
return count
}
// CalculateDesiredReplicas calculate desired worker replicas at the cluster level
func CalculateAvailableReplicas(pods corev1.PodList) int32 {
count := int32(0)
for _, pod := range pods.Items {
if pod.Status.Phase == corev1.PodPending || pod.Status.Phase == corev1.PodRunning {
count++
}
}
return count
}