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.

k8s.go 4.6 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. package cloud
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/go-resty/resty/v2"
  6. "gitlink.org.cn/JointCloud/pcm-coordinator/internal/participant/cloud"
  7. "gitlink.org.cn/JointCloud/pcm-coordinator/internal/scheduler/service/collector"
  8. "gitlink.org.cn/JointCloud/pcm-coordinator/pkg/constants"
  9. "gitlink.org.cn/JointCloud/pcm-coordinator/pkg/repository/result"
  10. "gitlink.org.cn/JointCloud/pcm-coordinator/pkg/utils/restyclient"
  11. v1 "k8s.io/api/core/v1"
  12. v2 "k8s.io/apimachinery/pkg/apis/meta/v1"
  13. )
  14. // 定义枚举类型
  15. type ParticipantCloud struct {
  16. participantId int64
  17. platform string
  18. host string
  19. userName string
  20. accessToken string
  21. *restyclient.RestyClient
  22. }
  23. func NewCloud(host string, id int64, platform string) *ParticipantCloud {
  24. return &ParticipantCloud{
  25. host: host,
  26. participantId: id,
  27. platform: platform,
  28. RestyClient: restyclient.InitClient(host, ""),
  29. }
  30. }
  31. func (c *ParticipantCloud) GetContainer(ctx context.Context, taskId string, clusterId string) (*collector.Task, error) {
  32. reqUrl := c.host + cloud.GetContainer
  33. containerResp := &collector.ContainerDetailResp{}
  34. httpClient := resty.New().R()
  35. _, err := httpClient.SetHeaders(
  36. map[string]string{
  37. "Content-Type": "application/json",
  38. "traceId": result.TraceIDFromContext(ctx),
  39. }).
  40. SetQueryParams(map[string]string{
  41. "pfId": clusterId,
  42. "name": taskId,
  43. }).
  44. SetResult(&containerResp).
  45. Get(reqUrl)
  46. if err != nil {
  47. return nil, err
  48. }
  49. fmt.Println("containerResp:", containerResp.Data)
  50. var resp collector.Task
  51. status := getStatusEnum(containerResp.Data)
  52. resp.Status = status
  53. // 提取 StartTime(Pod 启动时间)
  54. startTime := containerResp.Data.Status.StartTime
  55. if startTime == nil {
  56. fmt.Println("Pod 尚未启动,无 startTime")
  57. } else {
  58. resp.Start = startTime.Time.Format("2006-01-02 15:04:05")
  59. }
  60. // 提取 EndTime(容器终止时间,仅当 Pod 已结束时存在)
  61. // 遍历所有容器状态,查找已终止的容器
  62. var endTime *v2.Time
  63. for _, containerStatus := range containerResp.Data.Status.ContainerStatuses {
  64. if containerStatus.State.Terminated != nil {
  65. endTime = &containerStatus.State.Terminated.FinishedAt
  66. break // 取第一个终止的容器时间(若有多个容器,可根据需求调整)
  67. }
  68. }
  69. if endTime == nil {
  70. fmt.Println("Pod 尚未终止,无 endTime(可能仍在运行中)")
  71. } else {
  72. resp.End = endTime.Time.Format("2006-01-02 15:04:05")
  73. }
  74. return &resp, nil
  75. }
  76. func getStatusEnum(pod *v1.Pod) string {
  77. // 优先判断Pod的删除状态(是否正在删除)
  78. if !pod.DeletionTimestamp.IsZero() {
  79. // 已标记删除但未完全删除 → WaitDelete;已删除(若能查询到则表示未完全删除)
  80. return constants.WaitDelete
  81. }
  82. // 根据Pod的Phase(宏观状态)判断
  83. switch pod.Status.Phase {
  84. case v1.PodRunning:
  85. // 运行中:检查是否有容器在重启(可能处于WaitRestart)
  86. for _, cs := range pod.Status.ContainerStatuses {
  87. if cs.RestartCount > 0 && cs.State.Running == nil {
  88. // 有重启记录且当前运行中 → 刚重启完,对应WaitRestart
  89. return constants.WaitRestart
  90. }
  91. }
  92. return constants.Running
  93. case v1.PodPending:
  94. // Pending状态:检查容器是否在等待启动
  95. for _, cs := range pod.Status.ContainerStatuses {
  96. if cs.State.Waiting != nil {
  97. switch cs.State.Waiting.Reason {
  98. case "ContainerCreating", "PodInitializing":
  99. return constants.WaitStart // 等待启动
  100. case "Paused":
  101. return constants.WaitPause // 等待暂停(罕见,通常对应Pause状态)
  102. default:
  103. return constants.Waiting // 其他等待状态
  104. }
  105. }
  106. }
  107. return constants.Pending
  108. case v1.PodSucceeded:
  109. // 所有容器成功终止
  110. return constants.Succeeded
  111. case v1.PodFailed:
  112. // 至少一个容器失败终止
  113. return constants.Failed
  114. case v1.PodUnknown:
  115. // 未知状态 → 暂归为Waiting
  116. return constants.Waiting
  117. }
  118. // 检查容器状态(补充Phase未覆盖的情况)
  119. for _, cs := range pod.Status.ContainerStatuses {
  120. switch {
  121. case cs.State.Terminated != nil:
  122. if cs.State.Terminated.Reason == "Completed" {
  123. return constants.Completed // 容器正常完成
  124. }
  125. if cs.State.Terminated.Reason == "Error" {
  126. return constants.Failed // 错误终止
  127. }
  128. if cs.State.Terminated.Reason == "Cancelled" {
  129. return constants.Cancelled // 被取消
  130. }
  131. case cs.State.Waiting != nil && cs.State.Waiting.Reason == "Paused":
  132. return constants.WaitPause // 容器被暂停
  133. }
  134. }
  135. // 其他未覆盖状态(如部署中、已保存等)
  136. return constants.Deploying
  137. }

PCM is positioned as Software stack over Cloud, aiming to build the standards and ecology of heterogeneous cloud collaboration for JCC in a non intrusive and autonomous peer-to-peer manner.