@@ -17,7 +17,6 @@ limitations under the License.
1717package service
1818
1919import (
20- "cmp"
2120 "context"
2221 "errors"
2322 "fmt"
@@ -43,6 +42,7 @@ import (
4342 "github.com/deckhouse/virtualization-controller/pkg/common/pointer"
4443 "github.com/deckhouse/virtualization-controller/pkg/controller/conditions"
4544 "github.com/deckhouse/virtualization-controller/pkg/controller/kvbuilder"
45+ "github.com/deckhouse/virtualization-controller/pkg/controller/service/volumemode"
4646 "github.com/deckhouse/virtualization-controller/pkg/controller/supplements"
4747 "github.com/deckhouse/virtualization-controller/pkg/dvcr"
4848 "github.com/deckhouse/virtualization/api/core/v1alpha2"
@@ -53,6 +53,8 @@ type DiskService struct {
5353 dvcrSettings * dvcr.Settings
5454 protection * ProtectionService
5555 controllerName string
56+
57+ volumeAndAccessModesGetter volumemode.VolumeAndAccessModesGetter
5658}
5759
5860func NewDiskService (
@@ -62,10 +64,11 @@ func NewDiskService(
6264 controllerName string ,
6365) * DiskService {
6466 return & DiskService {
65- client : client ,
66- dvcrSettings : dvcrSettings ,
67- protection : protection ,
68- controllerName : controllerName ,
67+ client : client ,
68+ dvcrSettings : dvcrSettings ,
69+ protection : protection ,
70+ controllerName : controllerName ,
71+ volumeAndAccessModesGetter : volumemode .NewVolumeAndAccessModesGetter (client , nil ),
6972 }
7073}
7174
@@ -125,54 +128,7 @@ func (s DiskService) Start(
125128}
126129
127130func (s DiskService ) GetVolumeAndAccessModes (ctx context.Context , obj client.Object , sc * storagev1.StorageClass ) (corev1.PersistentVolumeMode , corev1.PersistentVolumeAccessMode , error ) {
128- if obj == nil {
129- return "" , "" , errors .New ("object is nil" )
130- }
131- if sc == nil {
132- return "" , "" , errors .New ("storage class is nil" )
133- }
134-
135- // Priority: object > storage class > storage profile.
136-
137- // 1. Get modes from annotations on the object.
138- accessMode , _ := s .parseAccessMode (obj )
139- volumeMode , _ := s .parseVolumeMode (obj )
140-
141- if accessMode != "" && volumeMode != "" {
142- return volumeMode , accessMode , nil
143- }
144-
145- // 2. Get modes from annotations on the storage class.
146- if m , exists := s .parseAccessMode (sc ); accessMode == "" && exists {
147- accessMode = m
148- }
149- if m , exists := s .parseVolumeMode (sc ); volumeMode == "" && exists {
150- volumeMode = m
151- }
152-
153- if accessMode != "" && volumeMode != "" {
154- return volumeMode , accessMode , nil
155- }
156-
157- // 3. Get modes from storage profile.
158- storageProfile , err := s .GetStorageProfile (ctx , sc .Name )
159- if err != nil {
160- return "" , "" , fmt .Errorf ("get storage profile: %w" , err )
161- }
162-
163- if storageProfile == nil {
164- return "" , "" , fmt .Errorf ("storage profile %q not found: %w" , sc .Name , ErrStorageProfileNotFound )
165- }
166-
167- storageCaps := s .parseStorageCapabilities (storageProfile .Status )
168- if accessMode == "" && storageCaps .AccessMode != "" {
169- accessMode = storageCaps .AccessMode
170- }
171- if volumeMode == "" && storageCaps .VolumeMode != "" {
172- volumeMode = storageCaps .VolumeMode
173- }
174-
175- return volumeMode , accessMode , nil
131+ return s .volumeAndAccessModesGetter .GetVolumeAndAccessModes (ctx , obj , sc )
176132}
177133
178134func (s DiskService ) StartImmediate (
@@ -446,105 +402,13 @@ func (s DiskService) GetStorageProfile(ctx context.Context, name string) (*cdiv1
446402 return object .FetchObject (ctx , types.NamespacedName {Name : name }, s .client , & cdiv1.StorageProfile {})
447403}
448404
449- type StorageCapabilities struct {
450- AccessMode corev1.PersistentVolumeAccessMode
451- VolumeMode corev1.PersistentVolumeMode
452- }
453-
454- func (cp StorageCapabilities ) IsEmpty () bool {
455- return cp .AccessMode == "" && cp .VolumeMode == ""
456- }
457-
458- var accessModeWeights = map [corev1.PersistentVolumeAccessMode ]int {
459- corev1 .ReadOnlyMany : 0 ,
460- corev1 .ReadWriteOncePod : 1 ,
461- corev1 .ReadWriteOnce : 2 ,
462- corev1 .ReadWriteMany : 3 ,
463- }
464-
465- var volumeModeWeights = map [corev1.PersistentVolumeMode ]int {
466- corev1 .PersistentVolumeFilesystem : 0 ,
467- corev1 .PersistentVolumeBlock : 1 ,
468- }
469-
470- func getAccessModeMax (modes []corev1.PersistentVolumeAccessMode ) corev1.PersistentVolumeAccessMode {
471- weight := - 1
472- var m corev1.PersistentVolumeAccessMode
473- for _ , mode := range modes {
474- if accessModeWeights [mode ] > weight {
475- weight = accessModeWeights [mode ]
476- m = mode
477- }
478- }
479- return m
480- }
481-
482- func (s DiskService ) parseVolumeMode (obj client.Object ) (corev1.PersistentVolumeMode , bool ) {
483- if obj == nil {
484- return "" , false
485- }
486- switch obj .GetAnnotations ()[annotations .AnnVirtualDiskVolumeMode ] {
487- case string (corev1 .PersistentVolumeBlock ):
488- return corev1 .PersistentVolumeBlock , true
489- case string (corev1 .PersistentVolumeFilesystem ):
490- return corev1 .PersistentVolumeFilesystem , true
491- default :
492- return "" , false
493- }
494- }
495-
496- func (s DiskService ) parseAccessMode (obj client.Object ) (corev1.PersistentVolumeAccessMode , bool ) {
497- if obj == nil {
498- return "" , false
499- }
500- switch obj .GetAnnotations ()[annotations .AnnVirtualDiskAccessMode ] {
501- case string (corev1 .ReadWriteOnce ):
502- return corev1 .ReadWriteOnce , true
503- case string (corev1 .ReadWriteMany ):
504- return corev1 .ReadWriteMany , true
505- default :
506- return "" , false
507- }
508- }
509-
510405func (s DiskService ) isImmediateBindingMode (sc * storagev1.StorageClass ) bool {
511406 if sc == nil {
512407 return false
513408 }
514409 return sc .GetAnnotations ()[annotations .AnnVirtualDiskBindingMode ] == string (storagev1 .VolumeBindingImmediate )
515410}
516411
517- func (s DiskService ) parseStorageCapabilities (status cdiv1.StorageProfileStatus ) StorageCapabilities {
518- var storageCapabilities []StorageCapabilities
519- for _ , cp := range status .ClaimPropertySets {
520- var mode corev1.PersistentVolumeMode
521- if cp .VolumeMode == nil || * cp .VolumeMode == "" {
522- mode = corev1 .PersistentVolumeFilesystem
523- } else {
524- mode = * cp .VolumeMode
525- }
526- storageCapabilities = append (storageCapabilities , StorageCapabilities {
527- AccessMode : getAccessModeMax (cp .AccessModes ),
528- VolumeMode : mode ,
529- })
530- }
531- slices .SortFunc (storageCapabilities , func (a , b StorageCapabilities ) int {
532- if c := cmp .Compare (accessModeWeights [a .AccessMode ], accessModeWeights [b .AccessMode ]); c != 0 {
533- return c
534- }
535- return cmp .Compare (volumeModeWeights [a .VolumeMode ], volumeModeWeights [b .VolumeMode ])
536- })
537-
538- if len (storageCapabilities ) == 0 {
539- return StorageCapabilities {
540- AccessMode : corev1 .ReadWriteOnce ,
541- VolumeMode : corev1 .PersistentVolumeFilesystem ,
542- }
543- }
544-
545- return storageCapabilities [len (storageCapabilities )- 1 ]
546- }
547-
548412func (s DiskService ) GetStorageClass (ctx context.Context , scName string ) (* storagev1.StorageClass , error ) {
549413 return object .FetchObject (ctx , types.NamespacedName {Name : scName }, s .client , & storagev1.StorageClass {})
550414}
0 commit comments