feat: support lock storage from selected cachedimage

This commit is contained in:
rainzm
2020-10-17 17:38:37 +08:00
parent f9be2999c6
commit 10f0f07bdb
17 changed files with 103 additions and 32 deletions
+2 -2
View File
@@ -77,8 +77,8 @@ func (self *SAliyunGuestDriver) GetStorageTypes() []string {
}
}
func (self *SAliyunGuestDriver) ChooseHostStorage(host *models.SHost, backend string, storageIds []string) *models.SStorage {
return self.chooseHostStorage(self, host, backend, storageIds)
func (self *SAliyunGuestDriver) ChooseHostStorage(host *models.SHost, diskConfig *api.DiskConfig, storageIds []string) (*models.SStorage, error) {
return self.chooseHostStorage(self, host, diskConfig.Backend, storageIds), nil
}
func (self *SAliyunGuestDriver) GetDetachDiskStatus() ([]string, error) {
+2 -2
View File
@@ -131,8 +131,8 @@ func (self *SAwsGuestDriver) GetStorageTypes() []string {
}
}
func (self *SAwsGuestDriver) ChooseHostStorage(host *models.SHost, backend string, storageIds []string) *models.SStorage {
return self.chooseHostStorage(self, host, backend, storageIds)
func (self *SAwsGuestDriver) ChooseHostStorage(host *models.SHost, diskConfig *api.DiskConfig, storageIds []string) (*models.SStorage, error) {
return self.chooseHostStorage(self, host, diskConfig.Backend, storageIds), nil
}
func (self *SAwsGuestDriver) GetDetachDiskStatus() ([]string, error) {
+2 -2
View File
@@ -79,8 +79,8 @@ func (self *SAzureGuestDriver) GetStorageTypes() []string {
}
}
func (self *SAzureGuestDriver) ChooseHostStorage(host *models.SHost, backend string, storageIds []string) *models.SStorage {
return self.chooseHostStorage(self, host, backend, storageIds)
func (self *SAzureGuestDriver) ChooseHostStorage(host *models.SHost, diskConfig *api.DiskConfig, storageIds []string) (*models.SStorage, error) {
return self.chooseHostStorage(self, host, diskConfig.Backend, storageIds), nil
}
func (self *SAzureGuestDriver) GetMaxSecurityGroupCount() int {
+4 -4
View File
@@ -249,15 +249,15 @@ func (self *SBaremetalGuestDriver) GetStorageTypes() []string {
}
}
func (self *SBaremetalGuestDriver) ChooseHostStorage(host *models.SHost, backend string, storageIds []string) *models.SStorage {
func (self *SBaremetalGuestDriver) ChooseHostStorage(host *models.SHost, diskConfig *api.DiskConfig, storageIds []string) (*models.SStorage, error) {
if len(storageIds) != 0 {
return models.StorageManager.FetchStorageById(storageIds[0])
return models.StorageManager.FetchStorageById(storageIds[0]), nil
}
bs := host.GetBaremetalstorage()
if bs == nil {
return nil
return nil, nil
}
return bs.GetStorage()
return bs.GetStorage(), nil
}
func (self *SBaremetalGuestDriver) RequestGuestCreateAllDisks(ctx context.Context, guest *models.SGuest, task taskman.ITask) error {
+40
View File
@@ -79,6 +79,46 @@ func (self *SESXiGuestDriver) GetDefaultSysDiskBackend() string {
return api.STORAGE_LOCAL
}
func (self *SESXiGuestDriver) ChooseHostStorage(host *models.SHost, diskConfig *api.DiskConfig, storageIds []string) (*models.SStorage, error) {
if !options.Options.LockStorageFromCachedimage || len(diskConfig.ImageId) == 0 {
return self.SVirtualizedGuestDriver.ChooseHostStorage(host, diskConfig, storageIds)
}
var (
image *cloudprovider.SImage
err error
)
obj, err := models.CachedimageManager.FetchById(diskConfig.ImageId)
if err != nil {
return nil, errors.Wrapf(err, "unable to fetch cachedimage %s", diskConfig.ImageId)
}
cachedimage := obj.(*models.SCachedimage)
if len(cachedimage.ExternalId) > 0 || cachedimage.ImageType != cloudprovider.CachedImageTypeSystem {
return self.SVirtualizedGuestDriver.ChooseHostStorage(host, diskConfig, storageIds)
}
storages, err := cachedimage.GetStorages()
if err != nil {
return nil, errors.Wrapf(err, "unable to GetStorages of cachedimage %s", diskConfig.ImageId)
}
if len(storages) == 0 {
log.Warningf("there no storage associated with cachedimage %q", image.Id)
return self.SVirtualizedGuestDriver.ChooseHostStorage(host, diskConfig, storageIds)
}
if len(storages) > 1 {
log.Warningf("there are multiple storageCache associated with caheimage %q", image.Id)
}
wantStorageIds := make([]string, len(storages))
for i := range wantStorageIds {
wantStorageIds[i] = storages[i].GetId()
}
for i := range wantStorageIds {
if utils.IsInStringArray(wantStorageIds[i], storageIds) {
log.Infof("use storage %q in where cachedimage %q", wantStorageIds[i], image.Id)
return &storages[i], nil
}
}
return self.SVirtualizedGuestDriver.ChooseHostStorage(host, diskConfig, storageIds)
}
func (self *SESXiGuestDriver) GetMinimalSysDiskSizeGb() int {
return options.Options.DefaultDiskSizeMB / 1024
}
+2 -2
View File
@@ -81,8 +81,8 @@ func (self *SGoogleGuestDriver) GetStorageTypes() []string {
}
}
func (self *SGoogleGuestDriver) ChooseHostStorage(host *models.SHost, backend string, storageIds []string) *models.SStorage {
return self.chooseHostStorage(self, host, backend, storageIds)
func (self *SGoogleGuestDriver) ChooseHostStorage(host *models.SHost, diskConfig *api.DiskConfig, storageIds []string) (*models.SStorage, error) {
return self.chooseHostStorage(self, host, diskConfig.Backend, storageIds), nil
}
func (self *SGoogleGuestDriver) GetGuestInitialStateAfterCreate() string {
+2 -2
View File
@@ -67,8 +67,8 @@ func (self *SHuaweiGuestDriver) GetStorageTypes() []string {
return []string{api.STORAGE_HUAWEI_SATA, api.STORAGE_HUAWEI_SAS, api.STORAGE_HUAWEI_SSD}
}
func (self *SHuaweiGuestDriver) ChooseHostStorage(host *models.SHost, backend string, storageIds []string) *models.SStorage {
return self.chooseHostStorage(self, host, backend, storageIds)
func (self *SHuaweiGuestDriver) ChooseHostStorage(host *models.SHost, diskConfig *api.DiskConfig, storageIds []string) (*models.SStorage, error) {
return self.chooseHostStorage(self, host, diskConfig.Backend, storageIds), nil
}
func (self *SHuaweiGuestDriver) GetDetachDiskStatus() ([]string, error) {
+2 -2
View File
@@ -91,8 +91,8 @@ func (self *SOpenStackGuestDriver) GetStorageTypes() []string {
return storages
}
func (self *SOpenStackGuestDriver) ChooseHostStorage(host *models.SHost, backend string, storageIds []string) *models.SStorage {
return self.chooseHostStorage(self, host, backend, storageIds)
func (self *SOpenStackGuestDriver) ChooseHostStorage(host *models.SHost, diskConfig *api.DiskConfig, storageIds []string) (*models.SStorage, error) {
return self.chooseHostStorage(self, host, diskConfig.Backend, storageIds), nil
}
func (self *SOpenStackGuestDriver) GetDetachDiskStatus() ([]string, error) {
+2 -2
View File
@@ -75,8 +75,8 @@ func (self *SQcloudGuestDriver) GetStorageTypes() []string {
}
}
func (self *SQcloudGuestDriver) ChooseHostStorage(host *models.SHost, backend string, storageIds []string) *models.SStorage {
return self.chooseHostStorage(self, host, backend, storageIds)
func (self *SQcloudGuestDriver) ChooseHostStorage(host *models.SHost, diskConfig *api.DiskConfig, storageIds []string) (*models.SStorage, error) {
return self.chooseHostStorage(self, host, diskConfig.Backend, storageIds), nil
}
func (self *SQcloudGuestDriver) GetDetachDiskStatus() ([]string, error) {
+3 -3
View File
@@ -174,11 +174,11 @@ func (self *SVirtualizedGuestDriver) GetStorageTypes() []string {
return nil
}
func (self *SVirtualizedGuestDriver) ChooseHostStorage(host *models.SHost, backend string, storageIds []string) *models.SStorage {
func (self *SVirtualizedGuestDriver) ChooseHostStorage(host *models.SHost, diskConfig *api.DiskConfig, storageIds []string) (*models.SStorage, error) {
if len(storageIds) == 0 {
return host.GetLeastUsedStorage(backend)
return host.GetLeastUsedStorage(diskConfig.Backend), nil
}
return models.StorageManager.FetchStorageById(storageIds[0])
return models.StorageManager.FetchStorageById(storageIds[0]), nil
}
func (self *SVirtualizedGuestDriver) RequestGuestCreateInsertIso(ctx context.Context, imageId string, guest *models.SGuest, task taskman.ITask) error {
+2 -2
View File
@@ -85,8 +85,8 @@ func (self *SZStackGuestDriver) GetMaxSecurityGroupCount() int {
return 1
}
func (self *SZStackGuestDriver) ChooseHostStorage(host *models.SHost, backend string, storageIds []string) *models.SStorage {
return self.chooseHostStorage(self, host, backend, storageIds)
func (self *SZStackGuestDriver) ChooseHostStorage(host *models.SHost, diskConfig *api.DiskConfig, storageIds []string) (*models.SStorage, error) {
return self.chooseHostStorage(self, host, diskConfig.Backend, storageIds), nil
}
func (self *SZStackGuestDriver) GetDetachDiskStatus() ([]string, error) {
+12
View File
@@ -272,6 +272,18 @@ func (manager *SCachedimageManager) cacheGlanceImageInfo(ctx context.Context, us
}
}
func (image *SCachedimage) GetStorages() ([]SStorage, error) {
sq := StorageManager.Query()
storagecacheimageSubq := StoragecachedimageManager.Query("storagecache_id").Equals("cachedimage_id", image.GetId()).SubQuery()
sq.Join(storagecacheimageSubq, sqlchemy.Equals(sq.Field("storagecache_id"), storagecacheimageSubq.Field("storagecache_id")))
storages := make([]SStorage, 0, 1)
err := db.FetchModelObjects(StorageManager, sq, &storages)
if err != nil {
return nil, errors.Wrap(err, "FetchModelObjects")
}
return storages, nil
}
func (manager *SCachedimageManager) GetImageById(ctx context.Context, userCred mcclient.TokenCredential, imageId string, refresh bool) (*cloudprovider.SImage, error) {
imgObj, _ := manager.FetchById(imageId)
if imgObj != nil {
+1 -1
View File
@@ -73,7 +73,7 @@ type IGuestDriver interface {
GetRandomNetworkTypes() []string
GetStorageTypes() []string
ChooseHostStorage(host *SHost, backend string, storageIds []string) *SStorage
ChooseHostStorage(host *SHost, diskConfig *api.DiskConfig, storageIds []string) (*SStorage, error)
StartGuestCreateTask(guest *SGuest, ctx context.Context, userCred mcclient.TokenCredential, params *jsonutils.JSONDict, pendingUsage quotas.IQuota, parentTaskId string) error
+15 -6
View File
@@ -3426,11 +3426,11 @@ func (self *SGuest) createDiskOnStorage(ctx context.Context, userCred mcclient.T
return disk, nil
}
func (self *SGuest) ChooseHostStorage(host *SHost, backend string, candidate *schedapi.CandidateDisk) *SStorage {
func (self *SGuest) ChooseHostStorage(host *SHost, diskConfig *api.DiskConfig, candidate *schedapi.CandidateDisk) (*SStorage, error) {
if candidate == nil || len(candidate.StorageIds) == 0 {
return self.GetDriver().ChooseHostStorage(host, backend, nil)
return self.GetDriver().ChooseHostStorage(host, diskConfig, nil)
}
return self.GetDriver().ChooseHostStorage(host, backend, candidate.StorageIds)
return self.GetDriver().ChooseHostStorage(host, diskConfig, candidate.StorageIds)
}
func (self *SGuest) createDiskOnHost(
@@ -3445,7 +3445,10 @@ func (self *SGuest) createDiskOnHost(
backupCandidate *schedapi.CandidateDisk,
autoAttach bool,
) (*SDisk, error) {
var storage *SStorage
var (
storage *SStorage
err error
)
if len(diskConfig.Storage) > 0 {
_storage, err := StorageManager.FetchByIdOrName(userCred, diskConfig.Storage)
if err != nil {
@@ -3456,7 +3459,10 @@ func (self *SGuest) createDiskOnHost(
}
storage = _storage.(*SStorage)
} else {
storage = self.ChooseHostStorage(host, diskConfig.Backend, candidate)
storage, err = self.ChooseHostStorage(host, diskConfig, candidate)
if err != nil {
return nil, errors.Wrap(err, "ChooseHostStorage")
}
}
if storage == nil {
return nil, fmt.Errorf("No storage on %s to create disk for %s", host.GetName(), diskConfig.Backend)
@@ -3468,7 +3474,10 @@ func (self *SGuest) createDiskOnHost(
}
if len(self.BackupHostId) > 0 {
backupHost := HostManager.FetchHostById(self.BackupHostId)
backupStorage := self.ChooseHostStorage(backupHost, diskConfig.Backend, backupCandidate)
backupStorage, err := self.ChooseHostStorage(backupHost, diskConfig, backupCandidate)
if err != nil {
return nil, errors.Wrap(err, "ChooseHostStorage")
}
diff, err := db.Update(disk, func() error {
disk.BackupStorageId = backupStorage.Id
return nil
+4 -1
View File
@@ -100,7 +100,10 @@ func ValidateScheduleCreateData(ctx context.Context, userCred mcclient.TokenCred
return nil, err
}
defaultStorage := GetDriver(hypervisor).ChooseHostStorage(baremetal, "", nil)
defaultStorage, err := GetDriver(hypervisor).ChooseHostStorage(baremetal, &api.DiskConfig{}, nil)
if err != nil {
return nil, errors.Wrap(err, "ChooseHostStorage")
}
if defaultStorage == nil {
return nil, httperrors.NewInsufficientResourceError("no valid storage on host")
}
+2
View File
@@ -146,6 +146,8 @@ type ComputeOptions struct {
SyncStorageCapacityUsedIntervalMinutes int `help:"interval sync storage capacity used" default:"10"`
LockStorageFromCachedimage bool `help:"must use storage in where selected cachedimage when creating vm"`
SCapabilityOptions
SASControllerOptions
common_options.CommonOptions
+6 -1
View File
@@ -328,7 +328,12 @@ func (self *GuestCreateBackupTask) StartCreateBackupDisks(ctx context.Context, g
if len(candidateDisks) >= i {
candidateDisk = candidateDisks[i]
}
storage := guest.ChooseHostStorage(host, api.STORAGE_LOCAL, candidateDisk)
diskConfig := &api.DiskConfig{Backend: api.STORAGE_LOCAL}
storage, err := guest.ChooseHostStorage(host, diskConfig, candidateDisk)
if err != nil {
self.TaskFailed(ctx, guest, jsonutils.NewString(fmt.Sprintf("unable to ChooseHostStorage: %v", err)))
return
}
if storage == nil {
self.TaskFailed(ctx, guest, jsonutils.NewString("Get backup storage error"))
return