Skip to content

Commit 7c1c530

Browse files
committed
Set VolumeHandle for dynamic provisioned VolumeGroupSnapshots
1 parent a7443c7 commit 7c1c530

File tree

3 files changed

+76
-17
lines changed

3 files changed

+76
-17
lines changed

pkg/common-controller/groupsnapshot_controller_helper.go

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,12 @@ func (ctrl *csiSnapshotCommonController) createSnapshotsForGroupSnapshotContent(
504504
return groupSnapshotContent, nil
505505
}
506506

507+
// No volume group snapshot handle is present.
508+
// Let's wait for the snapshotter sidecar to fill it.
509+
if groupSnapshotContent.Status.VolumeGroupSnapshotHandle == nil {
510+
return groupSnapshotContent, nil
511+
}
512+
507513
// The contents of the volume group snapshot class are needed to set the
508514
// metadata containing the secrets to recover the snapshots
509515
if groupSnapshot.Spec.VolumeGroupSnapshotClassName == nil {
@@ -561,6 +567,9 @@ func (ctrl *csiSnapshotCommonController) createSnapshotsForGroupSnapshotContent(
561567
volumeSnapshotContent := &crdv1.VolumeSnapshotContent{
562568
ObjectMeta: metav1.ObjectMeta{
563569
Name: volumeSnapshotContentName,
570+
Labels: map[string]string{
571+
utils.VolumeGroupSnapshotHandleLabel: *groupSnapshotContent.Status.VolumeGroupSnapshotHandle,
572+
},
564573
},
565574
Spec: crdv1.VolumeSnapshotContentSpec{
566575
VolumeSnapshotRef: v1.ObjectReference{
@@ -571,7 +580,7 @@ func (ctrl *csiSnapshotCommonController) createSnapshotsForGroupSnapshotContent(
571580
DeletionPolicy: groupSnapshotContent.Spec.DeletionPolicy,
572581
Driver: groupSnapshotContent.Spec.Driver,
573582
Source: crdv1.VolumeSnapshotContentSource{
574-
SnapshotHandle: &snapshotHandle,
583+
VolumeHandle: &volumeHandle,
575584
},
576585
},
577586
// The status will be set by VolumeSnapshotContent reconciler
@@ -590,24 +599,28 @@ func (ctrl *csiSnapshotCommonController) createSnapshotsForGroupSnapshotContent(
590599
metav1.SetMetaDataAnnotation(&volumeSnapshotContent.ObjectMeta, utils.AnnDeletionSecretRefNamespace, groupSnapshotSecret.Namespace)
591600
}
592601

593-
label := make(map[string]string)
594-
label[utils.VolumeGroupSnapshotNameLabel] = groupSnapshotContent.Spec.VolumeGroupSnapshotRef.Name
595602
volumeSnapshot := &crdv1.VolumeSnapshot{
596603
ObjectMeta: metav1.ObjectMeta{
597-
Name: volumeSnapshotName,
598-
Namespace: volumeSnapshotNamespace,
599-
Labels: label,
600-
Finalizers: []string{utils.VolumeSnapshotInGroupFinalizer},
601-
},
602-
Spec: crdv1.VolumeSnapshotSpec{
603-
Source: crdv1.VolumeSnapshotSource{
604-
PersistentVolumeClaimName: &pv.Spec.ClaimRef.Name,
604+
Name: volumeSnapshotName,
605+
Namespace: volumeSnapshotNamespace,
606+
Labels: map[string]string{
607+
utils.VolumeGroupSnapshotNameLabel: groupSnapshotContent.Spec.VolumeGroupSnapshotRef.Name,
605608
},
609+
Finalizers: []string{utils.VolumeSnapshotInGroupFinalizer},
606610
},
611+
// The spec stanza is set immediately
607612
// The status will be set by VolumeSnapshot reconciler
608613
}
609614

610-
_, err = ctrl.clientset.SnapshotV1().VolumeSnapshotContents().Create(ctx, volumeSnapshotContent, metav1.CreateOptions{})
615+
if pv != nil {
616+
volumeSnapshot.Spec.Source.PersistentVolumeClaimName = &pv.Spec.ClaimRef.Name
617+
} else {
618+
// If no persistent volume was found, set the PVC name to empty
619+
var emptyString string
620+
volumeSnapshot.Spec.Source.PersistentVolumeClaimName = &emptyString
621+
}
622+
623+
createdVolumeSnapshotContent, err := ctrl.clientset.SnapshotV1().VolumeSnapshotContents().Create(ctx, volumeSnapshotContent, metav1.CreateOptions{})
611624
if err != nil && !apierrs.IsAlreadyExists(err) {
612625
return groupSnapshotContent, fmt.Errorf(
613626
"createSnapshotsForGroupSnapshotContent: creating volumesnapshotcontent %w", err)
@@ -663,6 +676,32 @@ func (ctrl *csiSnapshotCommonController) createSnapshotsForGroupSnapshotContent(
663676
return groupSnapshotContent, fmt.Errorf(
664677
"createSnapshotsForGroupSnapshotContent: binding volumesnapshot to volumesnapshotcontent %w", err)
665678
}
679+
680+
// set the snapshot handle and the group snapshot handle
681+
// inside the volume snapshot content to allow
682+
// the CSI Snapshotter sidecar to reconcile its status
683+
_, err = utils.PatchVolumeSnapshotContent(createdVolumeSnapshotContent, []utils.PatchOp{
684+
{
685+
Op: "replace",
686+
Path: "/status",
687+
Value: &crdv1.VolumeSnapshotContentStatus{},
688+
},
689+
{
690+
Op: "replace",
691+
Path: "/status/snapshotHandle",
692+
Value: snapshotHandle,
693+
},
694+
{
695+
Op: "replace",
696+
Path: "/status/volumeGroupSnapshotHandle",
697+
Value: groupSnapshotContent.Status.VolumeGroupSnapshotHandle,
698+
},
699+
}, ctrl.clientset, "status")
700+
if err != nil {
701+
return groupSnapshotContent, fmt.Errorf(
702+
"createSnapshotsForGroupSnapshotContent: setting snapshotHandle in volumesnapshotcontent %w", err)
703+
}
704+
666705
}
667706

668707
// Phase 2: set the backlinks

pkg/sidecar-controller/snapshot_controller.go

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,15 @@ func (ctrl *csiSnapshotSideCarController) syncContent(content *crdv1.VolumeSnaps
8383
return false, nil
8484

8585
}
86-
if content.Spec.Source.VolumeHandle != nil && content.Status == nil {
86+
87+
// Create snapshot calling the CSI driver only if it is a dynamic
88+
// provisioning for an independent snapshot.
89+
_, groupSnapshotMember := content.Labels[utils.VolumeGroupSnapshotHandleLabel]
90+
if content.Spec.Source.VolumeHandle != nil && content.Status == nil && !groupSnapshotMember {
8791
klog.V(5).Infof("syncContent: Call CreateSnapshot for content %s", content.Name)
8892
return ctrl.createSnapshot(content)
8993
}
94+
9095
// Skip checkandUpdateContentStatus() if ReadyToUse is
9196
// already true. We don't want to keep calling CreateSnapshot
9297
// or ListSnapshots CSI methods over and over again for
@@ -253,11 +258,13 @@ func (ctrl *csiSnapshotSideCarController) checkandUpdateContentStatusOperation(c
253258
var size int64
254259
readyToUse := false
255260
var driverName string
256-
var snapshotID, groupSnapshotID string
261+
var groupSnapshotID string
257262
var snapshotterListCredentials map[string]string
258263

259-
if content.Spec.Source.SnapshotHandle != nil {
260-
klog.V(5).Infof("checkandUpdateContentStatusOperation: call GetSnapshotStatus for snapshot which is pre-bound to content [%s]", content.Name)
264+
volumeGroupSnapshotMember := content.Status != nil && content.Status.VolumeGroupSnapshotHandle != nil
265+
266+
if content.Spec.Source.SnapshotHandle != nil || (volumeGroupSnapshotMember && content.Status.SnapshotHandle != nil) {
267+
klog.V(5).Infof("checkandUpdateContentStatusOperation: call GetSnapshotStatus for snapshot content [%s]", content.Name)
261268

262269
if content.Spec.VolumeSnapshotClassName != nil {
263270
class, err := ctrl.getSnapshotClass(*content.Spec.VolumeSnapshotClassName)
@@ -286,7 +293,13 @@ func (ctrl *csiSnapshotSideCarController) checkandUpdateContentStatusOperation(c
286293
return content, err
287294
}
288295
driverName = content.Spec.Driver
289-
snapshotID = *content.Spec.Source.SnapshotHandle
296+
297+
var snapshotID string
298+
if content.Spec.Source.SnapshotHandle != nil {
299+
snapshotID = *content.Spec.Source.SnapshotHandle
300+
} else {
301+
snapshotID = *content.Status.SnapshotHandle
302+
}
290303

291304
klog.V(5).Infof("checkandUpdateContentStatusOperation: driver %s, snapshotId %s, creationTime %v, size %d, readyToUse %t, groupSnapshotID %s", driverName, snapshotID, creationTime, size, readyToUse, groupSnapshotID)
292305

pkg/utils/util.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,13 @@ const (
150150
// of a VolumeGroupSnapshot, and indicates the name of the latter.
151151
VolumeGroupSnapshotNameLabel = "groupsnapshot.storage.k8s.io/volumeGroupSnapshotName"
152152

153+
// VolumeGroupSnapshotHandleLabel is applied to VolumeSnapshotContents that are member
154+
// of a VolumeGroupSnapshotContent, and indicates the handle of the latter.
155+
//
156+
// This label is applied to inform the sidecar not to call CSI driver
157+
// to create snapshot if the snapshot belongs to a group.
158+
VolumeGroupSnapshotHandleLabel = "groupsnapshot.storage.k8s.io/volumeGroupSnapshotHandle"
159+
153160
// VolumeSnapshotContentInvalidLabel is applied to invalid content as a label key. The value does not matter.
154161
// See https://github.com/kubernetes/enhancements/blob/master/keps/sig-storage/177-volume-snapshot/tighten-validation-webhook-crd.md#automatic-labelling-of-invalid-objects
155162
VolumeSnapshotContentInvalidLabel = "snapshot.storage.kubernetes.io/invalid-snapshot-content-resource"

0 commit comments

Comments
 (0)