Skip to content

Conversation

loktev-d
Copy link
Contributor

@loktev-d loktev-d commented Sep 1, 2025

Description

Fix the VirtualDisk controller to respect user-specified storageClassName when creating disks from VirtualDiskSnapshot. Previously, the controller was always using the storage class from the original disk (stored in VolumeSnapshot annotations), completely ignoring the user-specified value in spec.persistentVolumeClaim.storageClassName. Also add error message when user tries to perform cross-provider restore.

Why do we need it, and what problem does it solve?

When users tried to restore a VirtualDisk from a snapshot with a different storage class, the parameter spec.persistentVolumeClaim.storageClassName was silently ignored. The restored disk would always use the same storage class as the original disk.

What is the expected result?

Checklist

  • The code is covered by unit tests.
  • e2e tests passed.
  • Documentation updated according to the changes.
  • Changes were tested in the Kubernetes cluster manually.

Changelog entries

section: vd
type: fix
summary: respect user-specified storage class when restoring from snapshot

Signed-off-by: Daniil Loktev <[email protected]>
@loktev-d loktev-d marked this pull request as draft September 1, 2025 12:22
@loktev-d loktev-d added this to the v0.26.0 milestone Sep 1, 2025
@loktev-d loktev-d added the e2e/run Run e2e test on cluster of PR author label Sep 1, 2025
@deckhouse-BOaTswain
Copy link
Contributor

deckhouse-BOaTswain commented Sep 1, 2025

Workflow has started.
Follow the progress here: Workflow Run

The target step completed with status: failure.

@deckhouse-BOaTswain deckhouse-BOaTswain removed the e2e/run Run e2e test on cluster of PR author label Sep 1, 2025
@loktev-d loktev-d added the e2e/run Run e2e test on cluster of PR author label Sep 1, 2025
@deckhouse-BOaTswain
Copy link
Contributor

deckhouse-BOaTswain commented Sep 1, 2025

Workflow has started.
Follow the progress here: Workflow Run

The target step completed with status: failure.

@deckhouse-BOaTswain deckhouse-BOaTswain removed the e2e/run Run e2e test on cluster of PR author label Sep 1, 2025
@loktev-d loktev-d added the e2e/run Run e2e test on cluster of PR author label Sep 1, 2025
@deckhouse-BOaTswain
Copy link
Contributor

deckhouse-BOaTswain commented Sep 1, 2025

Workflow has started.
Follow the progress here: Workflow Run

The target step completed with status: success.

@deckhouse-BOaTswain deckhouse-BOaTswain removed the e2e/run Run e2e test on cluster of PR author label Sep 1, 2025
@loktev-d loktev-d marked this pull request as ready for review September 2, 2025 05:50
@nevermarine nevermarine modified the milestones: v1.0.0, v1.1.0 Sep 11, 2025
@loktev-d loktev-d marked this pull request as draft September 17, 2025 07:16
Signed-off-by: Daniil Loktev <[email protected]>
@loktev-d loktev-d added the e2e/run Run e2e test on cluster of PR author label Sep 17, 2025
@deckhouse-BOaTswain
Copy link
Contributor

deckhouse-BOaTswain commented Sep 17, 2025

Workflow has started.
Follow the progress here: Workflow Run

The target step completed with status: failure.

@deckhouse-BOaTswain deckhouse-BOaTswain removed the e2e/run Run e2e test on cluster of PR author label Sep 17, 2025
@loktev-d loktev-d added the e2e/run Run e2e test on cluster of PR author label Sep 18, 2025
@deckhouse-BOaTswain
Copy link
Contributor

deckhouse-BOaTswain commented Sep 18, 2025

Workflow has started.
Follow the progress here: Workflow Run

The target step completed with status: failure.

@deckhouse-BOaTswain deckhouse-BOaTswain removed the e2e/run Run e2e test on cluster of PR author label Sep 18, 2025
@loktev-d loktev-d added the e2e/run Run e2e test on cluster of PR author label Sep 18, 2025
@loktev-d loktev-d added the e2e/run Run e2e test on cluster of PR author label Sep 29, 2025
@deckhouse-BOaTswain
Copy link
Contributor

deckhouse-BOaTswain commented Sep 29, 2025

Workflow has started.
Follow the progress here: Workflow Run

The target step completed with status: failure.

@deckhouse-BOaTswain deckhouse-BOaTswain removed the e2e/run Run e2e test on cluster of PR author label Sep 29, 2025
@loktev-d loktev-d added the e2e/run Run e2e test on cluster of PR author label Sep 29, 2025
@deckhouse-BOaTswain
Copy link
Contributor

deckhouse-BOaTswain commented Sep 29, 2025

Workflow has started.
Follow the progress here: Workflow Run

The target step completed with status: failure.

@deckhouse-BOaTswain deckhouse-BOaTswain removed the e2e/run Run e2e test on cluster of PR author label Sep 29, 2025
@loktev-d loktev-d added the e2e/run Run e2e test on cluster of PR author label Sep 29, 2025
@deckhouse-BOaTswain deckhouse-BOaTswain removed the e2e/run Run e2e test on cluster of PR author label Sep 29, 2025
@loktev-d loktev-d added the e2e/run Run e2e test on cluster of PR author label Sep 30, 2025
@deckhouse-BOaTswain
Copy link
Contributor

deckhouse-BOaTswain commented Sep 30, 2025

Workflow has started.
Follow the progress here: Workflow Run

