Automatic merge from release/2.7.0 -> release/2.8.0

* commit '3f1dfac8f16f0e40f68277a7fda345113b4f1064':
  fix: more accurate sync_status update time
  fix: cloud provider sync time is not set in auto-sync cycles
This commit is contained in:
邱剑
2019-03-19 08:20:56 +08:00
6 changed files with 117 additions and 46 deletions
+28 -4
View File
@@ -429,7 +429,24 @@ func (self *SCloudaccount) MarkSyncing(userCred mcclient.TokenCredential) error
return nil
}
func (self *SCloudaccount) MarkEndSync(userCred mcclient.TokenCredential) error {
func (self *SCloudaccount) MarkEndSyncWithLock(ctx context.Context, userCred mcclient.TokenCredential) error {
lockman.LockObject(ctx, self)
defer lockman.ReleaseObject(ctx, self)
if self.SyncStatus == CLOUD_PROVIDER_SYNC_STATUS_IDLE {
return nil
}
providers := self.GetCloudproviders()
for i := range providers {
if providers[i].SyncStatus != CLOUD_PROVIDER_SYNC_STATUS_IDLE {
return nil
}
}
return self.markEndSync(userCred)
}
func (self *SCloudaccount) markEndSync(userCred mcclient.TokenCredential) error {
_, err := db.Update(self, func() error {
self.SyncStatus = CLOUD_PROVIDER_SYNC_STATUS_IDLE
self.LastSyncEndAt = timeutils.UtcNow()
@@ -1125,8 +1142,8 @@ func (account *SCloudaccount) syncAccountStatus(ctx context.Context, userCred mc
account.MarkSyncing(userCred)
subaccounts, err := account.probeAccountStatus(ctx, userCred)
if err != nil {
account.markAccountDiscconected(ctx, userCred)
account.markAllProvidersDicconnected(ctx, userCred)
account.markAccountDiscconected(ctx, userCred)
return err
}
account.markAccountConnected(ctx, userCred)
@@ -1146,16 +1163,23 @@ func (account *SCloudaccount) SubmitSyncAccountTask(ctx context.Context, userCre
log.Debugf("syncAccountStatus %s %s", account.Id, account.Name)
err := account.syncAccountStatus(ctx, userCred)
if waitChan != nil {
if err != nil {
account.markEndSync(userCred)
}
waitChan <- err
} else {
syncCnt := 0
if err == nil && autoSync && account.Enabled && account.EnableAutoSync {
syncRange := SSyncRange{FullSync: true}
providers := account.GetEnabledCloudproviders()
for i := range providers {
providers[i].syncCloudproviderRegions(userCred, &syncRange, nil)
providers[i].syncCloudproviderRegions(ctx, userCred, &syncRange, nil, autoSync)
syncCnt += 1
}
}
account.MarkEndSync(userCred)
if syncCnt == 0 {
account.markEndSync(userCred)
}
}
})
}
+27 -16
View File
@@ -199,7 +199,19 @@ func (self *SCloudproviderregion) markSyncing(userCred mcclient.TokenCredential)
return nil
}
func (self *SCloudproviderregion) markEndSync(userCred mcclient.TokenCredential, syncResults SSyncResultSet) error {
func (self *SCloudproviderregion) markEndSync(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet) error {
err := self.markEndSyncInternal(userCred, syncResults)
if err != nil {
return err
}
err = self.GetProvider().markEndSyncWithLock(ctx, userCred)
if err != nil {
return err
}
return nil
}
func (self *SCloudproviderregion) markEndSyncInternal(userCred mcclient.TokenCredential, syncResults SSyncResultSet) error {
_, err := db.Update(self, func() error {
self.SyncStatus = CLOUD_PROVIDER_SYNC_STATUS_IDLE
self.LastSyncEndAt = timeutils.UtcNow()
@@ -230,11 +242,10 @@ func (set SSyncResultSet) Add(manager db.IModelManager, result compare.SyncResul
}
func (self *SCloudproviderregion) DoSync(ctx context.Context, userCred mcclient.TokenCredential, syncRange *SSyncRange) error {
err := self.markSyncing(userCred)
if err != nil {
log.Errorf("start sync sql fail?? %s", err)
return err
}
syncResults := SSyncResultSet{}
self.markSyncing(userCred)
defer self.markEndSync(ctx, userCred, syncResults)
localRegion := self.GetRegion()
provider := self.GetProvider()
@@ -244,8 +255,6 @@ func (self *SCloudproviderregion) DoSync(ctx context.Context, userCred mcclient.
return err
}
syncResults := SSyncResultSet{}
if localRegion.isManaged() {
remoteRegion, err := driver.GetIRegionById(localRegion.ExternalId)
if err == nil {
@@ -255,14 +264,13 @@ func (self *SCloudproviderregion) DoSync(ctx context.Context, userCred mcclient.
err = syncOnPremiseCloudProviderInfo(ctx, userCred, syncResults, provider, driver, syncRange)
}
if err != nil {
log.Errorf("dosync fail %s", err)
}
log.Debugf("%s", jsonutils.Marshal(syncResults))
err = self.markEndSync(userCred, syncResults)
if err != nil {
log.Errorf("mark end sync failed...")
return err
}
return nil
return err
}
func (self *SCloudproviderregion) getSyncTaskKey() string {
@@ -284,7 +292,7 @@ func (self *SCloudproviderregion) submitSyncTask(userCred mcclient.TokenCredenti
})
}
func (cpr *SCloudproviderregion) needSync() bool {
func (cpr *SCloudproviderregion) needAutoSync() bool {
if cpr.LastSyncEndAt.IsZero() {
return true
}
@@ -297,7 +305,10 @@ func (cpr *SCloudproviderregion) needSync() bool {
isEmpty = cpr.isEmptyPublicCloud()
}
if isEmpty {
intval = intval * 16 // no need to check empty region
intval = intval * 16 // no need to check empty region
if intval > 24*3600 { // at least once everyday
intval = 24 * 3600
}
region := cpr.GetRegion()
log.Debugf("empty region %s! no need to check so frequently", region.GetName())
}
+44 -10
View File
@@ -15,6 +15,7 @@ import (
"yunion.io/x/sqlchemy"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/options"
@@ -525,7 +526,7 @@ func (self *SCloudprovider) markStartSync(userCred mcclient.TokenCredential) err
return nil
}
func (self *SCloudprovider) MarkSyncing(userCred mcclient.TokenCredential) error {
func (self *SCloudprovider) markSyncing(userCred mcclient.TokenCredential) error {
_, err := db.Update(self, func() error {
self.SyncStatus = CLOUD_PROVIDER_SYNC_STATUS_SYNCING
self.LastSync = timeutils.UtcNow()
@@ -539,7 +540,34 @@ func (self *SCloudprovider) MarkSyncing(userCred mcclient.TokenCredential) error
return nil
}
func (self *SCloudprovider) MarkEndSync(userCred mcclient.TokenCredential) error {
func (self *SCloudprovider) markEndSyncWithLock(ctx context.Context, userCred mcclient.TokenCredential) error {
err := func() error {
lockman.LockObject(ctx, self)
defer lockman.ReleaseObject(ctx, self)
cprs := self.GetCloudproviderRegions()
for i := range cprs {
if cprs[i].SyncStatus != CLOUD_PROVIDER_SYNC_STATUS_IDLE {
return nil
}
}
err := self.markEndSync(userCred)
if err != nil {
return err
}
return nil
}()
if err != nil {
return err
}
account := self.GetCloudaccount()
return account.MarkEndSyncWithLock(ctx, userCred)
}
func (self *SCloudprovider) markEndSync(userCred mcclient.TokenCredential) error {
_, err := db.Update(self, func() error {
self.SyncStatus = CLOUD_PROVIDER_SYNC_STATUS_IDLE
self.LastSyncEndAt = timeutils.UtcNow()
@@ -857,19 +885,22 @@ func (provider *SCloudprovider) prepareCloudproviderRegions(ctx context.Context,
return cprs, nil
}
func (provider *SCloudprovider) GetEnabledCloudproviderRegions() []SCloudproviderregion {
func (provider *SCloudprovider) GetCloudproviderRegions() []SCloudproviderregion {
q := CloudproviderRegionManager.Query()
q = q.IsTrue("enabled")
q = q.Equals("cloudprovider_id", provider.Id)
q = q.Equals("sync_status", CLOUD_PROVIDER_SYNC_STATUS_IDLE)
// q = q.IsTrue("enabled")
// q = q.Equals("sync_status", CLOUD_PROVIDER_SYNC_STATUS_IDLE)
return CloudproviderRegionManager.fetchRecordsByQuery(q)
}
func (provider *SCloudprovider) syncCloudproviderRegions(userCred mcclient.TokenCredential, syncRange *SSyncRange, wg *sync.WaitGroup) {
cprs := provider.GetEnabledCloudproviderRegions()
func (provider *SCloudprovider) syncCloudproviderRegions(ctx context.Context, userCred mcclient.TokenCredential, syncRange *SSyncRange, wg *sync.WaitGroup, autoSync bool) {
provider.markSyncing(userCred)
cprs := provider.GetCloudproviderRegions()
syncCnt := 0
for i := range cprs {
if cprs[i].needSync() {
if cprs[i].Enabled && cprs[i].CanSync() && (!autoSync || cprs[i].needAutoSync()) {
syncCnt += 1
var waitChan chan bool = nil
if wg != nil {
wg.Add(1)
@@ -882,11 +913,14 @@ func (provider *SCloudprovider) syncCloudproviderRegions(userCred mcclient.Token
}
}
}
if syncCnt == 0 {
provider.markEndSyncWithLock(ctx, userCred)
}
}
func (provider *SCloudprovider) SyncCallSyncCloudproviderRegions(userCred mcclient.TokenCredential, syncRange *SSyncRange) {
func (provider *SCloudprovider) SyncCallSyncCloudproviderRegions(ctx context.Context, userCred mcclient.TokenCredential, syncRange *SSyncRange) {
var wg sync.WaitGroup
provider.syncCloudproviderRegions(userCred, syncRange, &wg)
provider.syncCloudproviderRegions(ctx, userCred, syncRange, &wg, false)
wg.Wait()
}
+1 -1
View File
@@ -24,7 +24,7 @@ type SSyncableBaseResource struct {
func (self *SSyncableBaseResource) CanSync() bool {
if self.SyncStatus == CLOUD_PROVIDER_SYNC_STATUS_QUEUED || self.SyncStatus == CLOUD_PROVIDER_SYNC_STATUS_SYNCING {
if self.LastSync.IsZero() || time.Now().Sub(self.LastSync) > 900*time.Second {
if self.LastSync.IsZero() || time.Now().Sub(self.LastSync) > 1800*time.Second {
return true
} else {
return false
+11 -10
View File
@@ -29,7 +29,7 @@ func (self *CloudAccountSyncInfoTask) OnInit(ctx context.Context, obj db.IStanda
err := cloudaccount.SyncCallSyncAccountTask(ctx, self.UserCred)
if err != nil {
cloudaccount.MarkEndSync(self.UserCred)
cloudaccount.MarkEndSyncWithLock(ctx, self.UserCred)
db.OpsLog.LogEvent(cloudaccount, db.ACT_SYNC_HOST_FAILED, err, self.UserCred)
self.SetStageFailed(ctx, err.Error())
logclient.AddActionLogWithStartable(self, cloudaccount, logclient.ACT_CLOUD_SYNC, err, self.UserCred, false)
@@ -45,24 +45,25 @@ func (self *CloudAccountSyncInfoTask) OnInit(ctx context.Context, obj db.IStanda
}
if !syncRange.NeedSyncInfo() {
cloudaccount.MarkEndSync(self.UserCred)
db.OpsLog.LogEvent(cloudaccount, db.ACT_SYNC_HOST_COMPLETE, "", self.UserCred)
self.SetStageComplete(ctx, nil)
logclient.AddActionLogWithStartable(self, cloudaccount, logclient.ACT_CLOUD_SYNC, "", self.UserCred, true)
self.OnCloudaccountSyncComplete(ctx, obj, nil)
return
}
self.SetStage("on_cloudaccount_sync_complete", nil)
cloudproviders := cloudaccount.GetEnabledCloudproviders()
for i := range cloudproviders {
cloudproviders[i].StartSyncCloudProviderInfoTask(ctx, self.UserCred, &syncRange, self.GetId())
if len(cloudproviders) > 0 {
self.SetStage("on_cloudaccount_sync_complete", nil)
for i := range cloudproviders {
cloudproviders[i].StartSyncCloudProviderInfoTask(ctx, self.UserCred, &syncRange, self.GetId())
}
} else {
self.OnCloudaccountSyncComplete(ctx, obj, nil)
}
}
func (self *CloudAccountSyncInfoTask) OnCloudaccountSyncComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
cloudaccount := obj.(*models.SCloudaccount)
cloudaccount.MarkEndSync(self.UserCred)
cloudaccount.MarkEndSyncWithLock(ctx, self.UserCred)
db.OpsLog.LogEvent(cloudaccount, db.ACT_SYNC_HOST_COMPLETE, "", self.UserCred)
self.SetStageComplete(ctx, nil)
logclient.AddActionLogWithStartable(self, cloudaccount, logclient.ACT_CLOUD_SYNC, "", self.UserCred, true)
@@ -50,8 +50,6 @@ func (self *CloudProviderSyncInfoTask) OnInit(ctx context.Context, obj db.IStand
db.OpsLog.LogEvent(provider, db.ACT_SYNCING_HOST, "", self.UserCred)
provider.MarkSyncing(self.UserCred)
syncRange := models.SSyncRange{}
syncRangeJson, _ := self.Params.Get("sync_range")
if syncRangeJson != nil {
@@ -59,14 +57,17 @@ func (self *CloudProviderSyncInfoTask) OnInit(ctx context.Context, obj db.IStand
}
syncRange.Normalize()
provider.SyncCallSyncCloudproviderRegions(self.UserCred, &syncRange)
self.SetStage("OnSyncCloudProviderInfoComplete", nil)
self.OnSyncCloudProviderInfoComplete(ctx, provider, nil)
taskman.LocalTaskRun(self, func() (jsonutils.JSONObject, error) {
provider.SyncCallSyncCloudproviderRegions(ctx, self.UserCred, &syncRange)
return nil, nil
})
}
func (self *CloudProviderSyncInfoTask) OnSyncCloudProviderInfoComplete(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
provider := obj.(*models.SCloudprovider)
provider.MarkEndSync(self.UserCred)
// provider.MarkEndSync(self.UserCred)
provider.CleanSchedCache()
self.SetStageComplete(ctx, nil)
db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_COMPLETE, "", self.UserCred)