Skip to content

Commit 6c1c0ea

Browse files
authored
Merge pull request #283 from xing-yang/check_pvc_inuse
Check if PVC is being used by a snapshot as source
2 parents 69db084 + c82c8e0 commit 6c1c0ea

File tree

3 files changed

+34
-9
lines changed

3 files changed

+34
-9
lines changed

pkg/common-controller/snapshot_controller.go

+26-1
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,11 @@ func (ctrl *csiSnapshotCommonController) syncSnapshot(snapshot *crdv1.VolumeSnap
166166
ctrl.eventRecorder.Event(snapshot, v1.EventTypeWarning, "ErrorPVCFinalizer", "Error check and remove PVC Finalizer for VolumeSnapshot")
167167
}
168168

169-
if snapshot.ObjectMeta.DeletionTimestamp != nil {
169+
// Proceed with snapshot deletion only if snapshot is not in the middled of being
170+
// created from a PVC with a finalizer. This is to ensure that the PVC finalizer
171+
// can be removed even if a delete snapshot request is received before create
172+
// snapshot has completed.
173+
if snapshot.ObjectMeta.DeletionTimestamp != nil && !ctrl.isPVCwithFinalizerInUseByCurrentSnapshot(snapshot) {
170174
err := ctrl.processSnapshotWithDeletionTimestamp(snapshot)
171175
if err != nil {
172176
return err
@@ -190,6 +194,27 @@ func (ctrl *csiSnapshotCommonController) syncSnapshot(snapshot *crdv1.VolumeSnap
190194
return nil
191195
}
192196

197+
// Check if PVC has a finalizer and if it is being used by the current snapshot as source.
198+
func (ctrl *csiSnapshotCommonController) isPVCwithFinalizerInUseByCurrentSnapshot(snapshot *crdv1.VolumeSnapshot) bool {
199+
// Get snapshot source which is a PVC
200+
pvc, err := ctrl.getClaimFromVolumeSnapshot(snapshot)
201+
if err != nil {
202+
klog.Infof("cannot get claim from snapshot [%s]: [%v] Claim may be deleted already.", snapshot.Name, err)
203+
return false
204+
}
205+
206+
// Check if there is a Finalizer on PVC. If not, return false
207+
if !slice.ContainsString(pvc.ObjectMeta.Finalizers, utils.PVCFinalizer, nil) {
208+
return false
209+
}
210+
211+
if !utils.IsSnapshotReady(snapshot) {
212+
klog.V(2).Infof("PVC %s/%s is being used by snapshot %s/%s as source", pvc.Namespace, pvc.Name, snapshot.Namespace, snapshot.Name)
213+
return true
214+
}
215+
return false
216+
}
217+
193218
// checkContentAndBoundStatus is a helper function that checks the following:
194219
// - It checks if content exists and returns the content object if it exists and nil otherwise.
195220
// - It checks the deletionPolicy and returns true if policy is Delete and false otherwise.

pkg/common-controller/snapshot_delete_test.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,8 @@ func TestDeleteSync(t *testing.T) {
172172
name: "3-1 - content will be deleted if snapshot deletion timestamp is set",
173173
initialContents: newContentArray("content3-1", "", "snap3-1", "sid3-1", validSecretClass, "", "", deletePolicy, nil, nil, true),
174174
expectedContents: nocontents,
175-
initialSnapshots: newSnapshotArray("snap3-1", "snapuid3-1", "claim3-1", "", validSecretClass, "content3-1", &False, nil, nil, nil, false, true, &timeNowMetav1),
176-
expectedSnapshots: withSnapshotFinalizers(newSnapshotArray("snap3-1", "snapuid3-1", "claim3-1", "", validSecretClass, "content3-1", &False, nil, nil, nil, false, false, &timeNowMetav1),
175+
initialSnapshots: newSnapshotArray("snap3-1", "snapuid3-1", "claim3-1", "", validSecretClass, "content3-1", &True, nil, nil, nil, false, true, &timeNowMetav1),
176+
expectedSnapshots: withSnapshotFinalizers(newSnapshotArray("snap3-1", "snapuid3-1", "claim3-1", "", validSecretClass, "content3-1", &True, nil, nil, nil, false, false, &timeNowMetav1),
177177
utils.VolumeSnapshotBoundFinalizer,
178178
),
179179
initialClaims: newClaimArray("claim3-1", "pvc-uid3-1", "1Gi", "volume3-1", v1.ClaimBound, &classEmpty),
@@ -186,8 +186,8 @@ func TestDeleteSync(t *testing.T) {
186186
name: "3-2 - content will not be deleted if deletion API call fails",
187187
initialContents: newContentArray("content3-2", "", "snap3-2", "sid3-2", validSecretClass, "", "", deletePolicy, nil, nil, true),
188188
expectedContents: newContentArray("content3-2", "", "snap3-2", "sid3-2", validSecretClass, "", "", deletePolicy, nil, nil, true),
189-
initialSnapshots: newSnapshotArray("snap3-2", "snapuid3-2", "claim3-2", "", validSecretClass, "content3-2", &False, nil, nil, nil, false, true, &timeNowMetav1),
190-
expectedSnapshots: newSnapshotArray("snap3-2", "snapuid3-2", "claim3-2", "", validSecretClass, "content3-2", &False, nil, nil, nil, false, true, &timeNowMetav1),
189+
initialSnapshots: newSnapshotArray("snap3-2", "snapuid3-2", "claim3-2", "", validSecretClass, "content3-2", &True, nil, nil, nil, false, true, &timeNowMetav1),
190+
expectedSnapshots: newSnapshotArray("snap3-2", "snapuid3-2", "claim3-2", "", validSecretClass, "content3-2", &True, nil, nil, nil, false, true, &timeNowMetav1),
191191
initialClaims: newClaimArray("claim3-2", "pvc-uid3-2", "1Gi", "volume3-2", v1.ClaimBound, &classEmpty),
192192
expectedEvents: []string{"Warning SnapshotContentObjectDeleteError"},
193193
initialSecrets: []*v1.Secret{secret()},
@@ -206,8 +206,8 @@ func TestDeleteSync(t *testing.T) {
206206
map[string]string{
207207
"snapshot.storage.kubernetes.io/volumesnapshot-being-deleted": "yes",
208208
}),
209-
initialSnapshots: newSnapshotArray("snap3-3", "snapuid3-3", "claim3-3", "", validSecretClass, "content3-3", &False, nil, nil, nil, false, true, &timeNowMetav1),
210-
expectedSnapshots: withSnapshotFinalizers(newSnapshotArray("snap3-3", "snapuid3-3", "claim3-3", "", validSecretClass, "content3-3", &False, nil, nil, nil, false, false, &timeNowMetav1),
209+
initialSnapshots: newSnapshotArray("snap3-3", "snapuid3-3", "claim3-3", "", validSecretClass, "content3-3", &True, nil, nil, nil, false, true, &timeNowMetav1),
210+
expectedSnapshots: withSnapshotFinalizers(newSnapshotArray("snap3-3", "snapuid3-3", "claim3-3", "", validSecretClass, "content3-3", &True, nil, nil, nil, false, false, &timeNowMetav1),
211211
utils.VolumeSnapshotBoundFinalizer,
212212
),
213213
initialClaims: newClaimArray("claim3-3", "pvc-uid3-3", "1Gi", "volume3-3", v1.ClaimBound, &classEmpty),

pkg/common-controller/snapshot_update_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -315,8 +315,8 @@ func TestSync(t *testing.T) {
315315
},
316316
{
317317
name: "5-5 - snapshot deletion candidate marked for deletion by syncSnapshot",
318-
initialSnapshots: newSnapshotArray("snap5-5", "snapuid5-5", "claim5-5", "", validSecretClass, "content5-5", &False, nil, nil, nil, false, true, &timeNowMetav1),
319-
expectedSnapshots: withSnapshotFinalizers(newSnapshotArray("snap5-5", "snapuid5-5", "claim5-5", "", validSecretClass, "content5-5", &False, nil, nil, nil, false, false, &timeNowMetav1),
318+
initialSnapshots: newSnapshotArray("snap5-5", "snapuid5-5", "claim5-5", "", validSecretClass, "content5-5", &True, nil, nil, nil, false, true, &timeNowMetav1),
319+
expectedSnapshots: withSnapshotFinalizers(newSnapshotArray("snap5-5", "snapuid5-5", "claim5-5", "", validSecretClass, "content5-5", &True, nil, nil, nil, false, false, &timeNowMetav1),
320320
utils.VolumeSnapshotBoundFinalizer,
321321
),
322322
initialContents: newContentArray("content5-5", "snapuid5-5", "snap5-5", "sid5-5", validSecretClass, "", "", crdv1.VolumeSnapshotContentRetain, nil, nil, true),

0 commit comments

Comments
 (0)