|
- package cloud
-
- import (
- "context"
- "fmt"
- "github.com/aliyun/alibaba-cloud-sdk-go/services/eci"
- "github.com/go-resty/resty/v2"
- "gitlink.org.cn/JointCloud/pcm-coordinator/internal/participant/cloud"
- "gitlink.org.cn/JointCloud/pcm-coordinator/internal/scheduler/service/collector"
- "gitlink.org.cn/JointCloud/pcm-coordinator/pkg/constants"
- "gitlink.org.cn/JointCloud/pcm-coordinator/pkg/repository/result"
- "gitlink.org.cn/JointCloud/pcm-coordinator/pkg/utils/restyclient"
- v1 "k8s.io/api/core/v1"
- v2 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/util/json"
- )
-
- // 定义枚举类型
-
- type ParticipantCloud struct {
- participantId int64
- platform string
- host string
- userName string
- accessToken string
- *restyclient.RestyClient
- }
-
- func NewCloud(host string, id int64, platform string) *ParticipantCloud {
- return &ParticipantCloud{
- host: host,
- participantId: id,
- platform: platform,
- RestyClient: restyclient.InitClient(host, ""),
- }
- }
-
- func (c *ParticipantCloud) GetContainer(ctx context.Context, name string, queryParam string, clusterId string) (collector.Task, error) {
- resp := collector.Task{}
- reqUrl := c.host + cloud.GetContainer
- containerResp := &collector.ContainerDetailResp{}
- httpClient := resty.New().R()
- _, err := httpClient.SetHeaders(
- map[string]string{
- "Content-Type": "application/json",
- "traceId": result.TraceIDFromContext(ctx),
- }).
- SetQueryParams(map[string]string{
- "pfId": clusterId,
- }).SetBody(cloud.GetParam{Name: name}).
- SetResult(&containerResp).
- Post(reqUrl)
- if err != nil {
- return resp, err
- }
- fmt.Println("containerResp:", containerResp.Data)
-
- if queryParam != "" && queryParam != "null" {
- resp = getEciStatusEnum(containerResp)
- } else {
- resp = getK8sStatusEnum(containerResp)
- }
-
- return resp, nil
- }
- func getK8sStatusEnum(containerDetail *collector.ContainerDetailResp) collector.Task {
- var resp collector.Task
- var pod v1.Pod
- bytes, err := json.Marshal(containerDetail.Data)
- if err != nil {
- return resp
- }
- json.Unmarshal(bytes, &pod)
- // 优先判断Pod的删除状态(是否正在删除)
- if !pod.DeletionTimestamp.IsZero() {
- // 已标记删除但未完全删除 → WaitDelete;已删除(若能查询到则表示未完全删除)
- resp.Status = constants.WaitDelete
- }
-
- // 根据Pod的Phase(宏观状态)判断
- switch pod.Status.Phase {
- case v1.PodRunning:
- // 运行中:检查是否有容器在重启(可能处于WaitRestart)
- for _, cs := range pod.Status.ContainerStatuses {
- if cs.RestartCount > 0 && cs.State.Running == nil {
- // 有重启记录且当前运行中 → 刚重启完,对应WaitRestart
- resp.Status = constants.WaitRestart
- }
- }
- resp.Status = constants.Running
-
- case v1.PodPending:
- // Pending状态:检查容器是否在等待启动
- for _, cs := range pod.Status.ContainerStatuses {
- if cs.State.Waiting != nil {
- switch cs.State.Waiting.Reason {
- case "ContainerCreating", "PodInitializing":
- resp.Status = constants.WaitStart // 等待启动
- case "Paused":
- resp.Status = constants.WaitPause // 等待暂停(罕见,通常对应Pause状态)
- default:
- resp.Status = constants.Waiting // 其他等待状态
- }
- }
- }
- resp.Status = constants.Pending
-
- case v1.PodSucceeded:
- // 所有容器成功终止
- resp.Status = constants.Succeeded
-
- case v1.PodFailed:
- // 至少一个容器失败终止
- resp.Status = constants.Failed
-
- case v1.PodUnknown:
- // 未知状态 → 暂归为Waiting
- resp.Status = constants.Waiting
- }
-
- // 检查容器状态(补充Phase未覆盖的情况)
- for _, cs := range pod.Status.ContainerStatuses {
- switch {
- case cs.State.Terminated != nil:
- if cs.State.Terminated.Reason == "Completed" {
- resp.Status = constants.Completed // 容器正常完成
- }
- if cs.State.Terminated.Reason == "Error" {
- resp.Status = constants.Failed // 错误终止
- }
- if cs.State.Terminated.Reason == "Cancelled" {
- resp.Status = constants.Cancelled // 被取消
- }
- case cs.State.Waiting != nil && cs.State.Waiting.Reason == "Paused":
- resp.Status = constants.WaitPause // 容器被暂停
- }
- }
-
- // 提取 StartTime(Pod 启动时间)
- startTime := pod.Status.StartTime
- if startTime == nil {
- fmt.Println("Pod 尚未启动,无 startTime")
- } else {
- resp.Start = startTime.Time.Format("2006-01-02 15:04:05")
- }
-
- // 提取 EndTime(容器终止时间,仅当 Pod 已结束时存在)
- // 遍历所有容器状态,查找已终止的容器
- var endTime *v2.Time
- for _, containerStatus := range pod.Status.ContainerStatuses {
- if containerStatus.State.Terminated != nil {
- endTime = &containerStatus.State.Terminated.FinishedAt
- break // 取第一个终止的容器时间(若有多个容器,可根据需求调整)
- }
- }
-
- if endTime == nil {
- fmt.Println("Pod 尚未终止,无 endTime(可能仍在运行中)")
- } else {
- resp.End = endTime.Time.Format("2006-01-02 15:04:05")
- }
- return resp
- }
- func getEciStatusEnum(containerDetail *collector.ContainerDetailResp) collector.Task {
- var resp collector.Task
- var eciResp eci.DescribeContainerGroupsResponse
- bytes, err := json.Marshal(containerDetail.Data)
- if err != nil {
- return resp
- }
- json.Unmarshal(bytes, &eciResp)
- if len(eciResp.ContainerGroups) == 0 {
- return resp
- }
- switch eciResp.ContainerGroups[0].Status {
- case "Pending":
- resp.Status = constants.Pending
- case "Creating":
- resp.Status = constants.WaitStart
- case "Running":
- resp.Status = constants.Running
- case "Stopping":
- resp.Status = constants.Stopped
- case "Stopped":
- resp.Status = constants.Stopped
- case "Failed":
- resp.Status = constants.Failed
- case "Deleting":
- resp.Status = constants.Deleted
- case "Succeeded":
- resp.Status = constants.Succeeded
- case "Unknown":
- resp.Status = constants.Failed
- }
- resp.Start = eciResp.ContainerGroups[0].CreationTime
- resp.End = eciResp.ContainerGroups[0].SucceededTime
- return resp
- }
|