From 8678ea28ee0910e8b84665fe0bd6ebd7238d119b Mon Sep 17 00:00:00 2001 From: Felix Prasse <1330854+flx5@users.noreply.github.com> Date: Thu, 22 May 2025 21:05:24 +0200 Subject: [PATCH] Keep manager label for VSC If distributed snapshotting is enabled in the external snapshotter a manager label is added to the volume snapshot content. When exposing the snapshot velero needs to keep this label around otherwise the exposed snapshot will never become ready. Signed-off-by: Felix Prasse <1330854+flx5@users.noreply.github.com> --- changelogs/unreleased/8969-flx5 | 1 + pkg/exposer/csi_snapshot.go | 12 ++++++++++++ pkg/exposer/csi_snapshot_test.go | 24 ++++++++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 changelogs/unreleased/8969-flx5 diff --git a/changelogs/unreleased/8969-flx5 b/changelogs/unreleased/8969-flx5 new file mode 100644 index 000000000..683f437a4 --- /dev/null +++ b/changelogs/unreleased/8969-flx5 @@ -0,0 +1 @@ +Add support for [distributed snapshotting](https://github.com/kubernetes-csi/external-snapshotter/tree/4cedb3f45790ac593ebfa3324c490abedf739477?tab=readme-ov-file#distributed-snapshotting) \ No newline at end of file diff --git a/pkg/exposer/csi_snapshot.go b/pkg/exposer/csi_snapshot.go index bee42a61c..9fb4e42e0 100644 --- a/pkg/exposer/csi_snapshot.go +++ b/pkg/exposer/csi_snapshot.go @@ -446,6 +446,7 @@ func (e *csiSnapshotExposer) createBackupVSC(ctx context.Context, ownerObject co ObjectMeta: metav1.ObjectMeta{ Name: backupVSCName, Annotations: snapshotVSC.Annotations, + Labels: map[string]string{}, }, Spec: snapshotv1api.VolumeSnapshotContentSpec{ VolumeSnapshotRef: corev1api.ObjectReference{ @@ -463,6 +464,17 @@ func (e *csiSnapshotExposer) createBackupVSC(ctx context.Context, ownerObject co }, } + /* + We need to keep the label of the managing node for distributed snapshots. + The external snapshot manager will only manage snapshots matching it's node if that feature is enabled. + + https://github.com/kubernetes-csi/external-snapshotter/tree/4cedb3f45790ac593ebfa3324c490abedf739477?tab=readme-ov-file#distributed-snapshotting + https://github.com/kubernetes-csi/external-snapshotter/blob/4cedb3f45790ac593ebfa3324c490abedf739477/pkg/utils/util.go#L158 + */ + if manager, ok := snapshotVSC.Labels["snapshot.storage.kubernetes.io/managed-by"]; ok { + vsc.ObjectMeta.Labels["snapshot.storage.kubernetes.io/managed-by"] = manager + } + return e.csiSnapshotClient.VolumeSnapshotContents().Create(ctx, vsc, metav1.CreateOptions{}) } diff --git a/pkg/exposer/csi_snapshot_test.go b/pkg/exposer/csi_snapshot_test.go index 223a85773..09fb91ff2 100644 --- a/pkg/exposer/csi_snapshot_test.go +++ b/pkg/exposer/csi_snapshot_test.go @@ -129,6 +129,11 @@ func TestExpose(t *testing.T) { }, } + vscObjWithLabels := vscObj + vscObjWithLabels.Labels = map[string]string{ + "snapshot.storage.kubernetes.io/managed-by": "worker", + } + daemonSet := &appsv1api.DaemonSet{ ObjectMeta: metav1.ObjectMeta{ Namespace: "velero", @@ -370,6 +375,24 @@ func TestExpose(t *testing.T) { daemonSet, }, }, + { + name: "success-with-labels", + ownerBackup: backup, + exposeParam: CSISnapshotExposeParam{ + SnapshotName: "fake-vs", + SourceNamespace: "fake-ns", + AccessMode: AccessModeFileSystem, + OperationTimeout: time.Millisecond, + ExposeTimeout: time.Millisecond, + }, + snapshotClientObj: []runtime.Object{ + vsObject, + vscObjWithLabels, + }, + kubeClientObj: []runtime.Object{ + daemonSet, + }, + }, { name: "restore size from exposeParam", ownerBackup: backup, @@ -650,6 +673,7 @@ func TestExpose(t *testing.T) { assert.Equal(t, expectedVSC.Name, *expectedVS.Spec.Source.VolumeSnapshotContentName) assert.Equal(t, expectedVSC.Annotations, vscObj.Annotations) + assert.Equal(t, expectedVSC.Labels, vscObj.Labels) assert.Equal(t, expectedVSC.Spec.DeletionPolicy, vscObj.Spec.DeletionPolicy) assert.Equal(t, expectedVSC.Spec.Driver, vscObj.Spec.Driver) assert.Equal(t, *expectedVSC.Spec.VolumeSnapshotClassName, *vscObj.Spec.VolumeSnapshotClassName)