@@ -18,6 +18,7 @@ package vd
1818
1919import (
2020 "context"
21+ "errors"
2122 "fmt"
2223 "log/slog"
2324
@@ -27,6 +28,7 @@ import (
2728 "sigs.k8s.io/controller-runtime/pkg/client"
2829
2930 "github.com/deckhouse/virtualization-controller/pkg/common/object"
31+ "github.com/deckhouse/virtualization-controller/pkg/controller/service"
3032 "github.com/deckhouse/virtualization-controller/pkg/featuregates"
3133 "github.com/deckhouse/virtualization/api/core/v1alpha2"
3234)
@@ -75,6 +77,53 @@ func StorageClassChanged(vd *v1alpha2.VirtualDisk) bool {
7577 return * specSc != "" && statusSc != ""
7678}
7779
80+ type VirtualDiskStorageClassResolver interface {
81+ GetModuleStorageClass (ctx context.Context ) (* storagev1.StorageClass , error )
82+ GetDefaultStorageClass (ctx context.Context ) (* storagev1.StorageClass , error )
83+ }
84+
85+ // ResolveStorageClassName resolves storage class name for a VirtualDisk
86+ // with the same precedence as VD handlers:
87+ // 1. vd.Status.StorageClassName
88+ // 2. vd.Spec.PersistentVolumeClaim.StorageClass
89+ // 3. module default storage class (if resolver is provided)
90+ // 4. cluster default storage class (if resolver is provided)
91+ func ResolveStorageClassName (ctx context.Context , vd * v1alpha2.VirtualDisk , resolver VirtualDiskStorageClassResolver ) (string , error ) {
92+ if vd == nil {
93+ return "" , nil
94+ }
95+
96+ if vd .Status .StorageClassName != "" {
97+ return vd .Status .StorageClassName , nil
98+ }
99+
100+ if vd .Spec .PersistentVolumeClaim .StorageClass != nil && * vd .Spec .PersistentVolumeClaim .StorageClass != "" {
101+ return * vd .Spec .PersistentVolumeClaim .StorageClass , nil
102+ }
103+
104+ if resolver == nil {
105+ return "" , nil
106+ }
107+
108+ moduleStorageClass , err := resolver .GetModuleStorageClass (ctx )
109+ if err != nil {
110+ return "" , err
111+ }
112+ if moduleStorageClass != nil {
113+ return moduleStorageClass .Name , nil
114+ }
115+
116+ defaultStorageClass , err := resolver .GetDefaultStorageClass (ctx )
117+ if err != nil && ! errors .Is (err , service .ErrDefaultStorageClassNotFound ) {
118+ return "" , err
119+ }
120+ if defaultStorageClass != nil {
121+ return defaultStorageClass .Name , nil
122+ }
123+
124+ return "" , fmt .Errorf ("storage class for VirtualDisk %q cannot be determined" , vd .Name )
125+ }
126+
78127func ValidateVirtualImageStorageClassProvisionerCompatibility (ctx context.Context , vd * v1alpha2.VirtualDisk , client client.Client ) error {
79128 if vd .Spec .DataSource == nil || vd .Spec .DataSource .Type != v1alpha2 .DataSourceTypeObjectRef {
80129 return nil
0 commit comments