Skip to content

Commit d37087c

Browse files
authored
Merge pull request kubernetes-csi#1198 from leonardoce/set-volumehandle
Set VolumeHandle for dynamically provisioned VolumeGroupSnapshots
2 parents 9cb9f0f + 7c1c530 commit d37087c

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 {
@@ -557,6 +563,9 @@ func (ctrl *csiSnapshotCommonController) createSnapshotsForGroupSnapshotContent(
557563
volumeSnapshotContent := &crdv1.VolumeSnapshotContent{
558564
ObjectMeta: metav1.ObjectMeta{
559565
Name: volumeSnapshotContentName,
566+
Labels: map[string]string{
567+
utils.VolumeGroupSnapshotHandleLabel: *groupSnapshotContent.Status.VolumeGroupSnapshotHandle,
568+
},
560569
},
561570
Spec: crdv1.VolumeSnapshotContentSpec{
562571
VolumeSnapshotRef: v1.ObjectReference{
@@ -567,7 +576,7 @@ func (ctrl *csiSnapshotCommonController) createSnapshotsForGroupSnapshotContent(
567576
DeletionPolicy: groupSnapshotContent.Spec.DeletionPolicy,
568577
Driver: groupSnapshotContent.Spec.Driver,
569578
Source: crdv1.VolumeSnapshotContentSource{
570-
SnapshotHandle: &snapshotHandle,
579+
VolumeHandle: &volumeHandle,
571580
},
572581
},
573582
// The status will be set by VolumeSnapshotContent reconciler
@@ -586,24 +595,28 @@ func (ctrl *csiSnapshotCommonController) createSnapshotsForGroupSnapshotContent(
586595
metav1.SetMetaDataAnnotation(&volumeSnapshotContent.ObjectMeta, utils.AnnDeletionSecretRefNamespace, groupSnapshotSecret.Namespace)
587596
}
588597

589-
label := make(map[string]string)
590-
label[utils.VolumeGroupSnapshotNameLabel] = groupSnapshotContent.Spec.VolumeGroupSnapshotRef.Name
591598
volumeSnapshot := &crdv1.VolumeSnapshot{
592599
ObjectMeta: metav1.ObjectMeta{
593-
Name: volumeSnapshotName,
594-
Namespace: volumeSnapshotNamespace,
595-
Labels: label,
596-
Finalizers: []string{utils.VolumeSnapshotInGroupFinalizer},
597-
},
598-
Spec: crdv1.VolumeSnapshotSpec{
599-
Source: crdv1.VolumeSnapshotSource{
600-
PersistentVolumeClaimName: &pv.Spec.ClaimRef.Name,
600+
Name: volumeSnapshotName,
601+
Namespace: volumeSnapshotNamespace,
602+
Labels: map[string]string{
603+
utils.VolumeGroupSnapshotNameLabel: groupSnapshotContent.Spec.VolumeGroupSnapshotRef.Name,
601604
},
605+
Finalizers: []string{utils.VolumeSnapshotInGroupFinalizer},
602606
},
607+
// The spec stanza is set immediately
603608
// The status will be set by VolumeSnapshot reconciler
604609
}
605610

606-
_, err = ctrl.clientset.SnapshotV1().VolumeSnapshotContents().Create(ctx, volumeSnapshotContent, metav1.CreateOptions{})
611+
if pv != nil {
612+
volumeSnapshot.Spec.Source.PersistentVolumeClaimName = &pv.Spec.ClaimRef.Name
613+
} else {
614+
// If no persistent volume was found, set the PVC name to empty
615+
var emptyString string
616+
volumeSnapshot.Spec.Source.PersistentVolumeClaimName = &emptyString
617+
}
618+
619+
createdVolumeSnapshotContent, err := ctrl.clientset.SnapshotV1().VolumeSnapshotContents().Create(ctx, volumeSnapshotContent, metav1.CreateOptions{})
607620
if err != nil && !apierrs.IsAlreadyExists(err) {
608621
return groupSnapshotContent, fmt.Errorf(
609622
"createSnapshotsForGroupSnapshotContent: creating volumesnapshotcontent %w", err)
@@ -648,6 +661,32 @@ func (ctrl *csiSnapshotCommonController) createSnapshotsForGroupSnapshotContent(
648661
return groupSnapshotContent, fmt.Errorf(
649662
"createSnapshotsForGroupSnapshotContent: binding volumesnapshot to volumesnapshotcontent %w", err)
650663
}
664+
665+
// set the snapshot handle and the group snapshot handle
666+
// inside the volume snapshot content to allow
667+
// the CSI Snapshotter sidecar to reconcile its status
668+
_, err = utils.PatchVolumeSnapshotContent(createdVolumeSnapshotContent, []utils.PatchOp{
669+
{
670+
Op: "replace",
671+
Path: "/status",
672+
Value: &crdv1.VolumeSnapshotContentStatus{},
673+
},
674+
{
675+
Op: "replace",
676+
Path: "/status/snapshotHandle",
677+
Value: snapshotHandle,
678+
},
679+
{
680+
Op: "replace",
681+
Path: "/status/volumeGroupSnapshotHandle",
682+
Value: groupSnapshotContent.Status.VolumeGroupSnapshotHandle,
683+
},
684+
}, ctrl.clientset, "status")
685+
if err != nil {
686+
return groupSnapshotContent, fmt.Errorf(
687+
"createSnapshotsForGroupSnapshotContent: setting snapshotHandle in volumesnapshotcontent %w", err)
688+
}
689+
651690
}
652691

653692
return groupSnapshotContent, nil

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)