From 593e8c9fd8162b1eb5f3c9d74748070f4b139113 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=88=E8=BD=A9?= Date: Mon, 12 Nov 2018 20:38:27 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E4=B8=BB=E6=9C=BA=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E5=88=A4=E6=96=AD=E7=A3=81=E7=9B=98=E6=98=AF=E5=90=A6?= =?UTF-8?q?=E5=8F=AF=E4=BB=A5resize?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/compute/guestdrivers/aliyun.go | 13 +++++++ pkg/compute/guestdrivers/baremetals.go | 4 +++ pkg/compute/guestdrivers/base.go | 4 +++ pkg/compute/guestdrivers/kvm.go | 8 +++++ pkg/compute/models/disks.go | 50 +++++++++++++++----------- pkg/compute/models/guestdrivers.go | 1 + pkg/compute/models/guests.go | 4 +++ 7 files changed, 64 insertions(+), 20 deletions(-) diff --git a/pkg/compute/guestdrivers/aliyun.go b/pkg/compute/guestdrivers/aliyun.go index 087fde7f4d..fbbb928d6a 100644 --- a/pkg/compute/guestdrivers/aliyun.go +++ b/pkg/compute/guestdrivers/aliyun.go @@ -69,6 +69,19 @@ func (self *SAliyunGuestDriver) GetDeployStatus() ([]string, error) { return []string{models.VM_READY, models.VM_RUNNING}, nil } +func (self *SAliyunGuestDriver) ValidateResizeDisk(guest *models.SGuest, disk *models.SDisk, storage *models.SStorage) error { + if !utils.IsInStringArray(guest.Status, []string{models.VM_READY, models.VM_RUNNING}) { + return fmt.Errorf("Cannot resize disk when guest in status %s", guest.Status) + } + if disk.DiskType == models.DISK_TYPE_SYS { + return fmt.Errorf("Cannot resize system disk") + } + if !utils.IsInStringArray(storage.StorageType, []string{models.STORAGE_PUBLIC_CLOUD, models.STORAGE_CLOUD_SSD, models.STORAGE_CLOUD_EFFICIENCY}) { + return fmt.Errorf("Cannot resize %s disk", storage.StorageType) + } + return nil +} + func (self *SAliyunGuestDriver) RequestDetachDisk(ctx context.Context, guest *models.SGuest, task taskman.ITask) error { return guest.StartSyncTask(ctx, task.GetUserCred(), false, task.GetTaskId()) } diff --git a/pkg/compute/guestdrivers/baremetals.go b/pkg/compute/guestdrivers/baremetals.go index e372e4a959..f5525dbdbd 100644 --- a/pkg/compute/guestdrivers/baremetals.go +++ b/pkg/compute/guestdrivers/baremetals.go @@ -61,6 +61,10 @@ func (self *SBaremetalGuestDriver) GetDeployStatus() ([]string, error) { return []string{models.VM_READY, models.VM_ADMIN}, nil } +func (self *SBaremetalGuestDriver) ValidateResizeDisk(guest *models.SGuest, disk *models.SDisk, storage *models.SStorage) error { + return httperrors.NewUnsupportOperationError("Cannot resize disk for baremtal") +} + func (self *SBaremetalGuestDriver) GetNamedNetworkConfiguration(guest *models.SGuest, userCred mcclient.TokenCredential, host *models.SHost, netConfig *models.SNetworkConfig) (*models.SNetwork, string, int8, models.IPAddlocationDirection) { net, _ := host.GetNetworkWithIdAndCredential(netConfig.Network, userCred, netConfig.Reserved) return net, netConfig.Mac, -1, models.IPAllocationStepdown diff --git a/pkg/compute/guestdrivers/base.go b/pkg/compute/guestdrivers/base.go index 979f22cce6..f4b65ff955 100644 --- a/pkg/compute/guestdrivers/base.go +++ b/pkg/compute/guestdrivers/base.go @@ -111,6 +111,10 @@ func (self *SBaseGuestDriver) GetChangeConfigStatus() ([]string, error) { return []string{}, fmt.Errorf("This Guest driver dose not implement GetChangeConfigStatus") } +func (self *SBaseGuestDriver) ValidateResizeDisk(guest *models.SGuest, disk *models.SDisk, storage *models.SStorage) error { + return fmt.Errorf("This Guest driver dose not implement ValidateResizeDisk") +} + func (self *SBaseGuestDriver) GetDeployStatus() ([]string, error) { return []string{}, fmt.Errorf("This Guest driver dose not implement GetDeployStatus") } diff --git a/pkg/compute/guestdrivers/kvm.go b/pkg/compute/guestdrivers/kvm.go index 632dfe9676..ad30a3925a 100644 --- a/pkg/compute/guestdrivers/kvm.go +++ b/pkg/compute/guestdrivers/kvm.go @@ -9,6 +9,7 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/log" + "yunion.io/x/pkg/utils" "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" "yunion.io/x/onecloud/pkg/compute/models" @@ -238,6 +239,13 @@ func (self *SKVMGuestDriver) GetDeployStatus() ([]string, error) { return []string{models.VM_READY}, nil } +func (self *SKVMGuestDriver) ValidateResizeDisk(guest *models.SGuest, disk *models.SDisk, storage *models.SStorage) error { + if !utils.IsInStringArray(guest.Status, []string{models.VM_READY, models.VM_RUNNING}) { + return fmt.Errorf("Cannot resize disk when guest in status %s", guest.Status) + } + return nil +} + func (self *SKVMGuestDriver) RequestDeleteDetachedDisk(ctx context.Context, disk *models.SDisk, task taskman.ITask, isPurge bool) error { return disk.StartDiskDeleteTask(ctx, task.GetUserCred(), task.GetTaskId(), isPurge) } diff --git a/pkg/compute/models/disks.go b/pkg/compute/models/disks.go index d09be47d8c..e9c0e8d5af 100644 --- a/pkg/compute/models/disks.go +++ b/pkg/compute/models/disks.go @@ -347,28 +347,38 @@ func (self *SDisk) AllowPerformResize(ctx context.Context, userCred mcclient.Tok } func (self *SDisk) PerformResize(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { - if sizeStr, err := data.GetString("size"); err != nil { + sizeStr, err := data.GetString("size") + if err != nil { return nil, err - } else if size, err := fileutils.GetSizeMb(sizeStr, 'M', 1024); err != nil { - return nil, err - } else if self.Status != DISK_READY { - return nil, httperrors.NewResourceNotReadyError("Resize disk when disk is READY") - } else if size < self.DiskSize { - return nil, httperrors.NewUnsupportOperationError("Disk cannot be thrink") - } else if size == self.DiskSize { - return nil, nil - } else { - addDisk := size - self.DiskSize - storage := self.GetStorage() - if addDisk > storage.GetFreeCapacity() && !storage.IsEmulated { - return nil, httperrors.NewOutOfResourceError("Not enough free space") - } - pendingUsage := SQuota{Storage: int(addDisk)} - if err := QuotaManager.CheckSetPendingQuota(ctx, userCred, userCred.GetProjectId(), &pendingUsage); err != nil { - return nil, httperrors.NewOutOfQuotaError(err.Error()) - } - return nil, self.StartDiskResizeTask(ctx, userCred, int64(size), "", &pendingUsage) } + size, err := fileutils.GetSizeMb(sizeStr, 'M', 1024) + if err != nil { + return nil, err + } + if self.Status != DISK_READY { + return nil, httperrors.NewResourceNotReadyError("Resize disk when disk is READY") + } + if size < self.DiskSize { + return nil, httperrors.NewUnsupportOperationError("Disk cannot be thrink") + } + if size == self.DiskSize { + return nil, nil + } + addDisk := size - self.DiskSize + storage := self.GetStorage() + if addDisk > storage.GetFreeCapacity() && !storage.IsEmulated { + return nil, httperrors.NewOutOfResourceError("Not enough free space") + } + if guests := self.GetGuests(); len(guests) > 0 { + if err := guests[0].ValidateResizeDisk(self, storage); err != nil { + return nil, httperrors.NewInputParameterError(err.Error()) + } + } + pendingUsage := SQuota{Storage: int(addDisk)} + if err := QuotaManager.CheckSetPendingQuota(ctx, userCred, userCred.GetProjectId(), &pendingUsage); err != nil { + return nil, httperrors.NewOutOfQuotaError(err.Error()) + } + return nil, self.StartDiskResizeTask(ctx, userCred, int64(size), "", &pendingUsage) } func (self *SDisk) GetIStorage() (cloudprovider.ICloudStorage, error) { diff --git a/pkg/compute/models/guestdrivers.go b/pkg/compute/models/guestdrivers.go index 2801e5e0c6..013016d6d9 100644 --- a/pkg/compute/models/guestdrivers.go +++ b/pkg/compute/models/guestdrivers.go @@ -84,6 +84,7 @@ type IGuestDriver interface { GetRebuildRootStatus() ([]string, error) GetChangeConfigStatus() ([]string, error) GetDeployStatus() ([]string, error) + ValidateResizeDisk(guest *SGuest, disk *SDisk, storage *SStorage) error CanKeepDetachDisk() bool RequestDeleteDetachedDisk(ctx context.Context, disk *SDisk, task taskman.ITask, isPurge bool) error diff --git a/pkg/compute/models/guests.go b/pkg/compute/models/guests.go index 380c7d387d..0ba76b32c7 100644 --- a/pkg/compute/models/guests.go +++ b/pkg/compute/models/guests.go @@ -489,6 +489,10 @@ func (guest *SGuest) SetHostId(hostId string) error { return err } +func (guest *SGuest) ValidateResizeDisk(disk *SDisk, storage *SStorage) error { + return guest.GetDriver().ValidateResizeDisk(guest, disk, storage) +} + func validateMemCpuData(data jsonutils.JSONObject) (int, int, error) { vmemSize := 0 vcpuCount := 0