From af8f9b06ef8238565b9a0503385fd8fcaf0a015f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=88=E8=BD=A9?= Date: Tue, 10 Mar 2026 15:06:36 +0800 Subject: [PATCH] fix(region): persistence server status change (#24407) --- pkg/apis/compute/serversku.go | 6 +++++ pkg/compute/models/server_skus.go | 42 +++++++++++++++++++++++-------- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/pkg/apis/compute/serversku.go b/pkg/apis/compute/serversku.go index 41adf2f20c..304c312c84 100644 --- a/pkg/apis/compute/serversku.go +++ b/pkg/apis/compute/serversku.go @@ -18,6 +18,12 @@ import ( "yunion.io/x/onecloud/pkg/apis" ) +const ( + SERVER_SKU_PROJECT_SRC_KEY = "project_src" + + SERVER_SKU_PROJECT_SRC_VALUE_LOCAL = "local" +) + type ServerSkuCreateInput struct { apis.EnabledStatusStandaloneResourceCreateInput diff --git a/pkg/compute/models/server_skus.go b/pkg/compute/models/server_skus.go index e0817a2b47..64eceb3859 100644 --- a/pkg/compute/models/server_skus.go +++ b/pkg/compute/models/server_skus.go @@ -80,7 +80,6 @@ type SServerSku struct { SCloudregionResourceBase SZoneResourceBase - // SkuId string `width:"64" charset:"ascii" nullable:"false" list:"user" create:"admin_required"` // x2.large InstanceTypeFamily string `width:"32" charset:"ascii" nullable:"true" list:"user" create:"admin_optional" update:"admin"` // x2 InstanceTypeCategory string `width:"32" charset:"utf8" nullable:"true" list:"user" create:"admin_optional" update:"admin"` // 通用型 LocalCategory string `width:"32" charset:"utf8" nullable:"true" list:"user" create:"admin_optional" update:"admin" default:""` // 记录本地分类 @@ -574,6 +573,9 @@ func (self *SServerSku) ValidateUpdateData(ctx context.Context, userCred mcclien func (self *SServerSku) PostUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) { ServerSkuManager.ClearSchedDescCache(true) + if utils.IsInStringArray(self.Provider, api.PUBLIC_CLOUD_PROVIDERS) && (data.Contains("prepaid_status") || data.Contains("postpaid_status")) { + self.SetMetadata(ctx, api.SERVER_SKU_PROJECT_SRC_KEY, api.SERVER_SKU_PROJECT_SRC_VALUE_LOCAL, userCred) + } self.SEnabledStatusStandaloneResourceBase.PostUpdate(ctx, userCred, query, data) } @@ -1175,7 +1177,7 @@ func (manager *SServerSkuManager) newPrivateCloudSku(ctx context.Context, userCr return manager.TableSpec().Insert(ctx, sku) } -func (self *SServerSku) syncWithCloudSku(ctx context.Context, userCred mcclient.TokenCredential, region *SCloudregion, extSku SServerSku) error { +func (self *SServerSku) syncWithCloudSku(ctx context.Context, region *SCloudregion, isLocalChangedStatus bool, extSku SServerSku) error { if self.Md5 == extSku.Md5 { return nil } @@ -1193,8 +1195,10 @@ func (self *SServerSku) syncWithCloudSku(ctx context.Context, userCred mcclient. } _, err = db.Update(self, func() error { - self.PrepaidStatus = sku.PrepaidStatus - self.PostpaidStatus = sku.PostpaidStatus + if !isLocalChangedStatus { + self.PrepaidStatus = sku.PrepaidStatus + self.PostpaidStatus = sku.PostpaidStatus + } self.SysDiskType = sku.SysDiskType self.DataDiskTypes = sku.DataDiskTypes self.CpuArch = sku.CpuArch @@ -1255,6 +1259,23 @@ func (region *SCloudregion) GetUsedSkus() (map[string]bool, error) { return usedSkus, nil } +// 获取本地已变更过套餐状态的公有云套餐 +func (manager *SServerSkuManager) GetLocalSkus() (map[string]bool, error) { + q := db.Metadata.Query("obj_id").Equals("obj_type", manager.Keyword()).Equals("key", api.SERVER_SKU_PROJECT_SRC_KEY).Equals("value", api.SERVER_SKU_PROJECT_SRC_VALUE_LOCAL) + ret := []struct { + ObjId string `json:"obj_id"` + }{} + err := q.All(&ret) + if err != nil { + return nil, errors.Wrapf(err, "GetLocalSkus") + } + localSkus := make(map[string]bool, 0) + for _, item := range ret { + localSkus[item.ObjId] = true + } + return localSkus, nil +} + func (region *SCloudregion) SyncServerSkus(ctx context.Context, userCred mcclient.TokenCredential, xor bool) compare.SyncResult { lockman.LockRawObject(ctx, ServerSkuManager.Keyword(), region.Id) defer lockman.ReleaseRawObject(ctx, ServerSkuManager.Keyword(), region.Id) @@ -1296,15 +1317,15 @@ func (region *SCloudregion) SyncServerSkus(ctx context.Context, userCred mcclien result.Error(errors.Wrapf(err, "GetUsedSkus %s", region.ExternalId)) return result } + localSkus, err := ServerSkuManager.GetLocalSkus() + if err != nil { + result.Error(errors.Wrapf(err, "GetLocalSkus")) + return result + } purgeIds := []string{} for i := 0; i < len(removed); i += 1 { - var err error if usedSkus[removed[i].Name] { - err = removed[i].MarkAsSoldout(ctx) - if err != nil { - result.DeleteError(err) - } continue } purgeIds = append(purgeIds, removed[i].Id) @@ -1321,7 +1342,8 @@ func (region *SCloudregion) SyncServerSkus(ctx context.Context, userCred mcclien if !xor { for i := 0; i < len(commondb); i += 1 { - err = commondb[i].syncWithCloudSku(ctx, userCred, region, commonext[i]) + _, isLocalChangedStatus := localSkus[commondb[i].Id] + err = commondb[i].syncWithCloudSku(ctx, region, isLocalChangedStatus, commonext[i]) if err != nil { result.UpdateError(err) } else {