Skip to content

Commit 4c38cc8

Browse files
committed
Remove VolumeSnapshotBeingCreated annotation after driver response
1 parent 313507f commit 4c38cc8

File tree

3 files changed

+56
-36
lines changed

3 files changed

+56
-36
lines changed

pkg/sidecar-controller/content_create_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,9 @@ func TestSyncContent(t *testing.T) {
5252
name: "1-2: Basic sync content create snapshot",
5353
initialContents: withContentStatus(newContentArray("content1-2", "snapuid1-2", "snap1-2", "sid1-2", defaultClass, "", "volume-handle-1-2", retainPolicy, nil, &defaultSize, true),
5454
nil),
55-
expectedContents: withContentStatus(newContentArray("content1-2", "snapuid1-2", "snap1-2", "sid1-2", defaultClass, "", "volume-handle-1-2", retainPolicy, nil, &defaultSize, true),
55+
expectedContents: withContentAnnotations(withContentStatus(newContentArray("content1-2", "snapuid1-2", "snap1-2", "sid1-2", defaultClass, "", "volume-handle-1-2", retainPolicy, nil, &defaultSize, true),
5656
&crdv1.VolumeSnapshotContentStatus{SnapshotHandle: toStringPointer("snapuid1-2"), RestoreSize: &defaultSize, ReadyToUse: &True}),
57+
map[string]string{}),
5758
expectedEvents: noevents,
5859
expectedCreateCalls: []createCall{
5960
{

pkg/sidecar-controller/snapshot_controller.go

Lines changed: 51 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -323,25 +323,25 @@ func (ctrl *csiSnapshotSideCarController) createSnapshotOperation(content *crdv1
323323
}
324324

325325
// NOTE(xyang): handle create timeout
326-
// Add annotation and set to Yes to indicate create snapshot request is
326+
// Add annotation to indicate create snapshot request is
327327
// sent to the storage system and wait for a response of success or failure.
328-
// Annotation will be set to No only after storage system has responded
328+
// Annotation will be removed only after storage system has responded
329329
// with success or failure. If the request times out, retry will happen
330-
// and annotation will stay as Yes to avoid leaking of snapshot
330+
// and annotation will remain to avoid leaking of snapshot
331331
// resources on the storage system
332-
err = ctrl.setAnnVolumeSnapshotBeingCreated(content, utils.AnnVolumeSnapshotBeingCreated_Yes)
332+
err = ctrl.setAnnVolumeSnapshotBeingCreated(content)
333333
if err != nil {
334334
return nil, fmt.Errorf("failed to set VolumeSnapshotBeingCreated annotation to Yes on the content %s: %q", content.Name, err)
335335
}
336336

337337
driverName, snapshotID, creationTime, size, readyToUse, err := ctrl.handler.CreateSnapshot(content, class.Parameters, snapshotterCredentials)
338338
if err != nil {
339339
// NOTE(xyang): handle create timeout
340-
// If it is not a timeout error, set annotation to No to indicate
340+
// If it is not a timeout error, remove annotation to indicate
341341
// storage system has responded with an error
342342
errStr := fmt.Sprintf("%q", err)
343343
if !strings.Contains(errStr, "DeadlineExceeded") {
344-
err = ctrl.setAnnVolumeSnapshotBeingCreated(content, utils.AnnVolumeSnapshotBeingCreated_No)
344+
err = ctrl.removeAnnVolumeSnapshotBeingCreated(content)
345345
if err != nil {
346346
return nil, fmt.Errorf("failed to set VolumeSnapshotBeingCreated annotation to No on the content %s: %q", content.Name, err)
347347
}
@@ -353,14 +353,6 @@ func (ctrl *csiSnapshotSideCarController) createSnapshotOperation(content *crdv1
353353
return nil, fmt.Errorf("failed to take snapshot of the volume, %s: driver name %s returned from the driver is different from driver %s in snapshot class", *content.Spec.Source.VolumeHandle, driverName, class.Driver)
354354
}
355355

356-
// NOTE(xyang): handle create timeout
357-
// Set annotation to No to indicate storage system has successfully
358-
// cut the snapshot
359-
err = ctrl.setAnnVolumeSnapshotBeingCreated(content, utils.AnnVolumeSnapshotBeingCreated_No)
360-
if err != nil {
361-
return nil, fmt.Errorf("failed to set VolumeSnapshotBeingCreated annotation to No on the content %s: %q", content.Name, err)
362-
}
363-
364356
klog.V(5).Infof("Created snapshot: driver %s, snapshotId %s, creationTime %v, size %d, readyToUse %t", driverName, snapshotID, creationTime, size, readyToUse)
365357

366358
timestamp := creationTime.UnixNano()
@@ -372,6 +364,14 @@ func (ctrl *csiSnapshotSideCarController) createSnapshotOperation(content *crdv1
372364
content = newContent
373365
}
374366

367+
// NOTE(xyang): handle create timeout
368+
// Remove annotation to indicate storage system has successfully
369+
// cut the snapshot
370+
err = ctrl.removeAnnVolumeSnapshotBeingCreated(content)
371+
if err != nil {
372+
return nil, fmt.Errorf("failed to set VolumeSnapshotBeingCreated annotation to No on the content %s: %q", content.Name, err)
373+
}
374+
375375
// Update content in the cache store
376376
_, err = ctrl.storeContentUpdate(content)
377377
if err != nil {
@@ -598,10 +598,10 @@ func (ctrl *csiSnapshotSideCarController) shouldDelete(content *crdv1.VolumeSnap
598598

599599
// NOTE(xyang): Handle create snapshot timeout
600600
// 2) shouldDelete returns false if AnnVolumeSnapshotBeingCreated
601-
// annotation is set and its value is Yes. This indicates a
602-
// CreateSnapshot CSI RPC has not responded with success or failure.
601+
// annotation is set. This indicates a CreateSnapshot CSI RPC has
602+
// not responded with success or failure.
603603
// We need to keep waiting for a response from the CSI driver.
604-
if metav1.HasAnnotation(content.ObjectMeta, utils.AnnVolumeSnapshotBeingCreated) && content.ObjectMeta.Annotations[utils.AnnVolumeSnapshotBeingCreated] == utils.AnnVolumeSnapshotBeingCreated_Yes {
604+
if metav1.HasAnnotation(content.ObjectMeta, utils.AnnVolumeSnapshotBeingCreated) {
605605
return false
606606
}
607607

@@ -614,17 +614,15 @@ func (ctrl *csiSnapshotSideCarController) shouldDelete(content *crdv1.VolumeSnap
614614

615615
// setAnnVolumeSnapshotBeingCreated sets VolumeSnapshotBeingCreated annotation
616616
// on VolumeSnapshotContent
617-
// If beingCreated is true, it indicates snapshot is being created
618-
// If beingCreated if false, it indicates CreateSnapshot CSI RPC returns
619-
// success or failure
620-
func (ctrl *csiSnapshotSideCarController) setAnnVolumeSnapshotBeingCreated(content *crdv1.VolumeSnapshotContent, annBeingCreated string) error {
621-
// Set AnnVolumeSnapshotBeingCreated if it is not set yet or if it is
622-
// set but has a different value
623-
if !metav1.HasAnnotation(content.ObjectMeta, utils.AnnVolumeSnapshotBeingCreated) || content.ObjectMeta.Annotations[utils.AnnVolumeSnapshotBeingCreated] != annBeingCreated {
624-
klog.V(5).Infof("setAnnVolumeSnapshotBeingCreated: set annotation [%s:%s] on content [%s].", utils.AnnVolumeSnapshotBeingCreated, annBeingCreated, content.Name)
625-
metav1.SetMetaDataAnnotation(&content.ObjectMeta, utils.AnnVolumeSnapshotBeingCreated, annBeingCreated)
626-
627-
updateContent, err := ctrl.clientset.SnapshotV1beta1().VolumeSnapshotContents().Update(content)
617+
// If set, it indicates snapshot is being created
618+
func (ctrl *csiSnapshotSideCarController) setAnnVolumeSnapshotBeingCreated(content *crdv1.VolumeSnapshotContent) error {
619+
// Set AnnVolumeSnapshotBeingCreated if it is not set yet
620+
if !metav1.HasAnnotation(content.ObjectMeta, utils.AnnVolumeSnapshotBeingCreated) {
621+
klog.V(5).Infof("setAnnVolumeSnapshotBeingCreated: set annotation [%s:yes] on content [%s].", utils.AnnVolumeSnapshotBeingCreated, content.Name)
622+
contentClone := content.DeepCopy()
623+
metav1.SetMetaDataAnnotation(&contentClone.ObjectMeta, utils.AnnVolumeSnapshotBeingCreated, "yes")
624+
625+
updateContent, err := ctrl.clientset.SnapshotV1beta1().VolumeSnapshotContents().Update(contentClone)
628626
if err != nil {
629627
return newControllerUpdateError(content.Name, err.Error())
630628
}
@@ -640,3 +638,28 @@ func (ctrl *csiSnapshotSideCarController) setAnnVolumeSnapshotBeingCreated(conte
640638
}
641639
return nil
642640
}
641+
642+
// removeAnnVolumeSnapshotBeingCreated removes the VolumeSnapshotBeingCreated
643+
// annotation from a content if there exists one.
644+
func (ctrl csiSnapshotSideCarController) removeAnnVolumeSnapshotBeingCreated(content *crdv1.VolumeSnapshotContent) error {
645+
if !metav1.HasAnnotation(content.ObjectMeta, utils.AnnVolumeSnapshotBeingCreated) {
646+
// the annotation does not exit, return directly
647+
return nil
648+
}
649+
contentClone := content.DeepCopy()
650+
delete(contentClone.ObjectMeta.Annotations, utils.AnnVolumeSnapshotBeingCreated)
651+
652+
updateContent, err := ctrl.clientset.SnapshotV1beta1().VolumeSnapshotContents().Update(contentClone)
653+
if err != nil {
654+
return newControllerUpdateError(content.Name, err.Error())
655+
}
656+
// update content if update is successful
657+
content = updateContent
658+
659+
klog.V(5).Infof("Removed VolumeSnapshotBeingCreated annotation from volume snapshot content %s", content.Name)
660+
_, err = ctrl.storeContentUpdate(content)
661+
if err != nil {
662+
klog.Errorf("failed to update content store %v", err)
663+
}
664+
return nil
665+
}

pkg/utils/util.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,20 +79,16 @@ const (
7979
AnnVolumeSnapshotBeingDeleted = "snapshot.storage.kubernetes.io/volumesnapshot-being-deleted"
8080

8181
// AnnVolumeSnapshotBeingCreated annotation applies to VolumeSnapshotContents.
82-
// If it is set and value is "yes", it indicates that the csi-snapshotter
82+
// If it is set, it indicates that the csi-snapshotter
8383
// sidecar has sent the create snapshot request to the storage system and
8484
// is waiting for a response of success or failure.
85-
// This annotation will be set to "no" if the driver's CreateSnapshot
85+
// This annotation will be removed if the driver's CreateSnapshot
8686
// CSI function returns success or failure. If the create snapshot
87-
// request times out, retry will happen and the annotation value will
88-
// stay as "yes".
87+
// request times out, retry will happen and the annotation will remain.
8988
// This only applies to dynamic provisioning of snapshots because
9089
// the create snapshot CSI method will not be called for pre-provisioned
9190
// snapshots.
9291
AnnVolumeSnapshotBeingCreated = "snapshot.storage.kubernetes.io/volumesnapshot-being-created"
93-
// VolumeSnapshotBeingCreated annotation values can be "yes" or "no"
94-
AnnVolumeSnapshotBeingCreated_Yes = "yes"
95-
AnnVolumeSnapshotBeingCreated_No = "no"
9692

9793
// Annotation for secret name and namespace will be added to the content
9894
// and used at snapshot content deletion time.

0 commit comments

Comments
 (0)