From 2486aa30719bc8b0fad75b084fa637e18e3c886e Mon Sep 17 00:00:00 2001 From: Qiu Jian Date: Sat, 17 Oct 2020 15:18:03 +0800 Subject: [PATCH] fix: cancel pending-delete should increase resource quota usages --- pkg/cloudcommon/db/quotas/register.go | 1 + pkg/cloudcommon/db/usages.go | 2 ++ pkg/cloudcommon/db/virtualresource.go | 17 +++++++++++++++-- pkg/compute/models/disks.go | 7 +++++-- pkg/compute/models/guest_actions.go | 7 +++++-- pkg/image/models/image_guest.go | 25 +++++++++++++++++++++++-- pkg/image/models/image_guest_joint.go | 3 ++- pkg/image/models/images.go | 7 +++++-- 8 files changed, 58 insertions(+), 11 deletions(-) diff --git a/pkg/cloudcommon/db/quotas/register.go b/pkg/cloudcommon/db/quotas/register.go index 5a7eac1877..2a61f7487c 100644 --- a/pkg/cloudcommon/db/quotas/register.go +++ b/pkg/cloudcommon/db/quotas/register.go @@ -33,6 +33,7 @@ var ( func init() { quotaManagerTable = make(map[reflect.Type]IQuotaManager) + db.AddUsages = AddUsages db.CancelUsages = CancelUsages db.CancelPendingUsagesInContext = cancelPendingUsagesInContext db.InitPendingUsagesInContext = initPendingUsagesInContext diff --git a/pkg/cloudcommon/db/usages.go b/pkg/cloudcommon/db/usages.go index 65f31b061f..c0270a2411 100644 --- a/pkg/cloudcommon/db/usages.go +++ b/pkg/cloudcommon/db/usages.go @@ -28,6 +28,8 @@ type IUsage interface { var ( CancelUsages func(ctx context.Context, userCred mcclient.TokenCredential, usages []IUsage) + AddUsages func(ctx context.Context, userCred mcclient.TokenCredential, usages []IUsage) + CancelPendingUsagesInContext func(ctx context.Context, userCred mcclient.TokenCredential) error InitPendingUsagesInContext func(ctx context.Context) context.Context diff --git a/pkg/cloudcommon/db/virtualresource.go b/pkg/cloudcommon/db/virtualresource.go index 1c7cf2e504..e854798fec 100644 --- a/pkg/cloudcommon/db/virtualresource.go +++ b/pkg/cloudcommon/db/virtualresource.go @@ -449,11 +449,21 @@ func (model *SVirtualResourceBase) AllowPerformCancelDelete(ctx context.Context, func (model *SVirtualResourceBase) PerformCancelDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { if model.PendingDeleted && !model.Deleted { err := model.DoCancelPendingDelete(ctx, userCred) - return nil, err + if err != nil { + return nil, errors.Wrap(err, "model.DoCancelPendingDelete") + } + model.RecoverUsages(ctx, userCred) } return nil, nil } +func (model *SVirtualResourceBase) RecoverUsages(ctx context.Context, userCred mcclient.TokenCredential) { + usages := model.GetIModel().GetUsages() + if AddUsages != nil && len(usages) > 0 { + AddUsages(ctx, userCred, usages) + } +} + func (model *SVirtualResourceBase) DoCancelPendingDelete(ctx context.Context, userCred mcclient.TokenCredential) error { err := model.CancelPendingDelete(ctx, userCred) if err == nil { @@ -472,7 +482,10 @@ func (model *SVirtualResourceBase) GetIVirtualModel() IVirtualModel { func (model *SVirtualResourceBase) CancelPendingDelete(ctx context.Context, userCred mcclient.TokenCredential) error { if model.PendingDeleted && !model.Deleted { - return model.MarkCancelPendingDelete(ctx, userCred) + err := model.MarkCancelPendingDelete(ctx, userCred) + if err != nil { + return errors.Wrap(err, "MarkCancelPendingDelete") + } } return nil } diff --git a/pkg/compute/models/disks.go b/pkg/compute/models/disks.go index 007f84ef82..9d4eb8644f 100644 --- a/pkg/compute/models/disks.go +++ b/pkg/compute/models/disks.go @@ -2150,9 +2150,12 @@ func (self *SDisk) AllowPerformCancelDelete(ctx context.Context, userCred mcclie } func (self *SDisk) PerformCancelDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { - if self.PendingDeleted { + if self.PendingDeleted && !self.Deleted { err := self.DoCancelPendingDelete(ctx, userCred) - return nil, err + if err != nil { + return nil, err + } + self.RecoverUsages(ctx, userCred) } return nil, nil } diff --git a/pkg/compute/models/guest_actions.go b/pkg/compute/models/guest_actions.go index 2e8319caeb..4fc81f8ae3 100644 --- a/pkg/compute/models/guest_actions.go +++ b/pkg/compute/models/guest_actions.go @@ -2638,9 +2638,12 @@ func (model *SGuest) AllowPerformCancelDelete(ctx context.Context, userCred mccl } func (self *SGuest) PerformCancelDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { - if self.PendingDeleted { + if self.PendingDeleted && !self.Deleted { err := self.DoCancelPendingDelete(ctx, userCred) - return nil, err + if err != nil { + return nil, errors.Wrap(err, "DoCancelPendingDelete") + } + self.RecoverUsages(ctx, userCred) } return nil, nil } diff --git a/pkg/image/models/image_guest.go b/pkg/image/models/image_guest.go index 8a740d5d83..1e8754d758 100644 --- a/pkg/image/models/image_guest.go +++ b/pkg/image/models/image_guest.go @@ -246,9 +246,12 @@ func (gi *SGuestImage) AllowPerformCancelDelete(ctx context.Context, userCred mc func (gi *SGuestImage) PerformCancelDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { - if gi.PendingDeleted { + if gi.PendingDeleted && !gi.Deleted { err := gi.DoCancelPendingDelete(ctx, userCred) - return nil, err + if err != nil { + return nil, errors.Wrap(err, "DoCancelPendingDelete") + } + gi.RecoverUsages(ctx, userCred) } return nil, nil } @@ -635,3 +638,21 @@ func (manager *SGuestImageManager) Usage(scope rbacutils.TRbacScope, ownerId mcc return usages } + +func (gi *SGuestImage) GetUsages() []db.IUsage { + if gi.PendingDeleted || gi.Deleted { + return nil + } + images, err := GuestImageJointManager.GetImagesByGuestImageId(gi.Id) + if err != nil { + return nil + } + usages := make([]db.IUsage, 0) + for i := range images { + ui := images[i].GetUsages() + if len(ui) > 0 { + usages = append(usages, ui...) + } + } + return usages +} diff --git a/pkg/image/models/image_guest_joint.go b/pkg/image/models/image_guest_joint.go index 02f4d69768..cd559b6e7a 100644 --- a/pkg/image/models/image_guest_joint.go +++ b/pkg/image/models/image_guest_joint.go @@ -16,6 +16,7 @@ package models import ( "context" + "database/sql" "yunion.io/x/pkg/errors" "yunion.io/x/sqlchemy" @@ -102,7 +103,7 @@ func (gm *SGuestImageJointManager) GetImagesByFilter(guestImageId string, q = filter(q) images := make([]SImage, 0, len(imageIds)) err = db.FetchModelObjects(ImageManager, q, &images) - if err != nil { + if err != nil && errors.Cause(err) != sql.ErrNoRows { return nil, errors.Wrap(err, "fetch images failed") } return images, nil diff --git a/pkg/image/models/images.go b/pkg/image/models/images.go index 0698e588ab..3b19087c6d 100644 --- a/pkg/image/models/images.go +++ b/pkg/image/models/images.go @@ -806,9 +806,12 @@ func (self *SImage) AllowPerformCancelDelete(ctx context.Context, userCred mccli } func (self *SImage) PerformCancelDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { - if self.PendingDeleted { + if self.PendingDeleted && !self.Deleted { err := self.DoCancelPendingDelete(ctx, userCred) - return nil, err + if err != nil { + return nil, errors.Wrap(err, "DoCancelPendingDelete") + } + self.RecoverUsages(ctx, userCred) } return nil, nil }