diff --git a/pkg/apis/compute/guests.go b/pkg/apis/compute/guests.go index 8134d33e93..31c2992de1 100644 --- a/pkg/apis/compute/guests.go +++ b/pkg/apis/compute/guests.go @@ -1625,6 +1625,17 @@ type ServerAttachIsolatedDeviceInput struct { Model string `json:"model"` } +type ServerDetachIsolatedDeviceInputBase struct { + Device string `json:"device"` + Index *int `json:"index"` +} +type ServerDetachIsolatedDeviceInput struct { + Devices []ServerDetachIsolatedDeviceInputBase `json:"devices"` + IsForce bool `json:"is_force"` + DetachAll bool `json:"detach_all"` + AutoStart bool `json:"auto_start"` +} + type ServerChangeBillingTypeInput struct { // 仅在虚拟机开机或关机状态下调用 // enmu: [postpaid, prepaid] diff --git a/pkg/apis/compute/isolated_device.go b/pkg/apis/compute/isolated_device.go index 9913edb797..76f7059fa9 100644 --- a/pkg/apis/compute/isolated_device.go +++ b/pkg/apis/compute/isolated_device.go @@ -41,7 +41,8 @@ type IsolateDeviceDetails struct { AllocatedCount int // 云主机名称 - Guest []string `json:"guest"` + Guest []string `json:"guest"` + GuestIds []string `json:"guest_ids"` // 云主机状态 GuestStatus []string `json:"guest_status"` } diff --git a/pkg/compute/models/guest_actions.go b/pkg/compute/models/guest_actions.go index 6619f203a4..76167d1e44 100644 --- a/pkg/compute/models/guest_actions.go +++ b/pkg/compute/models/guest_actions.go @@ -2428,12 +2428,11 @@ func (self *SGuest) DetachIsolatedDevices(ctx context.Context, userCred mcclient } // 卸载透传设备 -func (self *SGuest) PerformDetachIsolatedDevice(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { +func (self *SGuest) PerformDetachIsolatedDevice(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input *api.ServerDetachIsolatedDeviceInput) (jsonutils.JSONObject, error) { if self.Hypervisor != api.HYPERVISOR_KVM && self.Hypervisor != api.HYPERVISOR_POD { return nil, httperrors.NewNotAcceptableError("Not allow for hypervisor %s", self.Hypervisor) } - forceDetach := jsonutils.QueryBoolean(data, "is_force", false) - if !forceDetach { + if !input.IsForce { if !utils.IsInStringArray(self.GetStatus(), []string{api.VM_READY, api.VM_RUNNING}) || (self.Hypervisor == api.HYPERVISOR_POD && self.GetStatus() != api.VM_READY) { msg := fmt.Sprintf("Can't detach isolated device when guest is %s", self.GetStatus()) @@ -2448,46 +2447,49 @@ func (self *SGuest) PerformDetachIsolatedDevice(ctx context.Context, userCred mc } } - var detachAllDevice = jsonutils.QueryBoolean(data, "detach_all", false) devs := make([]SGuestIsolatedDevice, 0) - if !detachAllDevice { - device, err := data.GetString("device") - if err != nil { - msg := "Missing isolated device" - logclient.AddActionLogWithContext(ctx, self, logclient.ACT_GUEST_DETACH_ISOLATED_DEVICE, msg, userCred, false) - return nil, httperrors.NewBadRequestError("%s", msg) + if !input.DetachAll { + for i := range input.Devices { + device := input.Devices[i].Device + if input.Devices[i].Index == nil { + msg := "Missing isolated device index" + logclient.AddActionLogWithContext(ctx, self, logclient.ACT_GUEST_DETACH_ISOLATED_DEVICE, msg, userCred, false) + return nil, httperrors.NewBadRequestError("%s", msg) + } + index := *input.Devices[i].Index + iDev, err := IsolatedDeviceManager.FetchByIdOrName(ctx, userCred, device) + if err != nil { + msgFmt := "Isolated device %s not found" + msg := fmt.Sprintf(msgFmt, device) + logclient.AddActionLogWithContext(ctx, self, logclient.ACT_GUEST_DETACH_ISOLATED_DEVICE, msg, userCred, false) + return nil, httperrors.NewBadRequestError(msgFmt, device) + } + dev := iDev.(*SIsolatedDevice) + gdev, err := dev.GetGuestIsolatedDevice(self.Id, index) + if err != nil { + msg := err.Error() + logclient.AddActionLogWithContext(ctx, self, logclient.ACT_GUEST_DETACH_ISOLATED_DEVICE, msg, userCred, false) + return nil, httperrors.NewBadRequestError("%s", msg) + } + devs = append(devs, *gdev) } - index, err := data.Int("index") - if err != nil { - msg := "Missing isolated device index" - logclient.AddActionLogWithContext(ctx, self, logclient.ACT_GUEST_DETACH_ISOLATED_DEVICE, msg, userCred, false) - return nil, httperrors.NewBadRequestError("%s", msg) - } - iDev, err := IsolatedDeviceManager.FetchByIdOrName(ctx, userCred, device) - if err != nil { - msgFmt := "Isolated device %s not found" - msg := fmt.Sprintf(msgFmt, device) - logclient.AddActionLogWithContext(ctx, self, logclient.ACT_GUEST_DETACH_ISOLATED_DEVICE, msg, userCred, false) - return nil, httperrors.NewBadRequestError(msgFmt, device) - } - dev := iDev.(*SIsolatedDevice) - gdev, err := dev.GetGuestIsolatedDevice(self.Id, int(index)) + + } else { + var err error + devs, err = self.GetGuestIsolatedDevices() if err != nil { msg := err.Error() logclient.AddActionLogWithContext(ctx, self, logclient.ACT_GUEST_DETACH_ISOLATED_DEVICE, msg, userCred, false) return nil, httperrors.NewBadRequestError("%s", msg) } - devs = append(devs, *gdev) - } else { - devs, _ = self.GetGuestIsolatedDevices() } if err := self.DetachIsolatedDevices(ctx, userCred, devs); err != nil { return nil, err } - if forceDetach { + if input.IsForce { return nil, nil } - return nil, self.StartIsolatedDevicesSyncTask(ctx, userCred, jsonutils.QueryBoolean(data, "auto_start", false), "") + return nil, self.StartIsolatedDevicesSyncTask(ctx, userCred, input.AutoStart, "") } func (self *SGuest) startDetachIsolateDeviceWithoutNic(ctx context.Context, userCred mcclient.TokenCredential, device string, index int) error { diff --git a/pkg/compute/models/isolated_devices.go b/pkg/compute/models/isolated_devices.go index fccfefee93..d3efe34ca1 100644 --- a/pkg/compute/models/isolated_devices.go +++ b/pkg/compute/models/isolated_devices.go @@ -1592,12 +1592,14 @@ func (manager *SIsolatedDeviceManager) FetchCustomizeColumns( nguests := guestIds[i] if len(nguests) > 0 { rows[i].Guest = make([]string, len(nguests)) + rows[i].GuestIds = make([]string, len(nguests)) rows[i].GuestStatus = make([]string, len(nguests)) } for j := range nguests { if guest, ok := guests[nguests[j]]; ok { rows[i].Guest[j] = guest.Name + rows[i].GuestIds[j] = guest.Id rows[i].GuestStatus[j] = guest.Status } } diff --git a/pkg/compute/models/isolateddeviceresouce.go b/pkg/compute/models/isolateddeviceresouce.go index 9eec8eb03e..998b283ec8 100644 --- a/pkg/compute/models/isolateddeviceresouce.go +++ b/pkg/compute/models/isolateddeviceresouce.go @@ -82,6 +82,7 @@ func (manager *SIsolatedDeviceResourceBaseManager) FetchCustomizeColumns( rows[i].SharableResourceBaseInfo = devRows[i].SharableResourceBaseInfo rows[i].HostResourceInfo = devRows[i].HostResourceInfo rows[i].Guest = devRows[i].Guest + rows[i].GuestIds = devRows[i].GuestIds rows[i].GuestStatus = devRows[i].GuestStatus rows[i].Vendor = devRows[i].Vendor rows[i].MemoryAllocated = devRows[i].MemoryAllocated