diff --git a/pkg/compute/hostdrivers/aliyun.go b/pkg/compute/hostdrivers/aliyun.go index 2c9df47e38..47bdbe971e 100644 --- a/pkg/compute/hostdrivers/aliyun.go +++ b/pkg/compute/hostdrivers/aliyun.go @@ -13,6 +13,7 @@ import ( "yunion.io/x/onecloud/pkg/compute/models" "yunion.io/x/onecloud/pkg/compute/options" "yunion.io/x/onecloud/pkg/httperrors" + "yunion.io/x/pkg/utils" ) type SAliyunHostDriver struct { @@ -28,6 +29,21 @@ func (self *SAliyunHostDriver) GetHostType() string { return models.HOST_TYPE_ALIYUN } +func (self *SAliyunHostDriver) ValidateCreateDisk(storage *models.SStorage, sizeGb int) error { + if utils.IsInStringArray(storage.StorageType, []string{models.STORAGE_CLOUD_EFFICIENCY, models.STORAGE_CLOUD_SSD, models.STORAGE_CLOUD_ESSD}) { + if sizeGb < 20 || sizeGb > 32768 { + return fmt.Errorf("The %s disk size must be in the range of 20G ~ 32768G", storage.StorageType) + } + } else if storage.StorageType == models.STORAGE_PUBLIC_CLOUD { + if sizeGb < 5 || sizeGb > 2000 { + return fmt.Errorf("The %s disk size must be in the range of 5G ~ 2000G", storage.StorageType) + } + } else { + return fmt.Errorf("Not support create %s disk", storage.StorageType) + } + return nil +} + func (self *SAliyunHostDriver) CheckAndSetCacheImage(ctx context.Context, host *models.SHost, storageCache *models.SStoragecache, task taskman.ITask) error { params := task.GetParams() imageId, err := params.GetString("image_id") diff --git a/pkg/compute/hostdrivers/aws.go b/pkg/compute/hostdrivers/aws.go index b4022ab211..c1dd56a6c9 100644 --- a/pkg/compute/hostdrivers/aws.go +++ b/pkg/compute/hostdrivers/aws.go @@ -3,11 +3,13 @@ package hostdrivers import ( "context" "fmt" + "yunion.io/x/log" "yunion.io/x/onecloud/pkg/cloudcommon/db/lockman" "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/compute/options" "yunion.io/x/onecloud/pkg/httperrors" + "yunion.io/x/pkg/utils" "yunion.io/x/jsonutils" "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" @@ -22,6 +24,29 @@ func (self *SAwsHostDriver) GetHostType() string { return models.HOST_TYPE_AWS } +func (self *SAwsHostDriver) ValidateCreateDisk(storage *models.SStorage, sizeGb int) error { + if storage.StorageType == models.STORAGE_GP2_SSD { + if sizeGb < 1 || sizeGb > 16384 { + return fmt.Errorf("The %s disk size must be in the range of 1G ~ 16384GB", storage.StorageType) + } + } else if storage.StorageType == models.STORAGE_IO1_SSD { + if sizeGb < 4 || sizeGb > 16384 { + return fmt.Errorf("The %s disk size must be in the range of 4G ~ 16384GB", storage.StorageType) + } + } else if utils.IsInStringArray(storage.StorageType, []string{models.STORAGE_ST1_HDD, models.STORAGE_SC1_SSD}) { + if sizeGb < 500 || sizeGb > 16384 { + return fmt.Errorf("The %s disk size must be in the range of 500G ~ 16384GB", storage.StorageType) + } + } else if storage.StorageType == models.STORAGE_STANDARD_SSD { + if sizeGb < 1 || sizeGb > 1024 { + return fmt.Errorf("The %s disk size must be in the range of 1G ~ 1024GB", storage.StorageType) + } + } else { + return fmt.Errorf("Not support create %s disk", storage.StorageType) + } + return nil +} + func (self *SAwsHostDriver) CheckAndSetCacheImage(ctx context.Context, host *models.SHost, storageCache *models.SStoragecache, task taskman.ITask) error { params := task.GetParams() imageId, err := params.GetString("image_id") diff --git a/pkg/compute/hostdrivers/azure.go b/pkg/compute/hostdrivers/azure.go index 6635e9c879..edcf0d15e7 100644 --- a/pkg/compute/hostdrivers/azure.go +++ b/pkg/compute/hostdrivers/azure.go @@ -36,6 +36,10 @@ func (self *SAzureHostDriver) ValidateUpdateDisk(ctx context.Context, userCred m return data, nil } +func (self *SAzureHostDriver) ValidateCreateDisk(storage *models.SStorage, sizeGb int) error { + return nil +} + func (self *SAzureHostDriver) CheckAndSetCacheImage(ctx context.Context, host *models.SHost, storageCache *models.SStoragecache, task taskman.ITask) error { params := task.GetParams() imageId, err := params.GetString("image_id") diff --git a/pkg/compute/hostdrivers/base.go b/pkg/compute/hostdrivers/base.go index fc254c05e4..a245b2befa 100644 --- a/pkg/compute/hostdrivers/base.go +++ b/pkg/compute/hostdrivers/base.go @@ -20,6 +20,10 @@ func (self *SBaseHostDriver) ValidateUpdateDisk(ctx context.Context, userCred mc return data, nil } +func (self *SBaseHostDriver) ValidateCreateDisk(storage *models.SStorage, sizeGb int) error { + return fmt.Errorf("ot Implement ValidateCreateDisk") +} + func (self *SBaseHostDriver) RequestDeleteSnapshotsWithStorage(ctx context.Context, host *models.SHost, snapshot *models.SSnapshot, task taskman.ITask) error { return fmt.Errorf("Not Implement") } diff --git a/pkg/compute/hostdrivers/qcloud.go b/pkg/compute/hostdrivers/qcloud.go index 536c620c64..19c59970e1 100644 --- a/pkg/compute/hostdrivers/qcloud.go +++ b/pkg/compute/hostdrivers/qcloud.go @@ -28,6 +28,28 @@ func (self *SQcloudHostDriver) GetHostType() string { return models.HOST_TYPE_QCLOUD } +func (self *SQcloudHostDriver) ValidateCreateDisk(storage *models.SStorage, sizeGb int) error { + if sizeGb%10 != 0 { + return fmt.Errorf("The disk size must be a multiple of 10Gb") + } + if storage.StorageType == models.STORAGE_CLOUD_BASIC { + if sizeGb < 10 || sizeGb > 16000 { + return fmt.Errorf("The %s disk size must be in the range of 10 ~ 16000GB", storage.StorageType) + } + } else if storage.StorageType == models.STORAGE_CLOUD_PREMIUM { + if sizeGb < 50 || sizeGb > 16000 { + return fmt.Errorf("The %s disk size must be in the range of 50 ~ 16000GB", storage.StorageType) + } + } else if storage.StorageType == models.STORAGE_CLOUD_SSD { + if sizeGb < 100 || sizeGb > 16000 { + return fmt.Errorf("The %s disk size must be in the range of 100 ~ 16000GB", storage.StorageType) + } + } else { + return fmt.Errorf("Not support create %s disk", storage.StorageType) + } + return nil +} + func (self *SQcloudHostDriver) CheckAndSetCacheImage(ctx context.Context, host *models.SHost, storageCache *models.SStoragecache, task taskman.ITask) error { params := task.GetParams() imageId, err := params.GetString("image_id") diff --git a/pkg/compute/models/disks.go b/pkg/compute/models/disks.go index e09560fc9e..b75255497a 100644 --- a/pkg/compute/models/disks.go +++ b/pkg/compute/models/disks.go @@ -293,7 +293,7 @@ func (manager *SDiskManager) ValidateCreateData(ctx context.Context, userCred mc if _, err := manager.SSharableVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerProjId, query, data); err != nil { return nil, err } - pendingUsage := SQuota{Storage: diskConfig.Size} + pendingUsage := SQuota{Storage: diskConfig.SizeMb} if err := QuotaManager.CheckSetPendingQuota(ctx, userCred, userCred.GetProjectId(), &pendingUsage); err != nil { return nil, err } @@ -310,14 +310,11 @@ func (manager *SDiskManager) validateDiskOnStorage(diskConfig *SDiskConfig, stor if storage.StorageType != diskConfig.Backend { return httperrors.NewInputParameterError("Storage type[%s] not match backend %s", storage.StorageType, diskConfig.Backend) } - size := diskConfig.Size >> 10 - if storage.StorageType == STORAGE_CLOUD_EFFICIENCY || storage.StorageType == STORAGE_CLOUD_SSD { - if size < 20 || size > 32768 { - return httperrors.NewInputParameterError("cloud_ssd or cloud_efficiency disk only support 20G ~ 32768G") - } - } else if storage.StorageType == STORAGE_PUBLIC_CLOUD { - if size < 5 || size > 2000 { - return httperrors.NewInputParameterError("cloud disk only support 5G ~ 2000G") + sizeGb := diskConfig.SizeMb >> 10 + if host := storage.GetMasterHost(); host != nil { + //公有云磁盘大小检查。 + if err := host.GetHostDriver().ValidateCreateDisk(storage, sizeGb); err != nil { + return httperrors.NewInputParameterError(err.Error()) } } hoststorages := HoststorageManager.Query().SubQuery() @@ -328,7 +325,7 @@ func (manager *SDiskManager) validateDiskOnStorage(diskConfig *SDiskConfig, stor if len(hoststorage) == 0 { return httperrors.NewInputParameterError("Storage[%s] must attach to a host", storage.Name) } - if diskConfig.Size > storage.GetFreeCapacity() && !storage.IsEmulated { + if diskConfig.SizeMb > storage.GetFreeCapacity() && !storage.IsEmulated { return httperrors.NewInputParameterError("Not enough free space") } return nil @@ -968,7 +965,7 @@ func totalDiskSize(projectId string, active tristate.TriState, ready tristate.Tr type SDiskConfig struct { ImageId string // ImageDiskFormat string - Size int // MB + SizeMb int // MB Fs string // file system Format string // Driver string // @@ -1006,7 +1003,7 @@ func parseDiskInfo(ctx context.Context, userCred mcclient.TokenCredential, info continue } if regutils.MatchSize(p) { - diskConfig.Size, _ = fileutils.GetSizeMb(p, 'M', 1024) + diskConfig.SizeMb, _ = fileutils.GetSizeMb(p, 'M', 1024) } else if utils.IsInStringArray(p, osprofile.FS_TYPES) { diskConfig.Fs = p } else if utils.IsInStringArray(p, osprofile.IMAGE_FORMAT_TYPES) { @@ -1020,7 +1017,7 @@ func parseDiskInfo(ctx context.Context, userCred mcclient.TokenCredential, info } else if p[0] == '/' { diskConfig.Mountpoint = p } else if p == "autoextend" { - diskConfig.Size = -1 + diskConfig.SizeMb = -1 } else if utils.IsInStringArray(p, STORAGE_TYPES) { diskConfig.Backend = p } else if len(p) > 0 { @@ -1042,15 +1039,15 @@ func parseDiskInfo(ctx context.Context, userCred mcclient.TokenCredential, info } // diskConfig.ImageDiskFormat = image.DiskFormat CachedimageManager.ImageAddRefCount(image.Id) - if diskConfig.Size == 0 { - diskConfig.Size = image.MinDisk // MB + if diskConfig.SizeMb == 0 { + diskConfig.SizeMb = image.MinDisk // MB } } } } - if len(diskConfig.ImageId) > 0 && diskConfig.Size == 0 { - diskConfig.Size = options.Options.DefaultDiskSize // MB - } else if len(diskConfig.ImageId) == 0 && diskConfig.Size == 0 { + if len(diskConfig.ImageId) > 0 && diskConfig.SizeMb == 0 { + diskConfig.SizeMb = options.Options.DefaultDiskSize // MB + } else if len(diskConfig.ImageId) == 0 && diskConfig.SizeMb == 0 { return nil, httperrors.NewInputParameterError("Diskinfo not contains either imageID or size") } return &diskConfig, nil @@ -1086,7 +1083,7 @@ func (self *SDisk) fetchDiskInfo(diskConfig *SDiskConfig) { self.Nonpersistent = false } self.DiskFormat = diskConfig.Format - self.DiskSize = diskConfig.Size + self.DiskSize = diskConfig.SizeMb } type DiskInfo struct { diff --git a/pkg/compute/models/guest_actions.go b/pkg/compute/models/guest_actions.go index 0ab0ea09d7..0ebbad08e5 100644 --- a/pkg/compute/models/guest_actions.go +++ b/pkg/compute/models/guest_actions.go @@ -834,11 +834,11 @@ func (self *SGuest) PerformCreatedisk(ctx context.Context, userCred mcclient.Tok } disksConf.Set(diskSeq, jsonutils.Marshal(diskInfo)) if _, ok := diskSizes[diskInfo.Backend]; !ok { - diskSizes[diskInfo.Backend] = diskInfo.Size + diskSizes[diskInfo.Backend] = diskInfo.SizeMb } else { - diskSizes[diskInfo.Backend] += diskInfo.Size + diskSizes[diskInfo.Backend] += diskInfo.SizeMb } - diskSize += diskInfo.Size + diskSize += diskInfo.SizeMb diskIdx += 1 diskSeq = fmt.Sprintf("disk.%d", diskIdx) } @@ -1193,11 +1193,11 @@ func (self *SGuest) PerformChangeConfig(ctx context.Context, userCred mcclient.T if len(diskConf.Backend) == 0 { diskConf.Backend = self.getDefaultStorageType() } - if diskConf.Size > 0 { + if diskConf.SizeMb > 0 { if diskIdx >= len(disks) { newDisks.Add(jsonutils.Marshal(diskConf), fmt.Sprintf("disk.%d", newDiskIdx)) newDiskIdx += 1 - addDisk += diskConf.Size + addDisk += diskConf.SizeMb storage := host.GetLeastUsedStorage(diskConf.Backend) if storage == nil { return nil, httperrors.NewResourceNotReadyError("host not connect storage %s", diskConf.Backend) @@ -1206,22 +1206,22 @@ func (self *SGuest) PerformChangeConfig(ctx context.Context, userCred mcclient.T if !ok { diskSizes[storage.Id] = 0 } - diskSizes[storage.Id] = diskSizes[storage.Id] + diskConf.Size + diskSizes[storage.Id] = diskSizes[storage.Id] + diskConf.SizeMb } else { disk := disks[diskIdx].GetDisk() oldSize := disk.DiskSize - if diskConf.Size < oldSize { + if diskConf.SizeMb < oldSize { return nil, httperrors.NewInputParameterError("Cannot reduce disk size") - } else if diskConf.Size > oldSize { - arr := jsonutils.NewArray(jsonutils.NewString(disks[diskIdx].DiskId), jsonutils.NewInt(int64(diskConf.Size))) + } else if diskConf.SizeMb > oldSize { + arr := jsonutils.NewArray(jsonutils.NewString(disks[diskIdx].DiskId), jsonutils.NewInt(int64(diskConf.SizeMb))) resizeDisks.Add(arr) - addDisk += diskConf.Size - oldSize + addDisk += diskConf.SizeMb - oldSize storage := disks[diskIdx].GetDisk().GetStorage() _, ok := diskSizes[storage.Id] if !ok { diskSizes[storage.Id] = 0 } - diskSizes[storage.Id] = diskSizes[storage.Id] + diskConf.Size - oldSize + diskSizes[storage.Id] = diskSizes[storage.Id] + diskConf.SizeMb - oldSize } } } diff --git a/pkg/compute/models/guests.go b/pkg/compute/models/guests.go index 4d513dea9a..e9d93e888d 100644 --- a/pkg/compute/models/guests.go +++ b/pkg/compute/models/guests.go @@ -820,7 +820,7 @@ func getGuestResourceRequirements(ctx context.Context, userCred mcclient.TokenCr for idx := 0; data.Contains(fmt.Sprintf("disk.%d", idx)); idx += 1 { dataJson, _ := data.Get(fmt.Sprintf("disk.%d", idx)) diskConfig, _ := parseDiskInfo(ctx, userCred, dataJson) - diskSize += diskConfig.Size + diskSize += diskConfig.SizeMb } devCount := 0 diff --git a/pkg/compute/models/hostdrivers.go b/pkg/compute/models/hostdrivers.go index d6217e3c69..fc2cfe89de 100644 --- a/pkg/compute/models/hostdrivers.go +++ b/pkg/compute/models/hostdrivers.go @@ -14,6 +14,7 @@ type IHostDriver interface { GetHostType() string CheckAndSetCacheImage(ctx context.Context, host *SHost, storagecache *SStoragecache, task taskman.ITask) error ValidateUpdateDisk(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) + ValidateCreateDisk(storage *SStorage, sizeGb int) error RequestPrepareSaveDiskOnHost(ctx context.Context, host *SHost, disk *SDisk, imageId string, task taskman.ITask) error RequestSaveUploadImageOnHost(ctx context.Context, host *SHost, disk *SDisk, imageId string, task taskman.ITask, data jsonutils.JSONObject) error RequestAllocateDiskOnStorage(ctx context.Context, host *SHost, storage *SStorage, disk *SDisk, task taskman.ITask, content *jsonutils.JSONDict) error