fix(region): batch get isolated device spec (#21475)

This commit is contained in:
wanyaoqi
2024-10-28 16:16:02 +08:00
committed by GitHub
parent 34bd50ed9d
commit 6b03f5d648
3 changed files with 95 additions and 23 deletions
+1 -1
View File
@@ -855,7 +855,7 @@ func getIsolatedDeviceInfo(ctx context.Context, userCred mcclient.TokenCredentia
hosts := hostQuery.SubQuery()
q := devices.Query(devices.Field("model"), devices.Field("dev_type"), devices.Field("nvme_size_mb"))
q = q.Filter(sqlchemy.NotIn(devices.Field("dev_type"), []string{api.USB_TYPE, api.NIC_TYPE, api.NVME_PT_TYPE}))
q = q.Filter(sqlchemy.NotIn(devices.Field("dev_type"), []string{api.USB_TYPE, api.NIC_TYPE}))
if zone != nil {
q = q.Join(hosts, sqlchemy.Equals(devices.Field("host_id"), hosts.Field("id")))
q = q.Filter(sqlchemy.Equals(hosts.Field("zone_id"), zone.Id))
+81 -18
View File
@@ -469,6 +469,17 @@ func (self *SIsolatedDevice) getVendor() string {
}
}
func GetVendorByVendorDeviceId(vendorDeviceId string) string {
parts := strings.Split(vendorDeviceId, ":")
vendorId := parts[0]
vendor, ok := ID_VENDOR_MAP[vendorId]
if ok {
return vendor
} else {
return vendorId
}
}
func (self *SIsolatedDevice) IsGPU() bool {
return strings.HasPrefix(self.DevType, "GPU") || sets.NewString(api.CONTAINER_GPU_TYPES...).Has(self.DevType)
}
@@ -933,6 +944,71 @@ func (man *SIsolatedDeviceManager) GetSpecShouldCheckStatus(query *jsonutils.JSO
return true, nil
}
func (man *SIsolatedDeviceManager) BatchGetModelSpecs(statusCheck bool) (jsonutils.JSONObject, error) {
q := man.Query("vendor_device_id", "model", "dev_type")
if statusCheck {
q = q.IsNullOrEmpty("guest_id")
}
q.GroupBy(q.Field("vendor_device_id"), q.Field("model"), q.Field("dev_type"))
q.AppendField(sqlchemy.COUNT("*"))
if statusCheck {
hostQ := HostManager.Query().Equals("status", api.BAREMETAL_RUNNING).IsTrue("enabled").
In("host_type", []string{api.HOST_TYPE_HYPERVISOR, api.HOST_TYPE_CONTAINER})
hostSQ := hostQ.SubQuery()
q.Join(hostSQ, sqlchemy.Equals(q.Field("host_id"), hostSQ.Field("id")))
}
rows, err := q.Rows()
if err != nil {
return nil, errors.Wrap(err, "failed get specs")
}
defer rows.Close()
res := jsonutils.NewDict()
for rows.Next() {
var vendorDeviceId, m, t string
var count int
if err := rows.Scan(&vendorDeviceId, &m, &t, &count); err != nil {
return nil, errors.Wrap(err, "get model spec scan rows")
}
vendor := GetVendorByVendorDeviceId(vendorDeviceId)
specKeys := man.getSpecKeys(vendor, m, t)
specKey := GetSpecIdentKey(specKeys)
spec := man.getSpecByRows(vendorDeviceId, m, t, &count)
res.Set(specKey, spec)
}
return res, nil
}
func (man *SIsolatedDeviceManager) getSpecByRows(vendorDeviceId, model, devType string, count *int) *jsonutils.JSONDict {
var vdev bool
var hypervisor string
if utils.IsInStringArray(devType, api.VITRUAL_DEVICE_TYPES) {
vdev = true
}
if utils.IsInStringArray(devType, api.VALID_CONTAINER_DEVICE_TYPES) {
hypervisor = api.HYPERVISOR_POD
} else {
hypervisor = api.HYPERVISOR_KVM
}
ret := jsonutils.NewDict()
ret.Set("virtual_dev", jsonutils.NewBool(vdev))
ret.Set("hypervisor", jsonutils.NewString(hypervisor))
ret.Set("dev_type", jsonutils.NewString(devType))
ret.Set("model", jsonutils.NewString(model))
ret.Set("pci_id", jsonutils.NewString(vendorDeviceId))
ret.Set("vendor", jsonutils.NewString(GetVendorByVendorDeviceId(vendorDeviceId)))
if count != nil {
ret.Set("count", jsonutils.NewInt(int64(*count)))
}
return ret
}
type GpuSpec struct {
DevType string `json:"dev_type,allowempty"`
Model string `json:"model,allowempty"`
@@ -952,24 +1028,7 @@ func (self *SIsolatedDevice) GetSpec(statusCheck bool) *jsonutils.JSONDict {
return nil
}
}
var vdev bool
var hypervisor string
if utils.IsInStringArray(self.DevType, api.VITRUAL_DEVICE_TYPES) {
vdev = true
}
if utils.IsInStringArray(self.DevType, api.VALID_CONTAINER_DEVICE_TYPES) {
hypervisor = api.HYPERVISOR_POD
} else {
hypervisor = api.HYPERVISOR_KVM
}
ret := jsonutils.NewDict()
ret.Set("virtual_dev", jsonutils.NewBool(vdev))
ret.Set("hypervisor", jsonutils.NewString(hypervisor))
ret.Set("dev_type", jsonutils.NewString(self.DevType))
ret.Set("model", jsonutils.NewString(self.Model))
ret.Set("pci_id", jsonutils.NewString(self.VendorDeviceId))
ret.Set("vendor", jsonutils.NewString(self.getVendor()))
return ret
return IsolatedDeviceManager.getSpecByRows(self.VendorDeviceId, self.Model, self.DevType, nil)
}
func (self *SIsolatedDevice) GetGpuSpec() *GpuSpec {
@@ -986,6 +1045,10 @@ func (man *SIsolatedDeviceManager) GetSpecIdent(spec *jsonutils.JSONDict) []stri
devType, _ := spec.GetString("dev_type")
vendor, _ := spec.GetString("vendor")
model, _ := spec.GetString("model")
return man.getSpecKeys(vendor, model, devType)
}
func (man *SIsolatedDeviceManager) getSpecKeys(vendor, model, devType string) []string {
keys := []string{
fmt.Sprintf("type:%s", devType),
fmt.Sprintf("vendor:%s", vendor),
+13 -4
View File
@@ -38,6 +38,10 @@ type ISpecModel interface {
GetSpec(statusCheck bool) *jsonutils.JSONDict
}
type IBatchSpecModel interface {
BatchGetModelSpecs(statusCheck bool) (jsonutils.JSONObject, error)
}
func GetAllModelSpecs(ctx context.Context, userCred mcclient.TokenCredential, query *jsonutils.JSONDict) (jsonutils.JSONObject, error) {
mans := []ISpecModelManager{HostManager, IsolatedDeviceManager, GuestManager}
return GetModelsSpecs(ctx, userCred, query, mans...)
@@ -80,15 +84,20 @@ func GetModelSpec(manager ISpecModelManager, model ISpecModel) (jsonutils.JSONOb
}
func getModelSpecs(manager ISpecModelManager, ctx context.Context, userCred mcclient.TokenCredential, query *jsonutils.JSONDict) (jsonutils.JSONObject, error) {
statusCheck, err := manager.GetSpecShouldCheckStatus(query)
if err != nil {
return nil, err
}
if bm, ok := manager.(IBatchSpecModel); ok {
return bm.BatchGetModelSpecs(statusCheck)
}
items, err := ListItems(manager, ctx, userCred, query)
if err != nil {
return nil, err
}
retDict := jsonutils.NewDict()
statusCheck, err := manager.GetSpecShouldCheckStatus(query)
if err != nil {
return nil, err
}
for _, obj := range items {
specObj := obj.(ISpecModel)
spec := specObj.GetSpec(statusCheck)