From c94bcbdd0b1b45a66c33e4433923513932bea5dd Mon Sep 17 00:00:00 2001 From: wanyaoqi Date: Mon, 26 Aug 2019 18:55:54 +0800 Subject: [PATCH] fix rbd disk delete with snapshot --- pkg/compute/models/disks.go | 14 ++++++++++++++ pkg/compute/models/guests.go | 20 +++++--------------- pkg/compute/models/regiondrivers.go | 2 +- pkg/compute/models/snapshots.go | 14 ++++++++++++++ pkg/compute/regiondrivers/base.go | 2 +- pkg/compute/regiondrivers/kvm.go | 6 +++--- pkg/compute/regiondrivers/managedvirtual.go | 4 ++-- pkg/compute/tasks/guest_detach_disk_task.go | 10 +++++++++- pkg/compute/tasks/snapshot_delete_task.go | 2 +- 9 files changed, 50 insertions(+), 24 deletions(-) diff --git a/pkg/compute/models/disks.go b/pkg/compute/models/disks.go index 8ab4595ff1..f5ab0d7c95 100644 --- a/pkg/compute/models/disks.go +++ b/pkg/compute/models/disks.go @@ -1985,3 +1985,17 @@ func (self *SDisk) GetDynamicConditionInput() *jsonutils.JSONDict { conf := self.ToDiskConfig() return conf.JSON(conf) } + +func (self *SDisk) IsNeedWaitSnapshotsDeleted() (bool, error) { + storage := self.GetStorage() + if storage.StorageType == api.STORAGE_RBD { + scnt, err := self.GetSnapshotCount() + if err != nil { + return false, err + } + if scnt > 0 { + return true, nil + } + } + return false, nil +} diff --git a/pkg/compute/models/guests.go b/pkg/compute/models/guests.go index ffcc0320ef..cb9835656b 100644 --- a/pkg/compute/models/guests.go +++ b/pkg/compute/models/guests.go @@ -519,21 +519,6 @@ func (guest *SGuest) validateDeleteCondition(ctx context.Context, isPurge bool) if !isPurge && guest.IsValidPrePaid() { return httperrors.NewForbiddenError("not allow to delete prepaid server in valid status") } - gd := guest.GetDisks() - for i := 0; i < len(gd); i++ { - d := gd[i].GetDisk() - storage := d.GetStorage() - if storage.StorageType == api.STORAGE_RBD { - scnt, err := d.GetSnapshotCount() - if err != nil { - return err - } - if scnt > 0 { - return httperrors.NewBadRequestError( - "not allow to delete guest with %s disk has snapshots", storage.StorageType) - } - } - } return guest.SVirtualResourceBase.ValidateDeleteCondition(ctx) } @@ -1179,6 +1164,11 @@ func (manager *SGuestManager) validateEip(userCred mcclient.TokenCredential, inp return nil } +func (self *SGuest) PostUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) { + self.SVirtualResourceBase.PostUpdate(ctx, userCred, query, data) + self.StartSyncTask(ctx, userCred, true, "") +} + func (manager *SGuestManager) checkCreateQuota(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, input *api.ServerCreateInput, hasBackup bool) error { req := getGuestResourceRequirements(ctx, userCred, input, 1, hasBackup) quotaPlatform := make([]string, 0) diff --git a/pkg/compute/models/regiondrivers.go b/pkg/compute/models/regiondrivers.go index a22ca33c8a..5325ad596a 100644 --- a/pkg/compute/models/regiondrivers.go +++ b/pkg/compute/models/regiondrivers.go @@ -96,7 +96,7 @@ type IRegionDriver interface { OnDiskReset(ctx context.Context, userCred mcclient.TokenCredential, disk *SDisk, snapshot *SSnapshot, data jsonutils.JSONObject) error RequestApplySnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, sp *SSnapshotPolicy, task taskman.ITask, diskId string) error RequestCancelSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, sp *SSnapshotPolicy, task taskman.ITask, diskId string) error - OnSnapshotDelete(ctx context.Context, snapshot *SSnapshot, task taskman.ITask) error + OnSnapshotDelete(ctx context.Context, snapshot *SSnapshot, task taskman.ITask, data jsonutils.JSONObject) error } var regionDrivers map[string]IRegionDriver diff --git a/pkg/compute/models/snapshots.go b/pkg/compute/models/snapshots.go index e13b9f4b8f..f530485955 100644 --- a/pkg/compute/models/snapshots.go +++ b/pkg/compute/models/snapshots.go @@ -554,6 +554,20 @@ func (self *SSnapshot) StartSnapshotsDeleteTask(ctx context.Context, userCred mc } func (self *SSnapshot) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error { + if len(self.DiskId) > 0 { + disk := DiskManager.FetchDiskById(self.DiskId) + if disk != nil && disk.GetStorage().StorageType == api.STORAGE_RBD { + cnt, err := disk.GetGuestsCount() + if err == nil { + val := disk.GetMetadata("disk_delete_after_snapshots", userCred) + if cnt == 0 && val == "true" { + disk.StartDiskDeleteTask(ctx, userCred, "", false, true) + } + } else { + log.Errorln(err) + } + } + } return db.DeleteModel(ctx, userCred, self) } diff --git a/pkg/compute/regiondrivers/base.go b/pkg/compute/regiondrivers/base.go index 5d3fe4116e..94e4ac891d 100644 --- a/pkg/compute/regiondrivers/base.go +++ b/pkg/compute/regiondrivers/base.go @@ -196,6 +196,6 @@ func (self *SBaseRegionDriver) ValidateCreateSnapshopolicyDiskData(ctx context.C return fmt.Errorf("Not Implement ValidateCreateSnapshotpolicyDiskData") } -func (self *SBaseRegionDriver) OnSnapshotDelete(ctx context.Context, snapshot *models.SSnapshot, task taskman.ITask) error { +func (self *SBaseRegionDriver) OnSnapshotDelete(ctx context.Context, snapshot *models.SSnapshot, task taskman.ITask, data jsonutils.JSONObject) error { return fmt.Errorf("Not implement OnSnapshotDelete") } diff --git a/pkg/compute/regiondrivers/kvm.go b/pkg/compute/regiondrivers/kvm.go index 5423d4de2e..eed50d914a 100644 --- a/pkg/compute/regiondrivers/kvm.go +++ b/pkg/compute/regiondrivers/kvm.go @@ -779,7 +779,7 @@ func (self *SKVMRegionDriver) ValidateCreateSnapshotPolicyData(ctx context.Conte if err != nil { return err } - // TODO: kvm retention days + // TODO: To be determined if input.RetentionDays < -1 || input.RetentionDays == 0 || input.RetentionDays > 10 { return httperrors.NewInputParameterError("Retention days must in 1~10 or -1") } @@ -809,8 +809,8 @@ func (self *SKVMRegionDriver) RequestCancelSnapshotPolicy(ctx context.Context, u return nil } -func (self *SKVMRegionDriver) OnSnapshotDelete(ctx context.Context, snapshot *models.SSnapshot, task taskman.ITask) error { +func (self *SKVMRegionDriver) OnSnapshotDelete(ctx context.Context, snapshot *models.SSnapshot, task taskman.ITask, data jsonutils.JSONObject) error { task.SetStage("OnKvmSnapshotDelete", nil) - task.ScheduleRun(nil) + task.ScheduleRun(data) return nil } diff --git a/pkg/compute/regiondrivers/managedvirtual.go b/pkg/compute/regiondrivers/managedvirtual.go index c75c7c8951..61f1496dff 100644 --- a/pkg/compute/regiondrivers/managedvirtual.go +++ b/pkg/compute/regiondrivers/managedvirtual.go @@ -1227,8 +1227,8 @@ func (self *SManagedVirtualizationRegionDriver) ValidateCreateSnapshotPolicyData return nil } -func (self *SManagedVirtualizationRegionDriver) OnSnapshotDelete(ctx context.Context, snapshot *models.SSnapshot, task taskman.ITask) error { +func (self *SManagedVirtualizationRegionDriver) OnSnapshotDelete(ctx context.Context, snapshot *models.SSnapshot, task taskman.ITask, data jsonutils.JSONObject) error { task.SetStage("OnManagedSnapshotDelete", nil) - task.ScheduleRun(nil) + task.ScheduleRun(data) return nil } diff --git a/pkg/compute/tasks/guest_detach_disk_task.go b/pkg/compute/tasks/guest_detach_disk_task.go index c0927aef55..83f552d0b8 100644 --- a/pkg/compute/tasks/guest_detach_disk_task.go +++ b/pkg/compute/tasks/guest_detach_disk_task.go @@ -96,7 +96,12 @@ func (self *GuestDetachDiskTask) OnDetachDiskComplete(ctx context.Context, guest if host != nil && !host.Enabled && jsonutils.QueryBoolean(self.Params, "purge", false) { purge = true } - if !keepDisk && disk.AutoDelete { + waitSnapshotsDelete, err := disk.IsNeedWaitSnapshotsDeleted() + if err != nil { + self.OnTaskFail(ctx, guest, disk, err) + return + } + if !keepDisk && disk.AutoDelete && !waitSnapshotsDelete { cnt, _ := disk.GetGuestDiskCount() if cnt == 0 { self.SetStage("OnDiskDeleteComplete", nil) @@ -108,6 +113,9 @@ func (self *GuestDetachDiskTask) OnDetachDiskComplete(ctx context.Context, guest return } } + if waitSnapshotsDelete { + disk.SetMetadata(ctx, "disk_delete_after_snapshots", "true", self.UserCred) + } self.OnDiskDeleteComplete(ctx, guest, nil) } diff --git a/pkg/compute/tasks/snapshot_delete_task.go b/pkg/compute/tasks/snapshot_delete_task.go index d9466ca73d..d218ca8d5a 100644 --- a/pkg/compute/tasks/snapshot_delete_task.go +++ b/pkg/compute/tasks/snapshot_delete_task.go @@ -43,7 +43,7 @@ func (self *SnapshotDeleteTask) OnRequestSnapshotFailed(ctx context.Context, sna } func (self *SnapshotDeleteTask) OnRequestSnapshot(ctx context.Context, snapshot *models.SSnapshot, data jsonutils.JSONObject) { - err := snapshot.GetRegionDriver().OnSnapshotDelete(ctx, snapshot, self) + err := snapshot.GetRegionDriver().OnSnapshotDelete(ctx, snapshot, self, data) if err != nil { self.TaskFailed(ctx, snapshot, err.Error()) }