package models import ( "code.gitea.io/gitea/modules/timeutil" "errors" "strconv" "strings" "xorm.io/builder" ) type ResourceQueue struct { ID int64 `xorm:"pk autoincr"` QueueCode string Cluster string `xorm:"notnull"` AiCenterCode string AiCenterName string ComputeResource string AccCardType string CardsTotalNum int IsAutomaticSync bool Remark string DeletedTime timeutil.TimeStamp `xorm:"deleted"` CreatedTime timeutil.TimeStamp `xorm:"created"` CreatedBy int64 UpdatedTime timeutil.TimeStamp `xorm:"updated"` UpdatedBy int64 } func (r ResourceQueue) ConvertToRes() *ResourceQueueRes { return &ResourceQueueRes{ ID: r.ID, QueueCode: r.QueueCode, Cluster: r.Cluster, AiCenterCode: r.AiCenterCode, AiCenterName: r.AiCenterName, ComputeResource: r.ComputeResource, AccCardType: r.AccCardType, CardsTotalNum: r.CardsTotalNum, UpdatedTime: r.UpdatedTime, Remark: r.Remark, } } type ResourceQueueReq struct { QueueCode string Cluster string `binding:"Required"` AiCenterCode string ComputeResource string `binding:"Required"` AccCardType string `binding:"Required"` CardsTotalNum int CreatorId int64 IsAutomaticSync bool Remark string } func (r ResourceQueueReq) ToDTO() ResourceQueue { q := ResourceQueue{ QueueCode: r.QueueCode, Cluster: r.Cluster, AiCenterCode: r.AiCenterCode, ComputeResource: strings.ToUpper(r.ComputeResource), AccCardType: strings.ToUpper(r.AccCardType), CardsTotalNum: r.CardsTotalNum, IsAutomaticSync: r.IsAutomaticSync, Remark: r.Remark, CreatedBy: r.CreatorId, UpdatedBy: r.CreatorId, } if r.Cluster == OpenICluster { if r.AiCenterCode == AICenterOfCloudBrainOne { q.AiCenterName = "云脑一" } else if r.AiCenterCode == AICenterOfCloudBrainTwo { q.AiCenterName = "云脑二" } else if r.AiCenterCode == AICenterOfChengdu { q.AiCenterName = "启智成都智算" } } return q } type SearchResourceQueueOptions struct { ListOptions Cluster string AiCenterCode string ComputeResource string AccCardType string } type ResourceQueueListRes struct { TotalSize int64 List []*ResourceQueueRes } type ResourceQueueCodesRes struct { ID int64 QueueCode string Cluster string AiCenterCode string AiCenterName string } func (ResourceQueueCodesRes) TableName() string { return "resource_queue" } type ResourceAiCenterRes struct { AiCenterCode string AiCenterName string } type GetQueueCodesOptions struct { Cluster string } func NewResourceQueueListRes(totalSize int64, list []ResourceQueue) *ResourceQueueListRes { resList := make([]*ResourceQueueRes, len(list)) for i, v := range list { resList[i] = v.ConvertToRes() } return &ResourceQueueListRes{ TotalSize: totalSize, List: resList, } } type ResourceQueueRes struct { ID int64 QueueCode string Cluster string AiCenterCode string AiCenterName string ComputeResource string AccCardType string CardsTotalNum int UpdatedTime timeutil.TimeStamp Remark string } func InsertResourceQueue(queue ResourceQueue) (int64, error) { return x.Insert(&queue) } func UpdateResourceQueueById(queueId int64, queue ResourceQueue) (int64, error) { return x.ID(queueId).Update(&queue) } func UpdateResourceCardsTotalNum(queueId int64, queue ResourceQueue) (int64, error) { return x.ID(queueId).Cols("cards_total_num", "remark").Update(&queue) } func SearchResourceQueue(opts SearchResourceQueueOptions) (int64, []ResourceQueue, error) { var cond = builder.NewCond() if opts.Page <= 0 { opts.Page = 1 } if opts.Cluster != "" { cond = cond.And(builder.Eq{"cluster": opts.Cluster}) } if opts.AiCenterCode != "" { cond = cond.And(builder.Eq{"ai_center_code": opts.AiCenterCode}) } if opts.ComputeResource != "" { cond = cond.And(builder.Eq{"compute_resource": opts.ComputeResource}) } if opts.AccCardType != "" { cond = cond.And(builder.Eq{"acc_card_type": opts.AccCardType}) } n, err := x.Where(cond).Unscoped().Count(&ResourceQueue{}) if err != nil { return 0, nil, err } r := make([]ResourceQueue, 0) err = x.Where(cond).Desc("id").Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).Unscoped().Find(&r) if err != nil { return 0, nil, err } return n, r, nil } func GetResourceQueueCodes(opts GetQueueCodesOptions) ([]*ResourceQueueCodesRes, error) { cond := builder.NewCond() if opts.Cluster != "" { cond = cond.And(builder.Eq{"cluster": opts.Cluster}) } cond = cond.And(builder.Or(builder.IsNull{"deleted_time"}, builder.Eq{"deleted_time": 0})) r := make([]*ResourceQueueCodesRes, 0) err := x.Where(cond).OrderBy("cluster desc,ai_center_code asc").Find(&r) if err != nil { return nil, err } return r, nil } func GetResourceQueue(r *ResourceQueue) (*ResourceQueue, error) { has, err := x.Get(r) if err != nil { return nil, err } else if !has { return nil, nil } return r, nil } func ParseComputeResourceFormGrampus(grampusDeviceKind string) string { t := strings.Split(grampusDeviceKind, "/") if len(t) < 2 { return "" } return strings.ToUpper(t[1]) } type MemSize struct { Sizes []string Hex int } var memSize = MemSize{Sizes: []string{"K", "M", "G", "T", "P", "E"}, Hex: 1000} var iMemSize = MemSize{Sizes: []string{"Ki", "Mi", "Gi", "Ti", "Pi", "Ei"}, Hex: 1024} func MatchMemSize(memSize MemSize, val string) (int, float32, error) { for i, v := range memSize.Sizes { if strings.HasSuffix(val, v) { s := strings.TrimSuffix(val, v) f, err := strconv.ParseFloat(s, 32) if err != nil { return 0, 0, err } return i, float32(f), nil } } return -1, 0, nil } //TransferMemSize transfer oldValue format from old index to new index //eg: memSize.Sizes = []string{"M", "G", "T", "P", "E"}, oldValue = 10 , oldIndex = 1 , newIndex = 0. it means transfer 10G to 10000M //so it returns 10000 func TransferMemSize(memSize MemSize, oldValue float32, oldIndex int, newIndex int) float32 { diff := oldIndex - newIndex r := oldValue if diff > 0 { r = oldValue * float32(diff) * float32(memSize.Hex) } else if diff < 0 { r = oldValue / float32(-1*diff) / float32(memSize.Hex) } return r } //ParseMemSize find the memSize which matches value's format,and parse the number from value func ParseMemSize(value string, memSize MemSize, newIndex int) (bool, float32, error) { index, r, err := MatchMemSize(memSize, value) if err != nil { return false, 0, err } if index < 0 { return false, 0, nil } return true, TransferMemSize(memSize, r, index, newIndex), nil } func ParseMemSizeFromGrampus(grampusMemSize string) (float32, error) { if grampusMemSize == "" { return 0, nil } memflag, memResult, err := ParseMemSize(grampusMemSize, memSize, 2) if err != nil { return 0, err } if memflag { return memResult, nil } iMemFlag, imemResult, err := ParseMemSize(grampusMemSize, iMemSize, 2) if err != nil { return 0, err } if iMemFlag { return imemResult, nil } return 0, errors.New("grampus memSize format error") } func SyncGrampusQueues(updateList []ResourceQueue, insertList []ResourceQueue, existIds []int64) error { sess := x.NewSession() var err error defer func() { if err != nil { sess.Rollback() } sess.Close() }() //delete queues that no longer exists deleteQueueIds := make([]int64, 0) queueCond := builder.NewCond() queueCond = queueCond.And(builder.NotIn("resource_queue.id", existIds)).And(builder.Eq{"resource_queue.cluster": C2NetCluster}) if err := sess.Cols("resource_queue.id").Table("resource_queue"). Where(queueCond).Find(&deleteQueueIds); err != nil { return err } if len(deleteQueueIds) > 0 { if _, err = sess.In("id", deleteQueueIds).Update(&ResourceQueue{Remark: "自动同步时被下架"}); err != nil { return err } if _, err = sess.In("id", deleteQueueIds).Delete(&ResourceQueue{}); err != nil { return err } //delete specs and scene that no longer exists deleteSpcIds := make([]int64, 0) if err := sess.Cols("resource_specification.id").Table("resource_specification"). In("queue_id", deleteQueueIds).Find(&deleteSpcIds); err != nil { return err } if len(deleteSpcIds) > 0 { if _, err = sess.In("id", deleteSpcIds).Update(&ResourceSpecification{Status: SpecOffShelf}); err != nil { return err } } } //update exists specs if len(updateList) > 0 { for _, v := range updateList { if _, err = sess.ID(v.ID).Update(&v); err != nil { return err } } } //insert new specs if len(insertList) > 0 { if _, err = sess.Insert(insertList); err != nil { return err } } return sess.Commit() } func GetResourceAiCenters() ([]ResourceAiCenterRes, error) { r := make([]ResourceAiCenterRes, 0) err := x.SQL("SELECT t.ai_center_code, t.ai_center_name FROM (SELECT DISTINCT ai_center_code, ai_center_name,cluster FROM resource_queue WHERE (deleted_time IS NULL OR deleted_time=0)) t ORDER BY cluster desc,ai_center_code asc").Find(&r) if err != nil { return nil, err } return r, nil }