mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-01 15:07:17 +08:00
fix(region,host): custom device model add auto detect option
Signed-off-by: wanyaoqi <d3lx.yq@gmail.com>
This commit is contained in:
@@ -15,8 +15,13 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/util/printutils"
|
||||
|
||||
"yunion.io/x/onecloud/cmd/climc/shell"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
|
||||
baseoptions "yunion.io/x/onecloud/pkg/mcclient/options"
|
||||
options "yunion.io/x/onecloud/pkg/mcclient/options/compute"
|
||||
)
|
||||
|
||||
@@ -28,4 +33,69 @@ func init() {
|
||||
cmd.Delete(new(options.IsolatedDeviceIdsOptions))
|
||||
cmd.Perform("set-hardware-info", new(options.IsolatedDeviceModelSetHardwareInfoOptions))
|
||||
cmd.Get("hardware-info", new(options.IsolatedDeviceIdsOptions))
|
||||
|
||||
type HostIsolatedDeviceModelListOptions struct {
|
||||
baseoptions.BaseListOptions
|
||||
Host string `help:"ID or Name of Host"`
|
||||
IsolatedDeviceModel string `help:"ID or Name of Isolated device model"`
|
||||
}
|
||||
R(&HostIsolatedDeviceModelListOptions{}, "host-isolated-device-model-list",
|
||||
"List host Isolated device model pairs", func(s *mcclient.ClientSession, args *HostIsolatedDeviceModelListOptions) error {
|
||||
var params *jsonutils.JSONDict
|
||||
{
|
||||
var err error
|
||||
params, err = args.BaseListOptions.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
}
|
||||
}
|
||||
var result *printutils.ListResult
|
||||
var err error
|
||||
if len(args.Host) > 0 {
|
||||
result, err = modules.HostIsolatedDeviceModels.ListDescendent(s, args.Host, params)
|
||||
} else if len(args.IsolatedDeviceModel) > 0 {
|
||||
result, err = modules.HostIsolatedDeviceModels.ListDescendent2(s, args.IsolatedDeviceModel, params)
|
||||
} else {
|
||||
result, err = modules.HostIsolatedDeviceModels.List(s, params)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(result, modules.HostIsolatedDeviceModels.GetColumns(s))
|
||||
return nil
|
||||
})
|
||||
|
||||
type HostIsolatedDeviceModelDetailOptions struct {
|
||||
HOST string `help:"ID or Name of Host"`
|
||||
IsolatedDeviceModel string `help:"ID or Name of Isolated device model"`
|
||||
}
|
||||
R(&HostIsolatedDeviceModelDetailOptions{}, "host-isolated-device-model-show", "Show host isolated-device-model details", func(s *mcclient.ClientSession, args *HostIsolatedDeviceModelDetailOptions) error {
|
||||
result, err := modules.HostIsolatedDeviceModels.Get(s, args.HOST, args.IsolatedDeviceModel, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&HostIsolatedDeviceModelDetailOptions{}, "host-isolated-device-model-detach", "Detach a isolated-device-model from a host", func(s *mcclient.ClientSession, args *HostIsolatedDeviceModelDetailOptions) error {
|
||||
result, err := modules.HostIsolatedDeviceModels.Detach(s, args.HOST, args.IsolatedDeviceModel, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&HostIsolatedDeviceModelDetailOptions{}, "host-isolated-device-model-attach", "Attach a isolated-device-model to a host", func(s *mcclient.ClientSession, args *HostIsolatedDeviceModelDetailOptions) error {
|
||||
params := jsonutils.NewDict()
|
||||
result, err := modules.HostIsolatedDeviceModels.Attach(s, args.HOST, args.IsolatedDeviceModel, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
@@ -194,6 +194,9 @@ type IsolatedDeviceModelListInput struct {
|
||||
|
||||
// 支持热插拔 HotPluggable
|
||||
HotPluggable bool `json:"hot_pluggable"`
|
||||
|
||||
// 宿主机 Id
|
||||
HostId string `json:"host_id"`
|
||||
}
|
||||
|
||||
type IsolatedDeviceModelHardwareInfo struct {
|
||||
@@ -329,3 +332,19 @@ func (info IsolatedDevicePCIEInfo) GetThroughputPerLane() PCIEVersionThroughput
|
||||
}
|
||||
return NewPCIEVersionThroughput(PCIEVersionUnknown)
|
||||
}
|
||||
|
||||
type HostIsolatedDeviceModelDetails struct {
|
||||
SHostJointsBase
|
||||
HostJointResourceDetails
|
||||
// 宿主机Id
|
||||
HostId string `json:"host_id"`
|
||||
// 存储Id
|
||||
IsolatedDeviceModelId string `json:"isolated_device_model_id"`
|
||||
|
||||
Model string
|
||||
VendorId string
|
||||
DeviceId string
|
||||
DevType string
|
||||
HotPluggable bool
|
||||
DisableAutoDetect bool
|
||||
}
|
||||
|
||||
@@ -28,8 +28,6 @@ const (
|
||||
AMD_VENDOR_ID = "1002"
|
||||
)
|
||||
|
||||
const MEAT_PROBED_HOST_COUNT = "probed_host_count"
|
||||
|
||||
var VALID_GPU_TYPES = []string{GPU_HPC_TYPE, GPU_VGA_TYPE}
|
||||
var VALID_ATTACH_TYPES = []string{GPU_HPC_TYPE, GPU_VGA_TYPE, USB_TYPE, SRIOV_VGPU_TYPE, LEGACY_VGPU_TYPE}
|
||||
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/util/stringutils2"
|
||||
)
|
||||
|
||||
type SHostIsolatedDeviceModelManager struct {
|
||||
SHostJointsManager
|
||||
}
|
||||
|
||||
var HostIsolatedDeviceModelManager *SHostIsolatedDeviceModelManager
|
||||
|
||||
func init() {
|
||||
db.InitManager(func() {
|
||||
HostIsolatedDeviceModelManager = &SHostIsolatedDeviceModelManager{
|
||||
SHostJointsManager: NewHostJointsManager(
|
||||
"host_id",
|
||||
SHostIsolatedDeviceModel{},
|
||||
"host_isolated_device_models_tbl",
|
||||
"host_isolated_device_model",
|
||||
"host_isolated_device_models",
|
||||
IsolatedDeviceModelManager,
|
||||
),
|
||||
}
|
||||
HostIsolatedDeviceModelManager.SetVirtualObject(HostIsolatedDeviceModelManager)
|
||||
HostIsolatedDeviceModelManager.TableSpec().AddIndex(false, "host_id", "isolated_device_model_id")
|
||||
})
|
||||
}
|
||||
|
||||
type SHostIsolatedDeviceModel struct {
|
||||
SHostJointsBase
|
||||
|
||||
// 宿主机Id
|
||||
HostId string `width:"36" charset:"ascii" nullable:"false" list:"domain" create:"required" json:"host_id"`
|
||||
// 设备类型Id
|
||||
IsolatedDeviceModelId string `width:"36" charset:"ascii" nullable:"false" list:"domain" create:"required" json:"isolated_device_model_id" index:"true"`
|
||||
}
|
||||
|
||||
func (manager *SHostIsolatedDeviceModelManager) GetMasterFieldName() string {
|
||||
return "host_id"
|
||||
}
|
||||
|
||||
func (manager *SHostIsolatedDeviceModelManager) GetSlaveFieldName() string {
|
||||
return "isolated_device_model_id"
|
||||
}
|
||||
|
||||
func (self *SHostIsolatedDeviceModel) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
return db.DeleteModel(ctx, userCred, self)
|
||||
}
|
||||
|
||||
func (self *SHostIsolatedDeviceModel) Detach(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
return db.DetachJoint(ctx, userCred, self)
|
||||
}
|
||||
|
||||
func (manager *SHostIsolatedDeviceModelManager) FetchCustomizeColumns(
|
||||
ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject,
|
||||
objs []interface{},
|
||||
fields stringutils2.SSortedStrings,
|
||||
isList bool,
|
||||
) []api.HostIsolatedDeviceModelDetails {
|
||||
rows := make([]api.HostIsolatedDeviceModelDetails, len(objs))
|
||||
hostRows := manager.SHostJointsManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
||||
|
||||
devModelIds := make([]string, len(rows))
|
||||
for i := range rows {
|
||||
rows[i] = api.HostIsolatedDeviceModelDetails{
|
||||
HostJointResourceDetails: hostRows[i],
|
||||
}
|
||||
devModelIds[i] = objs[i].(*SHostIsolatedDeviceModel).IsolatedDeviceModelId
|
||||
}
|
||||
|
||||
devModels := make(map[string]SIsolatedDeviceModel)
|
||||
err := db.FetchStandaloneObjectsByIds(IsolatedDeviceModelManager, devModelIds, &devModels)
|
||||
if err != nil {
|
||||
log.Errorf("db.FetchStandaloneObjectsByIds fail %s", err)
|
||||
return rows
|
||||
}
|
||||
|
||||
for i := range rows {
|
||||
if devModel, ok := devModels[devModelIds[i]]; ok {
|
||||
rows[i] = objs[i].(*SHostIsolatedDeviceModel).getExtraDetails(devModel, rows[i])
|
||||
}
|
||||
}
|
||||
|
||||
return rows
|
||||
}
|
||||
|
||||
func (self *SHostIsolatedDeviceModel) getExtraDetails(devModel SIsolatedDeviceModel, out api.HostIsolatedDeviceModelDetails) api.HostIsolatedDeviceModelDetails {
|
||||
out.Model = devModel.Model
|
||||
out.VendorId = devModel.VendorId
|
||||
out.DeviceId = devModel.DeviceId
|
||||
out.DevType = devModel.DevType
|
||||
out.HotPluggable = devModel.HotPluggable.Bool()
|
||||
out.DisableAutoDetect = devModel.DisableAutoDetect.Bool()
|
||||
return out
|
||||
}
|
||||
|
||||
func (self *SHostIsolatedDeviceModel) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
|
||||
self.SHostJointsBase.PostCreate(ctx, userCred, ownerId, query, data)
|
||||
|
||||
iHost, err := HostManager.FetchByIdOrName(ctx, userCred, self.HostId)
|
||||
if err != nil {
|
||||
log.Errorf("failed fetch host %s: %s", self.HostId, err)
|
||||
return
|
||||
}
|
||||
host := iHost.(*SHost)
|
||||
log.Infof("start request host %s scan isolated devices", host.GetName())
|
||||
if err := host.RequestScanIsolatedDevices(ctx, userCred); err != nil {
|
||||
log.Errorf("failed scan isolated device %s", err)
|
||||
}
|
||||
}
|
||||
@@ -62,8 +62,15 @@ type SIsolatedDeviceModel struct {
|
||||
DevType string `width:"16" charset:"ascii" nullable:"false" list:"domain" create:"domain_required"`
|
||||
|
||||
HotPluggable tristate.TriState `default:"false" list:"domain" create:"domain_optional" update:"domain"`
|
||||
|
||||
// Disable auto detect isolated devices on host
|
||||
DisableAutoDetect tristate.TriState `default:"false" list:"domain" create:"domain_optional" update:"domain"`
|
||||
}
|
||||
|
||||
var _ db.IStandaloneModel = new(SIsolatedDeviceModel)
|
||||
|
||||
func (self *SIsolatedDeviceModel) SetName(name string) {}
|
||||
|
||||
func (manager *SIsolatedDeviceModelManager) ValidateCreateData(ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
ownerId mcclient.IIdentityProvider,
|
||||
@@ -102,9 +109,8 @@ func (self *SIsolatedDeviceModel) PostCreate(ctx context.Context, userCred mccli
|
||||
if err != nil {
|
||||
log.Errorf("!!!data.Unmarshal api.IsolatedDeviceModelCreateInput fail %s", err)
|
||||
}
|
||||
go func() {
|
||||
defer self.RemoveMetadata(ctx, api.MEAT_PROBED_HOST_COUNT, userCred)
|
||||
|
||||
go func() {
|
||||
for i := range input.Hosts {
|
||||
iHost, err := HostManager.FetchByIdOrName(ctx, userCred, input.Hosts[i])
|
||||
if err != nil {
|
||||
@@ -112,15 +118,37 @@ func (self *SIsolatedDeviceModel) PostCreate(ctx context.Context, userCred mccli
|
||||
continue
|
||||
}
|
||||
host := iHost.(*SHost)
|
||||
|
||||
if self.DisableAutoDetect.Bool() {
|
||||
err = self.Attach2Host(ctx, userCred, host)
|
||||
if err != nil {
|
||||
log.Errorf("failed attach to host %s: %s", input.Hosts[i], err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
log.Infof("start request host %s scan isolated devices", host.GetName())
|
||||
if err := host.RequestScanIsolatedDevices(ctx, userCred); err != nil {
|
||||
log.Errorf("failed scan isolated device %s", err)
|
||||
}
|
||||
self.SetMetadata(ctx, api.MEAT_PROBED_HOST_COUNT, strconv.Itoa(i+1), userCred)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (self *SIsolatedDeviceModel) Attach2Host(ctx context.Context, userCred mcclient.TokenCredential, host *SHost) error {
|
||||
hs := SHostIsolatedDeviceModel{}
|
||||
hs.SetModelManager(HostIsolatedDeviceModelManager, &hs)
|
||||
|
||||
hs.IsolatedDeviceModelId = self.Id
|
||||
hs.HostId = host.Id
|
||||
err := HostIsolatedDeviceModelManager.TableSpec().Insert(ctx, &hs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
db.OpsLog.LogAttachEvent(ctx, host, self, userCred, nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SIsolatedDeviceModel) ValidateDeleteCondition(ctx context.Context, info jsonutils.JSONObject) error {
|
||||
modelIsEmpty, err := IsolatedDeviceManager.CheckModelIsEmpty(self.Model, self.VendorId, self.DeviceId, self.DevType)
|
||||
if err != nil {
|
||||
@@ -217,6 +245,15 @@ func (manager *SIsolatedDeviceModelManager) ListItemFilter(
|
||||
if len(query.DeviceId) > 0 {
|
||||
q = q.Equals("device_id", query.DeviceId)
|
||||
}
|
||||
if len(query.HostId) > 0 {
|
||||
hidmq := HostIsolatedDeviceModelManager.Query("isolated_device_model_id").Equals("host_id", query.HostId).SubQuery()
|
||||
q = q.Filter(sqlchemy.OR(
|
||||
sqlchemy.IsFalse(q.Field("disable_auto_detect")),
|
||||
sqlchemy.IsNull(q.Field("disable_auto_detect")),
|
||||
sqlchemy.In(q.Field("id"), hidmq)),
|
||||
)
|
||||
}
|
||||
|
||||
return q, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -256,6 +256,7 @@ func InitHandlers(app *appsrv.Application) {
|
||||
models.HostnetworkManager,
|
||||
models.HoststorageManager,
|
||||
models.HostschedtagManager,
|
||||
models.HostIsolatedDeviceModelManager,
|
||||
models.StorageschedtagManager,
|
||||
models.NetworkschedtagManager,
|
||||
models.CloudproviderschedtagManager,
|
||||
|
||||
@@ -403,6 +403,7 @@ func (man *isolatedDeviceManager) getCustomIsolatedDeviceModels() ([]IsolatedDev
|
||||
params := jsonutils.NewDict()
|
||||
params.Set("limit", jsonutils.NewInt(0))
|
||||
params.Set("scope", jsonutils.NewString("system"))
|
||||
params.Set("host_id", jsonutils.NewString(man.host.GetHostId()))
|
||||
res, err := modules.IsolatedDeviceModels.List(man.getSession(), jsonutils.NewDict())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "list isolated_device_models from compute service")
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modulebase"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
)
|
||||
|
||||
var (
|
||||
HostIsolatedDeviceModels modulebase.JointResourceManager
|
||||
)
|
||||
|
||||
func init() {
|
||||
HostIsolatedDeviceModels = modules.NewJointComputeManager("host_isolated_device_model", "host_isolated_device_models",
|
||||
[]string{"Host_ID", "Host", "Isolated_device_model_id", "Isolated_device_model", "Model", "Dev_type", "Device_id", "Vendor_id",
|
||||
"Hot_pluggable", "Disable_auto_detect"},
|
||||
[]string{},
|
||||
&Hosts,
|
||||
&IsolatedDeviceModels)
|
||||
modules.RegisterCompute(&HostIsolatedDeviceModels)
|
||||
}
|
||||
@@ -26,7 +26,7 @@ var (
|
||||
func init() {
|
||||
IsolatedDeviceModels = modules.NewComputeManager("isolated_device_model", "isolated_device_models",
|
||||
[]string{"ID", "Dev_type",
|
||||
"Model", "Vendor_id", "Device_id"},
|
||||
"Model", "Vendor_id", "Device_id", "Hot_pluggable", "Disable_auto_detect"},
|
||||
[]string{})
|
||||
modules.RegisterCompute(&IsolatedDeviceModels)
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ type IsolatedDeviceModelListOptions struct {
|
||||
Model string `help:"filter by device model"`
|
||||
VendorId string `help:"filter by vendor id"`
|
||||
DeviceId string `help:"filter by device id"`
|
||||
HostId string `help:"filter by host id"`
|
||||
}
|
||||
|
||||
func (o *IsolatedDeviceModelListOptions) Params() (jsonutils.JSONObject, error) {
|
||||
@@ -35,11 +36,12 @@ func (o *IsolatedDeviceModelListOptions) Params() (jsonutils.JSONObject, error)
|
||||
}
|
||||
|
||||
type IsolatedDeviceModelCreateOptions struct {
|
||||
MODEL string `help:"device model name"`
|
||||
DEV_TYPE string `help:"custom device type"`
|
||||
VENDOR_ID string `help:"pci vendor id"`
|
||||
DEVICE_ID string `help:"pci device id"`
|
||||
Hosts []string `help:"hosts id or name rescan isolated device"`
|
||||
MODEL string `help:"device model name"`
|
||||
DEV_TYPE string `help:"custom device type"`
|
||||
VENDOR_ID string `help:"pci vendor id"`
|
||||
DEVICE_ID string `help:"pci device id"`
|
||||
DISABLE_AUTO_DETECT bool `help:"disable auto detect isolated devices on all of host"`
|
||||
Hosts []string `help:"hosts id or name rescan isolated device"`
|
||||
}
|
||||
|
||||
func (o *IsolatedDeviceModelCreateOptions) Params() (jsonutils.JSONObject, error) {
|
||||
@@ -49,9 +51,10 @@ func (o *IsolatedDeviceModelCreateOptions) Params() (jsonutils.JSONObject, error
|
||||
type IsolatedDeviceModelUpdateOptions struct {
|
||||
options.BaseIdOptions
|
||||
|
||||
MODEL string `help:"device model name"`
|
||||
VENDOR_ID string `help:"pci vendor id"`
|
||||
DEVICE_ID string `help:"pci device id"`
|
||||
MODEL string `help:"device model name"`
|
||||
VENDOR_ID string `help:"pci vendor id"`
|
||||
DEVICE_ID string `help:"pci device id"`
|
||||
DISABLE_AUTO_DETECT bool `help:"disable auto detect isolated devices on all of host"`
|
||||
}
|
||||
|
||||
func (o *IsolatedDeviceModelUpdateOptions) Params() (jsonutils.JSONObject, error) {
|
||||
|
||||
Reference in New Issue
Block a user