mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-21 14:19:49 +08:00
attach detach isolate device
This commit is contained in:
@@ -35,6 +35,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
"yunion.io/x/onecloud/pkg/util/httputils"
|
||||
"yunion.io/x/onecloud/pkg/util/logclient"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -2111,7 +2112,7 @@ func (self *SGuest) attachIsolatedDevice(userCred mcclient.TokenCredential, dev
|
||||
if dev.HostId != self.HostId {
|
||||
return fmt.Errorf("Isolated device and guest are not located in the same host")
|
||||
}
|
||||
_, err := self.GetModelManager().TableSpec().Update(self, func() error {
|
||||
_, err := IsolatedDeviceManager.TableSpec().Update(dev, func() error {
|
||||
dev.GuestId = self.Id
|
||||
return nil
|
||||
})
|
||||
@@ -2513,6 +2514,94 @@ func (self *SGuest) PerformDetachdisk(ctx context.Context, userCred mcclient.Tok
|
||||
return nil, httperrors.NewResourceNotFoundError("Disk %s not found", diskId)
|
||||
}
|
||||
|
||||
func (self *SGuest) AllowPerformDetachIsolatedDevice(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
return userCred.IsSystemAdmin()
|
||||
}
|
||||
|
||||
func (self *SGuest) PerformDetachIsolatedDevice(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
if self.Hypervisor != HYPERVISOR_KVM {
|
||||
return nil, httperrors.NewNotAcceptableError("Not allow for hypervisor %s", self.Hypervisor)
|
||||
}
|
||||
if self.Status != VM_READY {
|
||||
msg := "Only allowed to attach isolated device when guest is ready"
|
||||
logclient.AddActionLog(self, logclient.ACT_GUEST_DETACH_ISOLATED_DEVICE, msg, userCred, false)
|
||||
return nil, httperrors.NewInvalidStatusError(msg)
|
||||
}
|
||||
device, err := data.GetString("device")
|
||||
if err != nil {
|
||||
msg := "Missing isolated device"
|
||||
logclient.AddActionLog(self, logclient.ACT_GUEST_DETACH_ISOLATED_DEVICE, msg, userCred, false)
|
||||
return nil, httperrors.NewBadRequestError(msg)
|
||||
}
|
||||
iDev, err := IsolatedDeviceManager.FetchByIdOrName(userCred.GetProjectId(), device)
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("Isolated device %s not found", device)
|
||||
logclient.AddActionLog(self, logclient.ACT_GUEST_DETACH_ISOLATED_DEVICE, msg, userCred, false)
|
||||
return nil, httperrors.NewBadRequestError(msg)
|
||||
}
|
||||
dev := iDev.(*SIsolatedDevice)
|
||||
host := self.GetHost()
|
||||
lockman.LockObject(ctx, host)
|
||||
defer lockman.ReleaseObject(ctx, host)
|
||||
err = self.detachIsolateDevice(userCred, dev)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (self *SGuest) detachIsolateDevice(userCred mcclient.TokenCredential, dev *SIsolatedDevice) error {
|
||||
if dev.GuestId != self.Id {
|
||||
msg := "Isolated device is not attached to this guest"
|
||||
logclient.AddActionLog(self, logclient.ACT_GUEST_DETACH_ISOLATED_DEVICE, msg, userCred, false)
|
||||
return httperrors.NewBadRequestError(msg)
|
||||
}
|
||||
_, err := self.GetModelManager().TableSpec().Update(dev, func() error {
|
||||
dev.GuestId = ""
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
db.OpsLog.LogEvent(self, db.ACT_GUEST_DETACH_ISOLATED_DEVICE, dev.GetShortDesc(), userCred)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SGuest) AllowPerformAttachIsolatedDevice(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
return userCred.IsSystemAdmin()
|
||||
}
|
||||
|
||||
func (self *SGuest) PerformAttachIsolatedDevice(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
if self.Hypervisor != HYPERVISOR_KVM {
|
||||
return nil, httperrors.NewNotAcceptableError("Not allow for hypervisor %s", self.Hypervisor)
|
||||
}
|
||||
if self.Status != VM_READY {
|
||||
msg := "Only allowed to attach isolated device when guest is ready"
|
||||
logclient.AddActionLog(self, logclient.ACT_GUEST_ATTACH_ISOLATED_DEVICE, msg, userCred, false)
|
||||
return nil, httperrors.NewInvalidStatusError(msg)
|
||||
}
|
||||
device, err := data.GetString("device")
|
||||
if err != nil {
|
||||
msg := "Missing isolated device"
|
||||
logclient.AddActionLog(self, logclient.ACT_GUEST_ATTACH_ISOLATED_DEVICE, msg, userCred, false)
|
||||
return nil, httperrors.NewBadRequestError(msg)
|
||||
}
|
||||
iDev, err := IsolatedDeviceManager.FetchByIdOrName(userCred.GetProjectId(), device)
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("Isolated device %s not found", device)
|
||||
logclient.AddActionLog(self, logclient.ACT_GUEST_ATTACH_ISOLATED_DEVICE, msg, userCred, false)
|
||||
return nil, httperrors.NewBadRequestError(msg)
|
||||
}
|
||||
dev := iDev.(*SIsolatedDevice)
|
||||
host := self.GetHost()
|
||||
lockman.LockObject(ctx, host)
|
||||
defer lockman.ReleaseObject(ctx, host)
|
||||
err = self.attachIsolatedDevice(userCred, dev)
|
||||
var msg string
|
||||
if err != nil {
|
||||
msg = err.Error()
|
||||
}
|
||||
logclient.AddActionLog(self, logclient.ACT_GUEST_ATTACH_ISOLATED_DEVICE, msg, userCred, err == nil)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (self *SGuest) AllowPerformDetachnetwork(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
return self.IsOwner(userCred)
|
||||
}
|
||||
|
||||
@@ -452,10 +452,40 @@ func (self *SIsolatedDevice) GetCustomizeColumns(ctx context.Context, userCred m
|
||||
return extra
|
||||
}
|
||||
|
||||
func (self *SIsolatedDevice) ClearSchedDescCache() error {
|
||||
if len(self.HostId) == 0 {
|
||||
return nil
|
||||
}
|
||||
host := self.getHost()
|
||||
return host.ClearSchedDescCache()
|
||||
}
|
||||
|
||||
func (self *SIsolatedDevice) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
err := self.SStandaloneResourceBase.Delete(ctx, userCred)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return self.ClearSchedDescCache()
|
||||
}
|
||||
|
||||
func (self *SIsolatedDevice) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
|
||||
if len(self.GuestId) > 0 {
|
||||
if !jsonutils.QueryBoolean(data, "purge", false) {
|
||||
return httperrors.NewBadRequestError("Isolated device used by server: %s", self.GuestId)
|
||||
}
|
||||
iGuest, err := GuestManager.FetchById(self.GuestId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
guest := iGuest.(*SGuest)
|
||||
err = guest.detachIsolateDevice(userCred, self)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
host := self.getHost()
|
||||
if host != nil {
|
||||
db.OpsLog.LogEvent(host, db.ACT_HOST_DETACH_ISOLATED_DEVICE, self.GetShortDesc(), userCred)
|
||||
}
|
||||
return nil
|
||||
return self.RealDelete(ctx, userCred)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user