Merge pull request #7662 from Lyndon-Li/issue-fix-7648

Issue fix 7648: avoid snapshot leak on expose failure
This commit is contained in:
Xun Jiang/Bruce Jiang
2024-04-12 17:28:27 +08:00
committed by GitHub
4 changed files with 24 additions and 40 deletions

View File

@@ -0,0 +1 @@
Fix issue #7648. Adjust the exposing logic to avoid exposing failure and snapshot leak when expose fails

View File

@@ -113,41 +113,6 @@ func (e *csiSnapshotExposer) Expose(ctx context.Context, ownerObject corev1.Obje
curLog.WithField("vsc name", vsc.Name).WithField("vs name", volumeSnapshot.Name).Infof("Got VSC from VS in namespace %s", volumeSnapshot.Namespace)
retained, err := csi.RetainVSC(ctx, e.csiSnapshotClient, vsc)
if err != nil {
return errors.Wrap(err, "error to retain volume snapshot content")
}
curLog.WithField("vsc name", vsc.Name).WithField("retained", (retained != nil)).Info("Finished to retain VSC")
defer func() {
if retained != nil {
csi.DeleteVolumeSnapshotContentIfAny(ctx, e.csiSnapshotClient, retained.Name, curLog)
}
}()
err = csi.EnsureDeleteVS(ctx, e.csiSnapshotClient, volumeSnapshot.Name, volumeSnapshot.Namespace, csiExposeParam.OperationTimeout)
if err != nil {
return errors.Wrap(err, "error to delete volume snapshot")
}
curLog.WithField("vs name", volumeSnapshot.Name).Infof("VS is deleted in namespace %s", volumeSnapshot.Namespace)
err = csi.RemoveVSCProtect(ctx, e.csiSnapshotClient, vsc.Name, csiExposeParam.ExposeTimeout)
if err != nil {
return errors.Wrap(err, "error to remove protect from volume snapshot content")
}
curLog.WithField("vsc name", vsc.Name).Infof("Removed protect from VSC")
err = csi.EnsureDeleteVSC(ctx, e.csiSnapshotClient, vsc.Name, csiExposeParam.OperationTimeout)
if err != nil {
return errors.Wrap(err, "error to delete volume snapshot content")
}
curLog.WithField("vsc name", vsc.Name).Infof("VSC is deleted")
retained = nil
backupVS, err := e.createBackupVS(ctx, ownerObject, volumeSnapshot)
if err != nil {
return errors.Wrap(err, "error to create backup volume snapshot")
@@ -168,6 +133,27 @@ func (e *csiSnapshotExposer) Expose(ctx context.Context, ownerObject corev1.Obje
curLog.WithField("vsc name", backupVSC.Name).Infof("Backup VSC is created from %s", vsc.Name)
retained, err := csi.RetainVSC(ctx, e.csiSnapshotClient, vsc)
if err != nil {
return errors.Wrap(err, "error to retain volume snapshot content")
}
curLog.WithField("vsc name", vsc.Name).WithField("retained", (retained != nil)).Info("Finished to retain VSC")
err = csi.EnsureDeleteVS(ctx, e.csiSnapshotClient, volumeSnapshot.Name, volumeSnapshot.Namespace, csiExposeParam.OperationTimeout)
if err != nil {
return errors.Wrap(err, "error to delete volume snapshot")
}
curLog.WithField("vs name", volumeSnapshot.Name).Infof("VS is deleted in namespace %s", volumeSnapshot.Namespace)
err = csi.EnsureDeleteVSC(ctx, e.csiSnapshotClient, vsc.Name, csiExposeParam.OperationTimeout)
if err != nil {
return errors.Wrap(err, "error to delete volume snapshot content")
}
curLog.WithField("vsc name", vsc.Name).Infof("VSC is deleted")
var volumeSize resource.Quantity
if volumeSnapshot.Status.RestoreSize != nil && !volumeSnapshot.Status.RestoreSize.IsZero() {
volumeSize = *volumeSnapshot.Status.RestoreSize

View File

@@ -129,8 +129,7 @@ func GetVolumeSnapshotContentForVolumeSnapshot(
return vsc, nil
}
// RetainVSC updates the VSC's deletion policy to Retain and add a
// finalizer and then return the update VSC
// RetainVSC updates the VSC's deletion policy to Retain and then return the update VSC
func RetainVSC(ctx context.Context, snapshotClient snapshotter.SnapshotV1Interface,
vsc *snapshotv1api.VolumeSnapshotContent) (*snapshotv1api.VolumeSnapshotContent, error) {
if vsc.Spec.DeletionPolicy == snapshotv1api.VolumeSnapshotContentRetain {
@@ -139,7 +138,6 @@ func RetainVSC(ctx context.Context, snapshotClient snapshotter.SnapshotV1Interfa
return patchVSC(ctx, snapshotClient, vsc, func(updated *snapshotv1api.VolumeSnapshotContent) {
updated.Spec.DeletionPolicy = snapshotv1api.VolumeSnapshotContentRetain
updated.Finalizers = append(updated.Finalizers, volumeSnapshotContentProtectFinalizer)
})
}

View File

@@ -626,8 +626,7 @@ func TestRetainVSC(t *testing.T) {
clientObj: []runtime.Object{vscObj},
updated: &snapshotv1api.VolumeSnapshotContent{
ObjectMeta: metav1.ObjectMeta{
Name: "fake-vsc",
Finalizers: []string{volumeSnapshotContentProtectFinalizer},
Name: "fake-vsc",
},
Spec: snapshotv1api.VolumeSnapshotContentSpec{
DeletionPolicy: snapshotv1api.VolumeSnapshotContentRetain,