attach detach isolate device

This commit is contained in:
wanyaoqi
2018-09-14 11:50:22 +08:00
parent f910f6ada7
commit 92bbb9e235
2 changed files with 121 additions and 2 deletions
+90 -1
View File
@@ -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)
}
+31 -1
View File
@@ -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)
}