@@ -143,6 +143,9 @@ func InsertResourceQueue(queue ResourceQueue) (int64, error) { | |||
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() | |||
@@ -313,9 +316,6 @@ func SyncGrampusQueues(updateList []ResourceQueue, insertList []ResourceQueue, e | |||
if _, err = sess.In("id", deleteSpcIds).Update(&ResourceSpecification{Status: SpecOffShelf}); err != nil { | |||
return err | |||
} | |||
if _, err = sess.In("spec_id", deleteSpcIds).Delete(&ResourceSceneSpec{}); err != nil { | |||
return err | |||
} | |||
} | |||
} | |||
@@ -116,7 +116,7 @@ func InsertResourceScene(r ResourceSceneReq) error { | |||
//check | |||
specs := make([]ResourceSpecification, 0) | |||
cond := builder.In("id", r.SpecIds).And(builder.Eq{"status": SpecOnShelf}) | |||
cond := builder.In("id", r.SpecIds) | |||
if err := sess.Where(cond).Find(&specs); err != nil { | |||
return err | |||
} | |||
@@ -175,7 +175,7 @@ func UpdateResourceScene(r ResourceSceneReq) error { | |||
} | |||
//check specification | |||
specs := make([]ResourceSpecification, 0) | |||
cond := builder.In("id", r.SpecIds).And(builder.Eq{"status": SpecOnShelf}) | |||
cond := builder.In("id", r.SpecIds) | |||
if err := sess.Where(cond).Find(&specs); err != nil { | |||
return err | |||
} | |||
@@ -168,6 +168,7 @@ type FindSpecsOptions struct { | |||
UseShareMemGiB bool | |||
//if true,find specs no matter used or not used in scene. if false,only find specs used in scene | |||
RequestAll bool | |||
SpecStatus int | |||
} | |||
type Specification struct { | |||
@@ -269,10 +270,6 @@ func ResourceSpecOffShelf(id int64) (int64, error) { | |||
} | |||
sess.Close() | |||
}() | |||
//delete scene spec relation | |||
if _, err = sess.Where("spec_id = ?", id).Delete(&ResourceSceneSpec{}); err != nil { | |||
return 0, err | |||
} | |||
param := ResourceSpecification{ | |||
Status: SpecOffShelf, | |||
@@ -317,9 +314,6 @@ func SyncGrampusSpecs(updateList []ResourceSpecification, insertList []ResourceS | |||
if _, err = sess.Cols("status", "is_available").In("id", deleteIds).Update(&ResourceSpecification{Status: SpecOffShelf, IsAvailable: false}); err != nil { | |||
return err | |||
} | |||
if _, err = sess.In("spec_id", deleteIds).Delete(&ResourceSceneSpec{}); err != nil { | |||
return err | |||
} | |||
} | |||
//update exists specs | |||
@@ -384,6 +378,9 @@ func FindSpecs(opts FindSpecsOptions) ([]*Specification, error) { | |||
if opts.UseShareMemGiB { | |||
cond = cond.And(builder.Eq{"resource_specification.share_mem_gi_b": opts.ShareMemGiB}) | |||
} | |||
if opts.SpecStatus > 0 { | |||
cond = cond.And(builder.Eq{"resource_specification.status": opts.SpecStatus}) | |||
} | |||
r := make([]*Specification, 0) | |||
s := x.Where(cond). | |||
Join("INNER", "resource_queue", "resource_queue.id = resource_specification.queue_id") | |||
@@ -136,6 +136,26 @@ func GetResourceSpecificationList(ctx *context.Context) { | |||
ctx.JSON(http.StatusOK, response.SuccessWithData(list)) | |||
} | |||
func GetAllResourceSpecificationList(ctx *context.Context) { | |||
queue := ctx.QueryInt64("queue") | |||
status := ctx.QueryInt("status") | |||
cluster := ctx.Query("cluster") | |||
available := ctx.QueryInt("available") | |||
list, err := resource.GetAllDistinctResourceSpecification(models.SearchResourceSpecificationOptions{ | |||
QueueId: queue, | |||
Status: status, | |||
Cluster: cluster, | |||
AvailableCode: available, | |||
}) | |||
if err != nil { | |||
log.Error("GetResourceSpecificationList error.%v", err) | |||
ctx.JSON(http.StatusOK, response.ServerError(err.Error())) | |||
return | |||
} | |||
ctx.JSON(http.StatusOK, response.SuccessWithData(list)) | |||
} | |||
func GetResourceSpecificationScenes(ctx *context.Context) { | |||
specId := ctx.ParamsInt64(":id") | |||
list, err := resource.GetResourceSpecificationScenes(specId) | |||
@@ -645,6 +645,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
m.Group("/specification", func() { | |||
m.Get("", admin.GetSpecificationPage) | |||
m.Get("/list", admin.GetResourceSpecificationList) | |||
m.Get("/list/all", admin.GetAllResourceSpecificationList) | |||
m.Get("/scenes/:id", admin.GetResourceSpecificationScenes) | |||
m.Post("/grampus/sync", admin.SyncGrampusSpecs) | |||
m.Post("/add", binding.Bind(models.ResourceSpecificationReq{}), admin.AddResourceSpecification) | |||
@@ -1487,6 +1488,12 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
m.Get("/record/list", point.GetPointRecordList) | |||
}, reqSignIn) | |||
m.Group("/resources", func() { | |||
m.Group("/queue", func() { | |||
m.Get("/centers", admin.GetResourceAiCenters) | |||
}) | |||
}) | |||
if setting.API.EnableSwagger { | |||
m.Get("/swagger.v1.json", templates.JSONRenderer(), routers.SwaggerV1Json) | |||
} | |||
@@ -16,7 +16,7 @@ func AddResourceQueue(req models.ResourceQueueReq) error { | |||
} | |||
func UpdateResourceQueue(queueId int64, req models.ResourceQueueReq) error { | |||
if _, err := models.UpdateResourceQueueById(queueId, models.ResourceQueue{ | |||
if _, err := models.UpdateResourceCardsTotalNum(queueId, models.ResourceQueue{ | |||
CardsTotalNum: req.CardsTotalNum, | |||
Remark: req.Remark, | |||
}); err != nil { | |||
@@ -130,10 +130,48 @@ func GetResourceSpecificationList(opts models.SearchResourceSpecificationOptions | |||
if err != nil { | |||
return nil, err | |||
} | |||
return models.NewResourceSpecAndQueueListRes(n, r), nil | |||
} | |||
//GetAllDistinctResourceSpecification returns specification and queue after distinct | |||
//totalSize is always 0 here | |||
func GetAllDistinctResourceSpecification(opts models.SearchResourceSpecificationOptions) (*models.ResourceSpecAndQueueListRes, error) { | |||
opts.Page = 0 | |||
opts.PageSize = 1000 | |||
_, r, err := models.SearchResourceSpecification(opts) | |||
if err != nil { | |||
return nil, err | |||
} | |||
nr := distinctResourceSpecAndQueue(r) | |||
return models.NewResourceSpecAndQueueListRes(0, nr), nil | |||
} | |||
func distinctResourceSpecAndQueue(r []models.ResourceSpecAndQueue) []models.ResourceSpecAndQueue { | |||
specs := make([]models.ResourceSpecAndQueue, 0, len(r)) | |||
sourceSpecIdMap := make(map[string]models.ResourceSpecAndQueue, 0) | |||
for i := 0; i < len(r); i++ { | |||
spec := r[i] | |||
if spec.SourceSpecId == "" { | |||
specs = append(specs, spec) | |||
continue | |||
} | |||
if _, has := sourceSpecIdMap[spec.SourceSpecId]; has { | |||
//prefer to use on-shelf spec | |||
if sourceSpecIdMap[spec.SourceSpecId].Status != spec.Status && spec.Status == models.SpecOnShelf { | |||
for k, v := range specs { | |||
if v.ResourceSpecification.ID == sourceSpecIdMap[spec.SourceSpecId].ResourceSpecification.ID { | |||
specs[k] = spec | |||
} | |||
} | |||
} | |||
continue | |||
} | |||
specs = append(specs, spec) | |||
sourceSpecIdMap[spec.SourceSpecId] = spec | |||
} | |||
return specs | |||
} | |||
func GetResourceSpecificationScenes(specId int64) ([]models.ResourceSceneBriefRes, error) { | |||
r, err := models.GetSpecScenes(specId) | |||
if err != nil { | |||
@@ -200,6 +238,7 @@ func AddSpecOperateLog(doerId int64, operateType string, newValue, oldValue *mod | |||
} | |||
func FindAvailableSpecs(userId int64, opts models.FindSpecsOptions) ([]*models.Specification, error) { | |||
opts.SpecStatus = models.SpecOnShelf | |||
r, err := models.FindSpecs(opts) | |||
if err != nil { | |||
log.Error("FindAvailableSpecs error.%v", err) | |||
@@ -110,6 +110,19 @@ export const getResSpecificationList = (params) => { | |||
}); | |||
} | |||
// 查询资源规格列表(所有) | |||
// cluster 所属集群 :OpenI 启智集群,C2Net 智算集群 | |||
// queue 所属队列id | |||
// status 状态 : 1 待审核 2已上架 3已下架 | |||
export const getResSpecificationListAll = (params) => { | |||
return service({ | |||
url: '/admin/resources/specification/list/all', | |||
method: 'get', | |||
params, | |||
data: {}, | |||
}); | |||
} | |||
// 同步智算网络资源池(队列) | |||
export const syncResSpecification = () => { | |||
return service({ | |||
@@ -69,7 +69,9 @@ | |||
</div> | |||
<div class="content"> | |||
<el-select v-model="dataInfo.SpecIds" multiple collapse-tags class="specSel"> | |||
<el-option v-for="item in specsList" :key="item.k" :label="item.v" :value="item.k" /> | |||
<el-option v-for="item in specsList" :label="item.v" :key="item.k" :value="item.k"> | |||
<span v-html="item.v"></span> | |||
</el-option> | |||
</el-select> | |||
</div> | |||
</div> | |||
@@ -87,7 +89,7 @@ | |||
</template> | |||
<script> | |||
import BaseDialog from '~/components/BaseDialog.vue'; | |||
import { getResQueueCode, getResSpecificationList, addResScene, updateResScene } from '~/apis/modules/resources'; | |||
import { getResQueueCode, getResSpecificationListAll, addResScene, updateResScene } from '~/apis/modules/resources'; | |||
import { JOB_TYPE, CLUSTERS, ACC_CARD_TYPE, SPECIFICATION_STATUS } from '~/const'; | |||
import { getListValueWithKey } from '~/utils'; | |||
@@ -167,21 +169,21 @@ export default { | |||
const params = { | |||
cluster: this.dataInfo.Cluster, | |||
queue: this.dataInfo.QueueId === '-1' ? '' : this.dataInfo.QueueId, | |||
status: 2, | |||
page: 1, | |||
// status: 2, | |||
// page: 1, | |||
}; | |||
return getResSpecificationList(params).then(res => { | |||
return getResSpecificationListAll(params).then(res => { | |||
res = res.data; | |||
if (res.Code === 0) { | |||
const list = res.Data.List; | |||
const data = list.map((item) => { | |||
const Queue = item.Queue; | |||
const Spec = item.Spec; | |||
// const NGPU = `${Queue.ComputeResource}:${Spec.AccCardsNum === 0 ? '0' : Spec.AccCardsNum + '*' + getListValueWithKey(this.accCardTypeList, Queue.AccCardType)}`; | |||
const NGPU = `${Queue.ComputeResource}:${Spec.AccCardsNum + '*' + getListValueWithKey(this.accCardTypeList, Queue.AccCardType)}`; | |||
const statusStr = Spec.Status != '2' ? `<span style="color:rgb(245, 34, 45)">(${getListValueWithKey(this.statusList, Spec.Status.toString())})</span>` : ''; | |||
return { | |||
k: Spec.ID, | |||
v: `${NGPU}, CPU:${Spec.CpuCores}, ${this.$t('resourcesManagement.gpuMem')}:${Spec.GPUMemGiB}GB, ${this.$t('resourcesManagement.mem')}:${Spec.MemGiB}GB, ${this.$t('resourcesManagement.shareMem')}:${Spec.ShareMemGiB}GB, ${this.$t('resourcesManagement.unitPrice')}:${Spec.UnitPrice}${this.$t('resourcesManagement.point_hr')}`, | |||
v: `${NGPU}, CPU:${Spec.CpuCores}, ${this.$t('resourcesManagement.gpuMem')}:${Spec.GPUMemGiB}GB, ${this.$t('resourcesManagement.mem')}:${Spec.MemGiB}GB, ${this.$t('resourcesManagement.shareMem')}:${Spec.ShareMemGiB}GB, ${this.$t('resourcesManagement.unitPrice')}:${Spec.UnitPrice}${this.$t('resourcesManagement.point_hr')}${statusStr}`, | |||
} | |||
}); | |||
this.specsList.splice(0, Infinity, ...data); | |||
@@ -64,7 +64,7 @@ | |||
header-align="center" min-width="180"> | |||
<template slot-scope="scope"> | |||
<div v-for="item in scope.row.SpecsList" :key="item.k"> | |||
<span>{{ item.v }}</span> | |||
<span v-html="item.v"></span> | |||
</div> | |||
</template> | |||
</el-table-column> | |||
@@ -100,7 +100,7 @@ | |||
<script> | |||
import SceneDialog from '../components/SceneDialog.vue'; | |||
import { getQueueList, getResQueueCode, getResSceneList, updateResScene, getAiCenterList } from '~/apis/modules/resources'; | |||
import { JOB_TYPE, CLUSTERS, ACC_CARD_TYPE } from '~/const'; | |||
import { JOB_TYPE, CLUSTERS, ACC_CARD_TYPE, SPECIFICATION_STATUS } from '~/const'; | |||
import { getListValueWithKey } from '~/utils'; | |||
import { formatDate } from 'element-ui/lib/utils/date-util'; | |||
@@ -117,6 +117,7 @@ export default { | |||
selAiCenter: '', | |||
aiCenterList: [{ k: '', v: this.$t('resourcesManagement.allAiCenter') }], | |||
accCardTypeList: [...ACC_CARD_TYPE], | |||
statusList: [{ k: '', v: this.$t('resourcesManagement.allStatus') }, ...SPECIFICATION_STATUS], | |||
loading: false, | |||
tableData: [], | |||
pageInfo: { | |||
@@ -191,11 +192,11 @@ export default { | |||
let cluster = ''; | |||
for (let i = 0, iLen = Specs.length; i < iLen; i++) { | |||
const Spec = Specs[i]; | |||
// const NGPU = `${Spec.ComputeResource}:${Spec.AccCardsNum === 0 ? '0' : Spec.AccCardsNum + '*' + getListValueWithKey(this.accCardTypeList, Spec.AccCardType)}`; | |||
const NGPU = `${Spec.ComputeResource}:${Spec.AccCardsNum + '*' + getListValueWithKey(this.accCardTypeList, Spec.AccCardType)}`; | |||
const statusStr = Spec.Status != '2' ? `<span style="color:rgb(245, 34, 45)">(${getListValueWithKey(this.statusList, Spec.Status.toString())})</span>` : ''; | |||
specsList.push({ | |||
k: Spec.ID, | |||
v: `${NGPU}, CPU:${Spec.CpuCores}, ${this.$t('resourcesManagement.gpuMem')}:${Spec.GPUMemGiB}GB, ${this.$t('resourcesManagement.mem')}:${Spec.MemGiB}GB, ${this.$t('resourcesManagement.shareMem')}:${Spec.ShareMemGiB}GB, ${this.$t('resourcesManagement.unitPrice')}:${Spec.UnitPrice}${this.$t('resourcesManagement.point_hr')}`, | |||
v: `${NGPU}, CPU:${Spec.CpuCores}, ${this.$t('resourcesManagement.gpuMem')}:${Spec.GPUMemGiB}GB, ${this.$t('resourcesManagement.mem')}:${Spec.MemGiB}GB, ${this.$t('resourcesManagement.shareMem')}:${Spec.ShareMemGiB}GB, ${this.$t('resourcesManagement.unitPrice')}:${Spec.UnitPrice}${this.$t('resourcesManagement.point_hr')}${statusStr}`, | |||
}); | |||
cluster = Spec.Cluster; | |||
if (queueIds.indexOf(Spec.QueueId) < 0) { | |||