mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-06-09 16:07:36 +08:00
fix: server change config failed due to quota recode
This commit is contained in:
@@ -153,7 +153,14 @@ func (manager *SQuotaBaseManager) getQuotasInternal(ctx context.Context, keys IQ
|
||||
}
|
||||
|
||||
func (manager *SQuotaBaseManager) setQuotaInternal(ctx context.Context, userCred mcclient.TokenCredential, quota IQuota) error {
|
||||
return manager.TableSpec().InsertOrUpdate(quota)
|
||||
err := manager.TableSpec().InsertOrUpdate(quota)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "InsertOrUpdate")
|
||||
}
|
||||
if manager.nonNegative {
|
||||
quota.ResetNegative()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (manager *SQuotaBaseManager) addQuotaInternal(ctx context.Context, userCred mcclient.TokenCredential, diff IQuota) error {
|
||||
|
||||
@@ -69,7 +69,7 @@ func (manager *SQuotaBaseManager) cancelPendingUsage(ctx context.Context, userCr
|
||||
|
||||
func (manager *SQuotaBaseManager) _cancelPendingUsage(ctx context.Context, userCred mcclient.TokenCredential, localUsage IQuota, cancelUsage IQuota) error {
|
||||
originKeys := localUsage.GetKeys()
|
||||
currentKeys := cancelUsage.GetKeys()
|
||||
// currentKeys := cancelUsage.GetKeys()
|
||||
|
||||
pendingUsage := manager.newQuota()
|
||||
pendingUsage.SetKeys(originKeys)
|
||||
@@ -79,9 +79,6 @@ func (manager *SQuotaBaseManager) _cancelPendingUsage(ctx context.Context, userC
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "manager.pendingStore.SubQuota")
|
||||
}
|
||||
// save cancelUsage values
|
||||
subUsage := manager.newQuota()
|
||||
subUsage.Update(cancelUsage)
|
||||
//
|
||||
if localUsage != nil {
|
||||
localUsage.Sub(cancelUsage)
|
||||
@@ -89,18 +86,11 @@ func (manager *SQuotaBaseManager) _cancelPendingUsage(ctx context.Context, userC
|
||||
|
||||
log.Debugf("cancelUsage: %s localUsage: %s", jsonutils.Marshal(cancelUsage), jsonutils.Marshal(localUsage))
|
||||
|
||||
// update usages
|
||||
quotas, err := manager.usageStore.GetParentQuotas(ctx, currentKeys)
|
||||
err = manager.changeUsage(ctx, userCred, cancelUsage, true)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "manager.usageStore.GetParentQuotas")
|
||||
}
|
||||
for i := range quotas {
|
||||
subUsage.SetKeys(quotas[i].GetKeys())
|
||||
err := manager.usageStore.AddQuota(ctx, userCred, subUsage)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "manager.usageStore.AddQuota")
|
||||
}
|
||||
return errors.Wrap(err, "manager.changelUsage")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -112,6 +102,10 @@ func (manager *SQuotaBaseManager) cancelUsage(ctx context.Context, userCred mccl
|
||||
}
|
||||
|
||||
func (manager *SQuotaBaseManager) _cancelUsage(ctx context.Context, userCred mcclient.TokenCredential, usage IQuota) error {
|
||||
return manager.changeUsage(ctx, userCred, usage, false)
|
||||
}
|
||||
|
||||
func (manager *SQuotaBaseManager) changeUsage(ctx context.Context, userCred mcclient.TokenCredential, usage IQuota, isAdd bool) error {
|
||||
usages, err := manager.usageStore.GetParentQuotas(ctx, usage.GetKeys())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "manager.usageStore.GetParentQuotas")
|
||||
@@ -120,9 +114,16 @@ func (manager *SQuotaBaseManager) _cancelUsage(ctx context.Context, userCred mcc
|
||||
subUsage.Update(usage)
|
||||
for i := range usages {
|
||||
subUsage.SetKeys(usages[i].GetKeys())
|
||||
err := manager.usageStore.SubQuota(ctx, userCred, subUsage)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "manager.usageStore.AddQuota")
|
||||
if isAdd {
|
||||
err := manager.usageStore.AddQuota(ctx, userCred, subUsage)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "manager.usageStore.AddQuota")
|
||||
}
|
||||
} else {
|
||||
err := manager.usageStore.SubQuota(ctx, userCred, subUsage)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "manager.usageStore.SubQuota")
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -203,16 +204,23 @@ func (manager *SQuotaBaseManager) checkQuota(ctx context.Context, request IQuota
|
||||
}
|
||||
|
||||
func (manager *SQuotaBaseManager) __checkQuota(ctx context.Context, quota IQuota, request IQuota) error {
|
||||
keys := quota.GetKeys()
|
||||
log.Debugf("__checkQuota for keys: %s", QuotaKeyString(keys))
|
||||
used := manager.newQuota()
|
||||
err := manager.usageStore.GetQuota(ctx, quota.GetKeys(), used)
|
||||
err := manager.usageStore.GetQuota(ctx, keys, used)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "manager.usageStore.GetQuotaByKeys")
|
||||
}
|
||||
pendings, err := manager.pendingStore.GetChildrenQuotas(ctx, quota.GetKeys())
|
||||
log.Debugf("__checkQuota usage: %s", jsonutils.Marshal(used))
|
||||
pendings, err := manager.pendingStore.GetChildrenQuotas(ctx, keys)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "manager.pendingStore.GetChildrenQuotas")
|
||||
}
|
||||
for i := range pendings {
|
||||
if pendings[i].IsEmpty() {
|
||||
continue
|
||||
}
|
||||
log.Debugf("__checkQuota pending %d: %s", i, jsonutils.Marshal(pendings[i]))
|
||||
used.Add(pendings[i])
|
||||
}
|
||||
return used.Exceed(request, quota)
|
||||
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/gotypes"
|
||||
"yunion.io/x/pkg/util/reflectutils"
|
||||
"yunion.io/x/pkg/util/stringutils"
|
||||
@@ -226,7 +227,7 @@ func fetchTaskParams(
|
||||
if len(pendingUsages) > 0 {
|
||||
for i := range pendingUsages {
|
||||
pendingUsage := pendingUsages[i]
|
||||
if gotypes.IsNil(pendingUsage) || pendingUsage.IsEmpty() {
|
||||
if gotypes.IsNil(pendingUsage) {
|
||||
continue
|
||||
}
|
||||
key := pendingUsageKey(i)
|
||||
@@ -709,11 +710,17 @@ func (self *STask) IsCurrentStageComplete() bool {
|
||||
|
||||
func (self *STask) GetPendingUsage(quota quotas.IQuota, index int) error {
|
||||
key := pendingUsageKey(index)
|
||||
quotaJson, err := self.Params.Get(key)
|
||||
if err != nil {
|
||||
return err
|
||||
if self.Params.Contains(key) {
|
||||
quotaJson, err := self.Params.Get(key)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "task.Params.Get %s", key)
|
||||
}
|
||||
err = quotaJson.Unmarshal(quota)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "quotaJson.Unmarshal")
|
||||
}
|
||||
}
|
||||
return quotaJson.Unmarshal(quota)
|
||||
return nil
|
||||
}
|
||||
|
||||
func pendingUsageKey(index int) string {
|
||||
|
||||
@@ -2395,11 +2395,10 @@ func (self *SGuest) PerformChangeConfig(ctx context.Context, userCred mcclient.T
|
||||
return nil, err
|
||||
}
|
||||
pendingUsage.SetKeys(keys)
|
||||
if !pendingUsage.IsEmpty() {
|
||||
err := quotas.CheckSetPendingQuota(ctx, userCred, pendingUsage)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Debugf("ChangeConfig pendingUsage %s", jsonutils.Marshal(pendingUsage))
|
||||
err = quotas.CheckSetPendingQuota(ctx, userCred, pendingUsage)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(newDisks) > 0 {
|
||||
|
||||
@@ -199,10 +199,10 @@ func (self *GuestChangeConfigTask) OnGuestChangeCpuMemSpecComplete(ctx context.C
|
||||
return
|
||||
}
|
||||
changeConfigSpec := jsonutils.NewDict()
|
||||
if addCpu > 0 {
|
||||
if addCpu != 0 {
|
||||
changeConfigSpec.Set("add_cpu", jsonutils.NewInt(int64(addCpu)))
|
||||
}
|
||||
if addMem > 0 {
|
||||
if addMem != 0 {
|
||||
changeConfigSpec.Set("add_mem", jsonutils.NewInt(int64(addMem)))
|
||||
}
|
||||
if len(instanceType) > 0 {
|
||||
@@ -218,11 +218,16 @@ func (self *GuestChangeConfigTask) OnGuestChangeCpuMemSpecComplete(ctx context.C
|
||||
return
|
||||
}
|
||||
var cancelUsage models.SQuota
|
||||
var reduceUsage models.SQuota
|
||||
if addCpu > 0 {
|
||||
cancelUsage.Cpu = addCpu
|
||||
} else if addCpu < 0 {
|
||||
reduceUsage.Cpu = -addCpu
|
||||
}
|
||||
if addMem > 0 {
|
||||
cancelUsage.Memory = addMem
|
||||
} else if addMem < 0 {
|
||||
reduceUsage.Memory = -addMem
|
||||
}
|
||||
|
||||
keys, err := guest.GetQuotaKeys()
|
||||
@@ -231,19 +236,26 @@ func (self *GuestChangeConfigTask) OnGuestChangeCpuMemSpecComplete(ctx context.C
|
||||
return
|
||||
}
|
||||
cancelUsage.SetKeys(keys)
|
||||
reduceUsage.SetKeys(keys)
|
||||
|
||||
lockman.LockClass(ctx, guest.GetModelManager(), guest.ProjectId)
|
||||
defer lockman.ReleaseClass(ctx, guest.GetModelManager(), guest.ProjectId)
|
||||
|
||||
err = quotas.CancelPendingUsage(ctx, self.UserCred, &pendingUsage, &cancelUsage)
|
||||
if err != nil {
|
||||
self.markStageFailed(ctx, guest, fmt.Sprintf("CancelPendingUsage fail %s", err))
|
||||
return
|
||||
if !cancelUsage.IsEmpty() {
|
||||
err = quotas.CancelPendingUsage(ctx, self.UserCred, &pendingUsage, &cancelUsage)
|
||||
if err != nil {
|
||||
self.markStageFailed(ctx, guest, fmt.Sprintf("CancelPendingUsage fail %s", err))
|
||||
return
|
||||
}
|
||||
err = self.SetPendingUsage(&pendingUsage, 0)
|
||||
if err != nil {
|
||||
self.markStageFailed(ctx, guest, fmt.Sprintf("SetPendingUsage fail %s", err))
|
||||
return
|
||||
}
|
||||
}
|
||||
err = self.SetPendingUsage(&pendingUsage, 0)
|
||||
if err != nil {
|
||||
self.markStageFailed(ctx, guest, fmt.Sprintf("SetPendingUsage fail %s", err))
|
||||
return
|
||||
|
||||
if !reduceUsage.IsEmpty() {
|
||||
quotas.CancelUsages(ctx, self.UserCred, []db.IUsage{&reduceUsage})
|
||||
}
|
||||
|
||||
self.OnGuestChangeCpuMemSpecFinish(ctx, guest)
|
||||
|
||||
@@ -61,12 +61,8 @@ func JsonClientError(w http.ResponseWriter, e *httputils.JSONClientError) {
|
||||
}
|
||||
|
||||
func GeneralServerError(w http.ResponseWriter, e error) {
|
||||
je, ok := e.(*httputils.JSONClientError)
|
||||
if ok {
|
||||
JsonClientError(w, je)
|
||||
} else {
|
||||
InternalServerError(w, "%s", e)
|
||||
}
|
||||
je := NewGeneralError(e)
|
||||
JsonClientError(w, je)
|
||||
}
|
||||
|
||||
func BadRequestError(w http.ResponseWriter, msg string, params ...interface{}) {
|
||||
|
||||
Reference in New Issue
Block a user