The target step completed with status: failure.

@deckhouse-BOaTswain deckhouse-BOaTswain removed the e2e/run Run e2e test on cluster of PR author label Sep 30, 2025
@loktev-d loktev-d marked this pull request as ready for review October 1, 2025 09:45
Copy link

sourcery-ai bot commented Oct 1, 2025

Reviewer's Guide

This PR updates the VirtualDisk controller to respect a user-specified storageClassName when restoring from a snapshot, adds a pre-flight compatibility check to prevent cross-provider restores, and introduces annotation constants for storage provisioner tracking.

Sequence diagram for VirtualDisk restore with user-specified storageClassName and compatibility check

sequenceDiagram
    participant User
    participant Controller
    participant KubernetesAPI
    participant StorageClass
    participant PVC
    participant VolumeSnapshot

    User->>Controller: Request restore VirtualDisk from snapshot
    Controller->>VolumeSnapshot: Fetch snapshot metadata
    Controller->>KubernetesAPI: Fetch user-specified StorageClass
    Controller->>KubernetesAPI: Fetch original PVC from snapshot
    Controller->>KubernetesAPI: Fetch original storage provisioner annotation
    Controller->>StorageClass: Compare provisioner with original
    alt Provisioners are compatible
        Controller->>PVC: Create PVC with user-specified storageClassName
        Controller->>User: Success event
    else Provisioners are incompatible
        Controller->>User: Error event (cross-provider restore not supported)
    end
Loading

Class diagram for CreatePVCFromVDSnapshotStep changes

classDiagram
    class CreatePVCFromVDSnapshotStep {
        +Take(ctx, vd)
        +AddOriginalMetadata(vd)
        +buildPVC(vd, vs)
        +validateStorageClassCompatibility(ctx, vd, vdSnapshot, vs)
    }
    class VirtualDisk {
        +Spec: PersistentVolumeClaimSpec
        +Status: DiskStatus
    }
    class PersistentVolumeClaimSpec {
        +StorageClass: string
    }
    class VirtualDiskSnapshot {
        +Namespace: string
    }
    class VolumeSnapshot {
        +Annotations: map[string]string
        +Spec: VolumeSnapshotSpec
    }
    class StorageClass {
        +Provisioner: string
    }
    class PersistentVolumeClaim {
        +Annotations: map[string]string
    }
    CreatePVCFromVDSnapshotStep --> VirtualDisk
    CreatePVCFromVDSnapshotStep --> VirtualDiskSnapshot
    CreatePVCFromVDSnapshotStep --> VolumeSnapshot
    CreatePVCFromVDSnapshotStep --> StorageClass
    CreatePVCFromVDSnapshotStep --> PersistentVolumeClaim
Loading

Class diagram for new annotation constants in annotations.go

classDiagram
    class Annotations {
        +AnnStorageProvisioner: string
        +AnnStorageProvisionerDeprecated: string
    }
Loading

File-Level Changes

Change Details Files
Support user-specified storageClassName when building PVCs
  • Prefer spec.PersistentVolumeClaim.StorageClass over snapshot annotation
  • Fallback to existing annotation values when not specified
create_pvc_from_vdsnapshot_step.go
Validate storage class compatibility before PVC creation
  • Invoke validateStorageClassCompatibility in Take() with error handling and event recording
  • Fetch target StorageClass and original PVC, compare provisioners, and return error on mismatch
create_pvc_from_vdsnapshot_step.go
Add annotation constants for storage provisioner
  • Introduce AnnStorageProvisioner and AnnStorageProvisionerDeprecated entries
annotations/annotations.go

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there - I've reviewed your changes - here's some feedback:

  • In validateStorageClassCompatibility, add a nil check for vs.Spec.Source.PersistentVolumeClaimName before dereferencing it to avoid potential panics when the snapshot source isn’t a PVC.
  • Consider extracting the repeated annotation-reading logic (storageClassName, provisioner, volumeMode, etc.) into a shared helper to reduce duplication between buildPVC and compatibility validation.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In validateStorageClassCompatibility, add a nil check for vs.Spec.Source.PersistentVolumeClaimName before dereferencing it to avoid potential panics when the snapshot source isn’t a PVC.
- Consider extracting the repeated annotation-reading logic (storageClassName, provisioner, volumeMode, etc.) into a shared helper to reduce duplication between buildPVC and compatibility validation.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

hardcoretime
hardcoretime previously approved these changes Oct 1, 2025
Signed-off-by: Daniil Loktev <[email protected]>
loktev-d and others added 3 commits October 2, 2025 14:51
Signed-off-by: Daniil Loktev <[email protected]>
Signed-off-by: Daniil Loktev <[email protected]>
@loktev-d loktev-d added the e2e/run Run e2e test on cluster of PR author label Oct 2, 2025
@deckhouse-BOaTswain
Copy link
Contributor

deckhouse-BOaTswain commented Oct 2, 2025

Workflow has started.
Follow the progress here: Workflow Run

The target step completed with status: failure.

@deckhouse-BOaTswain deckhouse-BOaTswain removed the e2e/run Run e2e test on cluster of PR author label Oct 2, 2025
@loktev-d loktev-d merged commit 55e2188 into main Oct 6, 2025
27 of 28 checks passed
@loktev-d loktev-d deleted the fix/vd/use-specified-storage-class-from-snapshot branch October 6, 2025 10:46
This was referenced Oct 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants