diff --git a/pkg/compute/guestdrivers/managedvirtual.go b/pkg/compute/guestdrivers/managedvirtual.go index ca0ed59513..80549f000c 100644 --- a/pkg/compute/guestdrivers/managedvirtual.go +++ b/pkg/compute/guestdrivers/managedvirtual.go @@ -620,6 +620,11 @@ func (self *SManagedVirtualizedGuestDriver) RequestSyncstatusOnHost(ctx context. return nil, err } + err = guest.SyncAllWithCloudVM(ctx, userCred, host, ivm) + if err != nil { + return nil, err + } + status := ivm.GetStatus() switch status { case api.VM_RUNNING: diff --git a/pkg/compute/models/cloudsync.go b/pkg/compute/models/cloudsync.go index 2918265217..1c40fad22f 100644 --- a/pkg/compute/models/cloudsync.go +++ b/pkg/compute/models/cloudsync.go @@ -20,6 +20,7 @@ import ( "time" "yunion.io/x/log" + "yunion.io/x/pkg/errors" "yunion.io/x/pkg/util/compare" "yunion.io/x/pkg/utils" "yunion.io/x/sqlchemy" @@ -595,82 +596,107 @@ func syncHostVMs(ctx context.Context, userCred mcclient.TokenCredential, syncRes lockman.LockObject(ctx, syncVMPairs[i].Local) defer lockman.ReleaseObject(ctx, syncVMPairs[i].Local) - syncMetadata(ctx, userCred, syncVMPairs[i].Local, syncVMPairs[i].Remote) - syncVMNics(ctx, userCred, provider, localHost, syncVMPairs[i].Local, syncVMPairs[i].Remote) - syncVMDisks(ctx, userCred, provider, driver, localHost, syncVMPairs[i].Local, syncVMPairs[i].Remote, syncRange) - syncVMEip(ctx, userCred, provider, syncVMPairs[i].Local, syncVMPairs[i].Remote) - syncVMSecgroups(ctx, userCred, provider, syncVMPairs[i].Local, syncVMPairs[i].Remote) + syncVMPeripherals(ctx, userCred, syncVMPairs[i].Local, syncVMPairs[i].Remote, localHost, provider, driver) + // syncMetadata(ctx, userCred, syncVMPairs[i].Local, syncVMPairs[i].Remote) + // syncVMNics(ctx, userCred, provider, localHost, syncVMPairs[i].Local, syncVMPairs[i].Remote) + // syncVMDisks(ctx, userCred, provider, driver, localHost, syncVMPairs[i].Local, syncVMPairs[i].Remote, syncRange) + // syncVMEip(ctx, userCred, provider, syncVMPairs[i].Local, syncVMPairs[i].Remote) + // syncVMSecgroups(ctx, userCred, provider, syncVMPairs[i].Local, syncVMPairs[i].Remote) }() } } -func syncVMNics(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, host *SHost, localVM *SGuest, remoteVM cloudprovider.ICloudVM) { +func syncVMPeripherals(ctx context.Context, userCred mcclient.TokenCredential, local *SGuest, remote cloudprovider.ICloudVM, host *SHost, provider *SCloudprovider, driver cloudprovider.ICloudProvider) { + syncMetadata(ctx, userCred, local, remote) + err := syncVMNics(ctx, userCred, provider, host, local, remote) + if err != nil { + log.Errorf("syncVMNics error %s", err) + } + err = syncVMDisks(ctx, userCred, provider, driver, host, local, remote) + if err != nil { + log.Errorf("syncVMDisks error %s", err) + } + err = syncVMEip(ctx, userCred, provider, local, remote) + if err != nil { + log.Errorf("syncVMEip error %s", err) + } + err = syncVMSecgroups(ctx, userCred, provider, local, remote) + if err != nil { + log.Errorf("syncVMSecgroups error %s", err) + } +} + +func syncVMNics(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, host *SHost, localVM *SGuest, remoteVM cloudprovider.ICloudVM) error { nics, err := remoteVM.GetINics() if err != nil { - msg := fmt.Sprintf("GetINics for VM %s failed %s", remoteVM.GetName(), err) - log.Errorf(msg) - return + // msg := fmt.Sprintf("GetINics for VM %s failed %s", remoteVM.GetName(), err) + // log.Errorf(msg) + return errors.Wrap(err, "remoteVM.GetINics") } result := localVM.SyncVMNics(ctx, userCred, host, nics, nil) msg := result.Result() notes := fmt.Sprintf("syncVMNics for VM %s result: %s", localVM.Name, msg) log.Infof(notes) if result.IsError() { - return + return result.AllError() } - db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_COMPLETE, msg, userCred) + // db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_COMPLETE, msg, userCred) // logclient.AddActionLog(provider, getAction(task.Params), notes, task.UserCred, true) + return nil } -func syncVMDisks(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, driver cloudprovider.ICloudProvider, host *SHost, localVM *SGuest, remoteVM cloudprovider.ICloudVM, syncRange *SSyncRange) { +func syncVMDisks(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, driver cloudprovider.ICloudProvider, host *SHost, localVM *SGuest, remoteVM cloudprovider.ICloudVM) error { disks, err := remoteVM.GetIDisks() if err != nil { - msg := fmt.Sprintf("GetIDisks for VM %s failed %s", remoteVM.GetName(), err) - log.Errorf(msg) - return + // msg := fmt.Sprintf("GetIDisks for VM %s failed %s", remoteVM.GetName(), err) + // log.Errorf(msg) + return errors.Wrap(err, "remoteVM.GetIDisks") } result := localVM.SyncVMDisks(ctx, userCred, driver, host, disks, provider.GetOwnerId()) msg := result.Result() notes := fmt.Sprintf("syncVMDisks for VM %s result: %s", localVM.Name, msg) log.Infof(notes) if result.IsError() { - return + return result.AllError() } - db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_COMPLETE, msg, userCred) + // db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_COMPLETE, msg, userCred) // logclient.AddActionLog(provider, getAction(task.Params), notes, task.UserCred, true) + return nil } -func syncVMEip(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, localVM *SGuest, remoteVM cloudprovider.ICloudVM) { +func syncVMEip(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, localVM *SGuest, remoteVM cloudprovider.ICloudVM) error { eip, err := remoteVM.GetIEIP() if err != nil { - msg := fmt.Sprintf("GetIEIP for VM %s failed %s", remoteVM.GetName(), err) - log.Errorf(msg) - return + // msg := fmt.Sprintf("GetIEIP for VM %s failed %s", remoteVM.GetName(), err) + // log.Errorf(msg) + return errors.Wrap(err, "remoteVM.GetIEIP") } result := localVM.SyncVMEip(ctx, userCred, provider, eip, provider.GetOwnerId()) msg := result.Result() log.Infof("syncVMEip for VM %s result: %s", localVM.Name, msg) if result.IsError() { - return + return result.AllError() } - db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_COMPLETE, msg, userCred) + // db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_COMPLETE, msg, userCred) + return nil } -func syncVMSecgroups(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, localVM *SGuest, remoteVM cloudprovider.ICloudVM) { +func syncVMSecgroups(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, localVM *SGuest, remoteVM cloudprovider.ICloudVM) error { secgroupIds, err := remoteVM.GetSecurityGroupIds() if err != nil { - msg := fmt.Sprintf("GetSecurityGroupIds for VM %s failed %s", remoteVM.GetName(), err) - log.Errorf(msg) - return + // msg := fmt.Sprintf("GetSecurityGroupIds for VM %s failed %s", remoteVM.GetName(), err) + // log.Errorf(msg) + return errors.Wrap(err, "remoteVM.GetSecurityGroupIds") } result := localVM.SyncVMSecgroups(ctx, userCred, provider, secgroupIds) msg := result.Result() log.Infof("SyncVMSecgroups for VM %s result: %s", localVM.Name, msg) if result.IsError() { - return + return result.AllError() } - db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_COMPLETE, msg, userCred) + // db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_COMPLETE, msg, userCred) + return nil } func syncZoneSkusFromCloud(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, provider *SCloudprovider, localZone *SZone, remoteRegion cloudprovider.ICloudRegion, remoteZone cloudprovider.ICloudZone) { diff --git a/pkg/compute/models/elasticips.go b/pkg/compute/models/elasticips.go index f3e97b784f..daf9053e7d 100644 --- a/pkg/compute/models/elasticips.go +++ b/pkg/compute/models/elasticips.go @@ -96,19 +96,6 @@ func (manager *SElasticipManager) ListItemFilter(ctx context.Context, q *sqlchem return nil, err } - /*managerFilter, _ := query.GetString("manager") - if len(managerFilter) > 0 { - managerI, err := CloudproviderManager.FetchByIdOrName(userCred, managerFilter) - if err != nil { - if err == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError("cloud provider %s not found", managerFilter) - } else { - return nil, httperrors.NewGeneralError(err) - } - } - q = q.Equals("manager_id", managerI.GetId()) - }*/ - regionFilter, _ := query.GetString("region") if len(regionFilter) > 0 { regionObj, err := CloudregionManager.FetchByIdOrName(userCred, regionFilter) @@ -154,25 +141,6 @@ func (manager *SElasticipManager) ListItemFilter(ctx context.Context, q *sqlchem } } - /*accountStr := jsonutils.GetAnyString(query, []string{"account", "account_id", "cloudaccount", "cloudaccount_id"}) - if len(accountStr) > 0 { - account, err := CloudaccountManager.FetchByIdOrName(nil, accountStr) - if err != nil { - if err == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError2(CloudaccountManager.Keyword(), accountStr) - } - return nil, httperrors.NewGeneralError(err) - } - subq := CloudproviderManager.Query("id").Equals("cloudaccount_id", account.GetId()).SubQuery() - q = q.Filter(sqlchemy.In(q.Field("manager_id"), subq)) - } - - providerStr := jsonutils.GetAnyString(query, []string{"provider"}) - if len(providerStr) > 0 { - subq := CloudproviderManager.Query("id").Equals("provider", providerStr).SubQuery() - q = q.Filter(sqlchemy.In(q.Field("manager_id"), subq)) - }*/ - if query.Contains("usable") { usable := jsonutils.QueryBoolean(query, "usable", false) if usable { @@ -618,7 +586,7 @@ func (self *SElasticip) Dissociate(ctx context.Context, userCred mcclient.TokenC } if self.Mode == api.EIP_MODE_INSTANCE_PUBLICIP { - self.Delete(ctx, userCred) + self.RealDelete(ctx, userCred) } return nil } diff --git a/pkg/compute/models/guests.go b/pkg/compute/models/guests.go index 5bc035f464..c3f1e35bbb 100644 --- a/pkg/compute/models/guests.go +++ b/pkg/compute/models/guests.go @@ -1970,6 +1970,31 @@ func (self *SGuest) syncRemoveCloudVM(ctx context.Context, userCred mcclient.Tok return nil } +func (guest *SGuest) SyncAllWithCloudVM(ctx context.Context, userCred mcclient.TokenCredential, host *SHost, extVM cloudprovider.ICloudVM) error { + if host == nil { + return errors.Error("guest has no host") + } + + provider := host.GetCloudprovider() + if provider == nil { + return errors.Error("host has no provider") + } + + driver, err := provider.GetProvider() + if err != nil { + return errors.Wrap(err, "provider.GetProvider") + } + + err = guest.syncWithCloudVM(ctx, userCred, driver, host, extVM, provider.GetOwnerId()) + if err != nil { + return errors.Wrap(err, "guest.syncWithCloudVM") + } + + syncVMPeripherals(ctx, userCred, guest, extVM, host, provider, driver) + + return nil +} + func (self *SGuest) syncWithCloudVM(ctx context.Context, userCred mcclient.TokenCredential, provider cloudprovider.ICloudProvider, host *SHost, extVM cloudprovider.ICloudVM, syncOwnerId mcclient.IIdentityProvider) error { recycle := false diff --git a/pkg/compute/tasks/guest_stop_task.go b/pkg/compute/tasks/guest_stop_task.go index 7d641a557c..f88e31bf77 100644 --- a/pkg/compute/tasks/guest_stop_task.go +++ b/pkg/compute/tasks/guest_stop_task.go @@ -79,7 +79,8 @@ func (self *GuestStopTask) OnMasterStopTaskCompleteFailed(ctx context.Context, o func (self *GuestStopTask) OnGuestStopTaskComplete(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) { if !self.IsSubtask() { - guest.SetStatus(self.UserCred, api.VM_READY, "") + guest.StartSyncstatus(ctx, self.UserCred, "") + // guest.SetStatus(self.UserCred, api.VM_READY, "") } db.OpsLog.LogEvent(guest, db.ACT_STOP, guest.GetShortDesc(ctx), self.UserCred) models.HostManager.ClearSchedDescCache(guest.HostId) diff --git a/pkg/mcclient/modules/mod_elasticips.go b/pkg/mcclient/modules/mod_elasticips.go index c00cca57b0..79814b10e0 100644 --- a/pkg/mcclient/modules/mod_elasticips.go +++ b/pkg/mcclient/modules/mod_elasticips.go @@ -20,7 +20,7 @@ var ( func init() { Elasticips = NewComputeManager("eip", "eips", - []string{"ID", "Name", "IP_Addr", "Status", + []string{"ID", "Name", "Mode", "IP_Addr", "Status", "Associate_Type", "Associate_ID", "Associate_Name", "Bandwidth", "Charge_Type", diff --git a/pkg/multicloud/aws/instance.go b/pkg/multicloud/aws/instance.go index 9adcaa6944..260ea0fe26 100644 --- a/pkg/multicloud/aws/instance.go +++ b/pkg/multicloud/aws/instance.go @@ -300,6 +300,7 @@ func (self *SInstance) GetIEIP() (cloudprovider.ICloudEIP, error) { eip.InstanceId = self.InstanceId eip.AllocationId = self.InstanceId // fixed. AllocationId等于InstanceId即表示为 仿真EIP。 eip.Bandwidth = 10000 + eip.Status = EIP_STATUS_INUSE return &eip, nil } else { return nil, nil diff --git a/pkg/multicloud/aws/region.go b/pkg/multicloud/aws/region.go index a238f63e02..240b3caa65 100644 --- a/pkg/multicloud/aws/region.go +++ b/pkg/multicloud/aws/region.go @@ -912,7 +912,10 @@ func (region *SRegion) DeleteIBucket(name string) error { input.Bucket = &name _, err = s3cli.DeleteBucket(input) if err != nil { - if strings.Index(err.Error(), "NoSuchBucket") >= 0 { + if region.client.debug { + log.Debugf("%#v %s", err, err) + } + if strings.Index(err.Error(), "NoSuchBucket:") >= 0 { return nil } return errors.Wrap(err, "DeleteBucket") @@ -930,6 +933,12 @@ func (region *SRegion) IBucketExist(name string) (bool, error) { input.Bucket = &name _, err = s3cli.HeadBucket(input) if err != nil { + if region.client.debug { + log.Debugf("%#v %s", err, err) + } + if strings.Index(err.Error(), "NotFound:") >= 0 { + return false, nil + } return false, errors.Wrap(err, "IsBucketExist") } return true, nil diff --git a/pkg/multicloud/objectstore/shell.go b/pkg/multicloud/objectstore/shell.go index 560feb0d0e..643a6d11c8 100644 --- a/pkg/multicloud/objectstore/shell.go +++ b/pkg/multicloud/objectstore/shell.go @@ -79,6 +79,18 @@ func S3Shell() { return nil }) + type BucketExistOptions struct { + NAME string `help:"name of bucket to delete"` + } + shellutils.R(&BucketExistOptions{}, "bucket-exist", "Test existence of a bucket", func(cli cloudprovider.ICloudRegion, args *BucketExistOptions) error { + exist, err := cli.IBucketExist(args.NAME) + if err != nil { + return err + } + fmt.Printf("Exist: %v\n", exist) + return nil + }) + type BucketObjectsOptions struct { BUCKET string `help:"name of bucket to list objects"` Prefix string `help:"prefix"`