mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-01-06 13:26:26 +00:00
Merge pull request #7662 from Lyndon-Li/issue-fix-7648
Issue fix 7648: avoid snapshot leak on expose failure
This commit is contained in:
1
changelogs/unreleased/7662-Lyndon-Li
Normal file
1
changelogs/unreleased/7662-Lyndon-Li
Normal file
@@ -0,0 +1 @@
|
||||
Fix issue #7648. Adjust the exposing logic to avoid exposing failure and snapshot leak when expose fails
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user