You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

common.go 4.1 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. Copyright 2021 The KubeEdge Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package runtime
  14. import (
  15. "context"
  16. "encoding/json"
  17. "fmt"
  18. "math"
  19. "strings"
  20. "time"
  21. v1 "k8s.io/api/core/v1"
  22. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  23. "k8s.io/client-go/kubernetes"
  24. "k8s.io/client-go/util/workqueue"
  25. "k8s.io/klog/v2"
  26. sednav1 "github.com/kubeedge/sedna/pkg/apis/sedna/v1alpha1"
  27. )
  28. const (
  29. // resourceUpdateTries defines times of trying to update resource
  30. resourceUpdateTries = 3
  31. )
  32. // GetNodeIPByName get node ip by node name
  33. func GetNodeIPByName(kubeClient kubernetes.Interface, name string) (string, error) {
  34. n, err := kubeClient.CoreV1().Nodes().Get(context.Background(), name, metav1.GetOptions{})
  35. if err != nil {
  36. return "", err
  37. }
  38. typeToAddress := make(map[v1.NodeAddressType]string)
  39. for _, addr := range n.Status.Addresses {
  40. typeToAddress[addr.Type] = addr.Address
  41. }
  42. address, found := typeToAddress[v1.NodeExternalIP]
  43. if found {
  44. return address, nil
  45. }
  46. address, found = typeToAddress[v1.NodeInternalIP]
  47. if found {
  48. return address, nil
  49. }
  50. return "", fmt.Errorf("can't found node ip for node %s", name)
  51. }
  52. // GetBackoff calc the next wait time for the key
  53. func GetBackoff(queue workqueue.RateLimitingInterface, key interface{}) time.Duration {
  54. exp := queue.NumRequeues(key)
  55. if exp <= 0 {
  56. return time.Duration(0)
  57. }
  58. // The backoff is capped such that 'calculated' value never overflows.
  59. backoff := float64(DefaultBackOff.Nanoseconds()) * math.Pow(2, float64(exp-1))
  60. if backoff > math.MaxInt64 {
  61. return MaxBackOff
  62. }
  63. calculated := time.Duration(backoff)
  64. if calculated > MaxBackOff {
  65. return MaxBackOff
  66. }
  67. return calculated
  68. }
  69. func CalcActivePodCount(pods []*v1.Pod) int32 {
  70. var result int32 = 0
  71. for _, p := range pods {
  72. if v1.PodSucceeded != p.Status.Phase &&
  73. v1.PodFailed != p.Status.Phase &&
  74. p.DeletionTimestamp == nil {
  75. result++
  76. }
  77. }
  78. return result
  79. }
  80. // ConvertK8SValidName converts to the k8s valid name
  81. func ConvertK8SValidName(name string) string {
  82. // the name(e.g. pod/volume name) should be a lowercase RFC 1123 label:
  83. // [a-z0-9]([-a-z0-9]*[a-z0-9])?
  84. // and no more than 63 characters
  85. limitCount := 63
  86. var fixName []byte
  87. for _, c := range []byte(strings.ToLower(name)) {
  88. if ('a' <= c && c <= 'z') ||
  89. ('0' <= c && c <= '9') ||
  90. c == '-' {
  91. fixName = append(fixName, c)
  92. continue
  93. }
  94. // the first char not '-'
  95. // and no two consecutive '-'
  96. if len(fixName) > 0 && fixName[len(fixName)-1] != '-' {
  97. fixName = append(fixName, '-')
  98. }
  99. }
  100. // fix limitCount
  101. if len(fixName) > limitCount {
  102. fixName = fixName[:limitCount]
  103. }
  104. // fix the end character
  105. if len(fixName) > 0 && fixName[len(fixName)-1] == '-' {
  106. fixName[len(fixName)-1] = 'z'
  107. }
  108. return string(fixName)
  109. }
  110. // ConvertMapToMetrics converts the metric map to list of resource Metric
  111. func ConvertMapToMetrics(metric map[string]interface{}) []sednav1.Metric {
  112. var l []sednav1.Metric
  113. for k, v := range metric {
  114. var displayValue string
  115. switch t := v.(type) {
  116. case string:
  117. displayValue = t
  118. default:
  119. // ignore the json marshal error
  120. b, _ := json.Marshal(v)
  121. displayValue = string(b)
  122. }
  123. l = append(l, sednav1.Metric{Key: k, Value: displayValue})
  124. }
  125. return l
  126. }
  127. // RetryUpdateStatus simply retries to call the status update func
  128. func RetryUpdateStatus(name, namespace string, updateStatusFunc func() error) error {
  129. var err error
  130. for try := 1; try <= resourceUpdateTries; try++ {
  131. err = updateStatusFunc()
  132. if err == nil {
  133. return nil
  134. }
  135. klog.Warningf("Error to update %s/%s status, tried %d times: %+v", namespace, name, try, err)
  136. }
  137. return err
  138. }