Repository: kubernetes/kubernetes
File: test/e2e/storage/framework/volume_group_snapshot_resource.go (Go)

Code before:

	contentNamesSet := sets.New[string]()
	for _, vs := range vss.Items {
		for _, owner := range vs.GetOwnerReferences() {
			if owner.Kind == "VolumeGroupSnapshot" && owner.UID == vgsUID {
				if status, ok := vs.Object["status"].(map[string]interface{}); ok {
					if cName, ok := status["boundVolumeSnapshotContentName"].(string); ok && cName != "" {
						contentNamesSet.Insert(cName)
					}
				}
			}
		}
	}
	return contentNamesSet, nil
}

// cleanupRetainedVolumeSnapshotContents forcibly deletes VolumeSnapshotContents with Retain policy
func (r *VolumeGroupSnapshotResource) cleanupRetainedVolumeSnapshotContents(ctx context.Context, dc dynamic.Interface, contentNames sets.Set[string], timeouts *framework.TimeoutContext) {
	// Update deletion policy and delete each VolumeSnapshotContent
	for _, contentName := range contentNames.UnsortedList() {
		vsc, err := dc.Resource(utils.SnapshotContentGVR).Get(ctx, contentName, metav1.GetOptions{})
		if err != nil {
			if !apierrors.IsNotFound(err) {
				framework.Logf("Warning: failed to get VolumeSnapshotContent %q: %v", contentName, err)
			}
			continue
		}

		// Update deletion policy to Delete
		vscSpec := vsc.Object["spec"].(map[string]interface{})
		vscSpec["deletionPolicy"] = "Delete"
		_, err = dc.Resource(utils.SnapshotContentGVR).Update(ctx, vsc, metav1.UpdateOptions{})
		if err != nil && !apierrors.IsNotFound(err) {
			framework.Logf("Warning: failed to update VolumeSnapshotContent %q deletion policy: %v", contentName, err)
		}

		// Delete VolumeSnapshotContent
		err = dc.Resource(utils.SnapshotContentGVR).Delete(ctx, contentName, metav1.DeleteOptions{})
		if err != nil && !apierrors.IsNotFound(err) {
			framework.Logf("Warning: failed to delete VolumeSnapshotContent %q: %v", contentName, err)
		}
	}

	// Wait for all VolumeSnapshotContents to be deleted
	framework.Logf("Waiting for VolumeSnapshotContents to be deleted")
	for _, contentName := range contentNames.UnsortedList() {
		if err := utils.WaitForGVRDeletion(ctx, dc, utils.SnapshotContentGVR, contentName, framework.Poll, timeouts.SnapshotDelete); err != nil {
			framework.Logf("Warning: VolumeSnapshotContent %q may not be fully deleted: %v", contentName, err)
		}
	}
}

Review comment (bug):
Please throw an error + return. We expect the content to exist and it's a bug somewhere if it does not,

Code after:

	contentNamesSet := sets.New[string]()
	for _, vs := range vss.Items {
		for _, owner := range vs.GetOwnerReferences() {
			if owner.Kind == "VolumeGroupSnapshot" && owner.UID == vgsUID {
				if status, ok := vs.Object["status"].(map[string]interface{}); ok {
					if cName, ok := status["boundVolumeSnapshotContentName"].(string); ok && cName != "" {
						contentNamesSet.Insert(cName)
					}
				}
			}
		}
	}
	return contentNamesSet, nil
}

// cleanupRetainedVolumeSnapshotContents forcibly deletes VolumeSnapshotContents with Retain policy
func (r *VolumeGroupSnapshotResource) cleanupRetainedVolumeSnapshotContents(ctx context.Context, dc dynamic.Interface, contentNames sets.Set[string], timeouts *framework.TimeoutContext) {
	// Update deletion policy and delete each VolumeSnapshotContent
	for _, contentName := range contentNames.UnsortedList() {
		// Patch deletion policy to Delete
		patchData := []byte(`{"spec":{"deletionPolicy":"Delete"}}`)
		_, err := dc.Resource(utils.SnapshotContentGVR).Patch(ctx, contentName, types.MergePatchType, patchData, metav1.PatchOptions{})
		if err != nil {
			framework.Failf("Failed to patch VolumeSnapshotContent %q deletion policy: %v", contentName, err)
			return
		}

		// Delete VolumeSnapshotContent
		err = dc.Resource(utils.SnapshotContentGVR).Delete(ctx, contentName, metav1.DeleteOptions{})
		if err != nil {
			framework.Failf("Failed to delete VolumeSnapshotContent %q: %v", contentName, err)
			return
		}
	}

	// Wait for all VolumeSnapshotContents to be deleted
	framework.Logf("Waiting for VolumeSnapshotContents to be deleted")
	for _, contentName := range contentNames.UnsortedList() {
		if err := utils.WaitForGVRDeletion(ctx, dc, utils.SnapshotContentGVR, contentName, framework.Poll, timeouts.SnapshotDelete); err != nil {
			framework.Failf("VolumeSnapshotContent %q was not fully deleted: %v", contentName, err)
			return
		}
	}
}

// cleanupRetainedVGSContent forcibly deletes VolumeGroupSnapshotContent with Retain policy
func (r *VolumeGroupSnapshotResource) cleanupRetainedVGSContent(ctx context.Context, dc dynamic.Interface, vgscName string, timeouts *framework.TimeoutContext) {
	framework.Logf("Deleting VGSContent %q", vgscName)

	// Patch deletion policy to Delete