mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
feat: support lock storage from selected cachedimage
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user