diff --git a/pkg/compute/guestdrivers/esxi.go b/pkg/compute/guestdrivers/esxi.go index 51008d9ede..58bccfe669 100644 --- a/pkg/compute/guestdrivers/esxi.go +++ b/pkg/compute/guestdrivers/esxi.go @@ -166,12 +166,15 @@ func (self *SESXiGuestDriver) ChooseHostStorage(host *models.SHost, guest *model if err != nil { return nil, errors.Wrapf(err, "unable to fetch Guest of InstanceSnapshot %q", ispId) } - storages := ispGuest.GetStorages() + storages, err := ispGuest.GetStorages() + if err != nil { + return nil, errors.Wrapf(err, "GetStorages") + } if len(storages) == 0 { return self.SVirtualizedGuestDriver.ChooseHostStorage(host, guest, diskConfig, storageIds) } if utils.IsInStringArray(storages[0].GetId(), storageIds) { - return storages[0], nil + return &storages[0], nil } return self.SVirtualizedGuestDriver.ChooseHostStorage(host, guest, diskConfig, storageIds) } @@ -211,8 +214,31 @@ func (self *SESXiGuestDriver) GetChangeConfigStatus(guest *models.SGuest) ([]str } func (self *SESXiGuestDriver) ValidateChangeConfig(ctx context.Context, userCred mcclient.TokenCredential, guest *models.SGuest, cpuChanged bool, memChanged bool, newDisks []*api.DiskConfig) error { + defaultStorageId := "" + if root, _ := guest.GetSystemDisk(); root != nil { + defaultStorageId = root.StorageId + } + storages, err := guest.GetStorages() + if err != nil { + return errors.Wrapf(err, "GetStorages") + } + storageMap := map[string]string{} + for _, storage := range storages { + storageMap[storage.StorageType] = storage.Id + if len(defaultStorageId) == 0 { + defaultStorageId = storage.Id + } + } for i := range newDisks { newDisks[i].Format = "vmdk" + if len(newDisks[i].Storage) == 0 { + // 若不指定存储类型,默认和系统盘一致 + if len(newDisks[i].Backend) == 0 { + newDisks[i].Storage = defaultStorageId + } else if storageId, ok := storageMap[newDisks[i].Backend]; ok { // 否则和已有磁盘存储保持一致 + newDisks[i].Storage = storageId + } + } } return nil } diff --git a/pkg/compute/models/guest_actions.go b/pkg/compute/models/guest_actions.go index c5427ebecd..f5a6250eef 100644 --- a/pkg/compute/models/guest_actions.go +++ b/pkg/compute/models/guest_actions.go @@ -4023,51 +4023,18 @@ func (self *SGuest) PerformRenew(ctx context.Context, userCred mcclient.TokenCre return nil, nil } -func (self *SGuest) GetStorages() []*SStorage { - disks, _ := self.GetDisks() - storageMap := make(map[string]*SStorage) - for i := range disks { - storage, _ := disks[i].GetStorage() - if _, ok := storageMap[storage.GetId()]; !ok { - storageMap[storage.GetId()] = storage - } +func (self *SGuest) GetStorages() ([]SStorage, error) { + q := StorageManager.Query().Distinct() + disks := DiskManager.Query().SubQuery() + guestdisks := GuestdiskManager.Query().Equals("guest_id", self.Id).SubQuery() + q = q.Join(disks, sqlchemy.Equals(disks.Field("storage_id"), q.Field("id"))) + q = q.Join(guestdisks, sqlchemy.Equals(guestdisks.Field("disk_id"), disks.Field("id"))) + ret := []SStorage{} + err := db.FetchModelObjects(StorageManager, q, &ret) + if err != nil { + return nil, err } - ret := make([]*SStorage, 0, len(storageMap)) - for _, s := range storageMap { - ret = append(ret, s) - } - return ret -} - -func (self *SGuest) SyncCapacityUsedForStorage(ctx context.Context, storageIds []string) error { - if self.Hypervisor != api.HYPERVISOR_ESXI { - return nil - } - var storages []*SStorage - if len(storageIds) == 0 { - storages = self.GetStorages() - } else { - q := StorageManager.Query() - if len(storageIds) == 1 { - q = q.Equals("id", storageIds[0]) - } else { - q = q.In("id", storageIds[0]) - } - ss := make([]SStorage, 0, len(storageIds)) - err := db.FetchModelObjects(StorageManager, q, &ss) - if err != nil { - return errors.Wrap(err, "FetchModelObjects") - } - storages = make([]*SStorage, len(ss)) - for i := range ss { - storages[i] = &ss[i] - } - } - for _, s := range storages { - err := s.SyncCapacityUsed(ctx) - return errors.Wrapf(err, "unable to SyncCapacityUsed for storage %q", s.GetId()) - } - return nil + return ret, nil } func (self *SGuest) startGuestRenewTask(ctx context.Context, userCred mcclient.TokenCredential, duration string, parentTaskId string) error { diff --git a/pkg/compute/models/storages.go b/pkg/compute/models/storages.go index b95cd19cb3..264c50e5d2 100644 --- a/pkg/compute/models/storages.go +++ b/pkg/compute/models/storages.go @@ -966,54 +966,6 @@ func (sm *SStorageManager) SyncCapacityUsedForEsxiStorage(ctx context.Context, u } } -func (sm *SStorageManager) SyncCapacityUsedForStorage(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) { - cpSubQ := CloudproviderManager.Query("id").In("provider", CapacityUsedCloudStorageProvider).SubQuery() - sQ := sm.Query() - sQ = sQ.Join(cpSubQ, sqlchemy.Equals(sQ.Field("manager_id"), cpSubQ.Field("id"))) - storages := make([]SStorage, 0, 5) - err := db.FetchModelObjects(sm, sQ, &storages) - if err != nil { - log.Errorf("unable to fetch storages with sql %q: %v", sQ.String(), err) - } - for i := range storages { - err := storages[i].SyncCapacityUsed(ctx) - if err != nil { - log.Errorf("unable to sync CapacityUsed for storage %q: %v", storages[i].Id, err) - } - } -} - -func (s *SStorage) SyncCapacityUsed(ctx context.Context) error { - cp := s.GetCloudprovider() - if cp == nil { - return errors.Wrapf(errors.ErrNotFound, "no cloudprovider for storage %s", s.Id) - } - if !utils.IsInStringArray(cp.Provider, CapacityUsedCloudStorageProvider) { - return nil - } - icp, err := cp.GetProvider(ctx) - if err != nil { - return errors.Wrap(err, "GetProvider") - } - iregion, err := icp.GetOnPremiseIRegion() - if err != nil { - return errors.Wrap(err, "GetOnPremiseIRegion") - } - cloudStorage, err := iregion.GetIStorageById(s.ExternalId) - if err != nil { - return errors.Wrap(err, "GetIStorageById") - } - capacityUsed := cloudStorage.GetCapacityUsedMB() - if s.ActualCapacityUsed == capacityUsed { - return nil - } - _, err = db.UpdateWithLock(ctx, s, func() error { - s.ActualCapacityUsed = capacityUsed - return nil - }) - return err -} - func (self *SStorage) syncWithCloudStorage(ctx context.Context, userCred mcclient.TokenCredential, extStorage cloudprovider.ICloudStorage, provider *SCloudprovider) error { diff, err := db.UpdateWithLock(ctx, self, func() error { // self.Name = extStorage.GetName() diff --git a/pkg/compute/tasks/guest_create_task.go b/pkg/compute/tasks/guest_create_task.go index 755d5453f2..cdd546f575 100644 --- a/pkg/compute/tasks/guest_create_task.go +++ b/pkg/compute/tasks/guest_create_task.go @@ -170,11 +170,6 @@ func (self *GuestCreateTask) StartDeployGuest(ctx context.Context, guest *models func (self *GuestCreateTask) OnDeployGuestDescComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { guest := obj.(*models.SGuest) - // sync capacityUsed for storage - // err := guest.SyncCapacityUsedForStorage(ctx, nil) - // if err != nil { - // log.Errorf("unable to SyncCapacityUsedForStorage: %v", err) - // } // bind eip { diff --git a/pkg/compute/tasks/guest_delete_task.go b/pkg/compute/tasks/guest_delete_task.go index 8a73cba5a3..765d269b0d 100644 --- a/pkg/compute/tasks/guest_delete_task.go +++ b/pkg/compute/tasks/guest_delete_task.go @@ -280,7 +280,7 @@ func (self *GuestDeleteTask) OnPendingDeleteCompleteFailed(ctx context.Context, func (self *GuestDeleteTask) StartDeleteGuest(ctx context.Context, guest *models.SGuest) { // Temporary storageids to sync capacityUsed after delete { - storages := guest.GetStorages() + storages, _ := guest.GetStorages() storageIds := make([]string, len(storages)) for i := range storages { storageIds[i] = storages[i].GetId() @@ -345,18 +345,6 @@ func (self *GuestDeleteTask) OnGuestDeleteComplete(ctx context.Context, obj db.I guest.EjectAllVfd(self.UserCred) guest.DeleteEip(ctx, self.UserCred) guest.GetDriver().OnDeleteGuestFinalCleanup(ctx, guest, self.UserCred) - // sync capacity used for storage - // ja, err := self.Params.GetArray(STORAGEIDS) - // if err == nil { - // storageIds := make([]string, len(ja)) - // for i := range ja { - // storageIds[i], _ = ja[i].GetString() - // } - // err = guest.SyncCapacityUsedForStorage(ctx, storageIds) - // if err != nil { - // log.Errorf("unable to SyncCapacityUsedForStoarage: %v", err) - // } - // } self.DeleteGuest(ctx, guest) }