@@ -19,6 +19,7 @@ import (
1919 prometheusapi "github.com/prometheus/client_golang/api"
2020 prometheusv1 "github.com/prometheus/client_golang/api/prometheus/v1"
2121 corev1 "k8s.io/api/core/v1"
22+ storagev1 "k8s.io/api/storage/v1"
2223 k8serrors "k8s.io/apimachinery/pkg/api/errors"
2324 "k8s.io/apimachinery/pkg/api/meta"
2425 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -28,16 +29,19 @@ import (
2829 "k8s.io/client-go/rest"
2930 "k8s.io/utils/ptr"
3031 virtv1 "kubevirt.io/api/core/v1"
32+
3133 cdiv1 "kubevirt.io/containerized-data-importer-api/pkg/apis/core/v1beta1"
3234 k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
3335)
3436
3537const (
36- prometheusURLKey = "PROMETHEUS_URL"
37- prometheusRoute = "prometheus-k8s"
38- progressQuery = "kubevirt_vmi_migration_data_processed_bytes{name=\" %s\" } / (kubevirt_vmi_migration_data_processed_bytes{name=\" %s\" } + kubevirt_vmi_migration_data_remaining_bytes{name=\" %s\" }) * 100"
39- VMIKind = "VirtualMachineInstance"
40- PodKind = "Pod"
38+ prometheusURLKey = "PROMETHEUS_URL"
39+ prometheusRoute = "prometheus-k8s"
40+ progressQuery = "kubevirt_vmi_migration_data_processed_bytes{name=\" %s\" } / (kubevirt_vmi_migration_data_processed_bytes{name=\" %s\" } + kubevirt_vmi_migration_data_remaining_bytes{name=\" %s\" }) * 100"
41+ VMIKind = "VirtualMachineInstance"
42+ PodKind = "Pod"
43+ defaultVirtStorageClass = "storageclass.kubevirt.io/is-default-virt-class"
44+ defaultK8sStorageClass = "storageclass.kubernetes.io/is-default-class"
4145)
4246
4347var (
@@ -455,25 +459,35 @@ func updateVM(client k8sclient.Client, vm *virtv1.VirtualMachine, sourceVolumes,
455459 log .V (5 ).Info ("Setting volume migration strategy to migration" , "vm" , vmCopy .Name )
456460 vmCopy .Spec .UpdateVolumesStrategy = ptr.To [virtv1.UpdateVolumesStrategy ](virtv1 .UpdateVolumesStrategyMigration )
457461
462+ volumeNameToPVCMap := make (map [string ]string )
463+
458464 for i := 0 ; i < len (sourceVolumes ); i ++ {
459465 // Check if we need to update DataVolumeTemplates.
460- for j , dvTemplate := range vmCopy .Spec .DataVolumeTemplates {
461- if dvTemplate .Name == sourceVolumes [i ] {
462- log .V (5 ).Info ("Updating DataVolumeTemplate" , "source" , sourceVolumes [i ], "target" , targetVolumes [i ])
463- vmCopy .Spec .DataVolumeTemplates [j ].Name = targetVolumes [i ]
464- }
465- }
466466 for j , volume := range vm .Spec .Template .Spec .Volumes {
467467 if volume .PersistentVolumeClaim != nil && volume .PersistentVolumeClaim .ClaimName == sourceVolumes [i ] {
468468 log .V (5 ).Info ("Updating PersistentVolumeClaim" , "source" , sourceVolumes [i ], "target" , targetVolumes [i ])
469469 vmCopy .Spec .Template .Spec .Volumes [j ].PersistentVolumeClaim .ClaimName = targetVolumes [i ]
470+ volumeNameToPVCMap [sourceVolumes [i ]] = targetVolumes [i ]
470471 }
471472 if volume .DataVolume != nil && volume .DataVolume .Name == sourceVolumes [i ] {
472473 log .V (5 ).Info ("Updating DataVolume" , "source" , sourceVolumes [i ], "target" , targetVolumes [i ])
473474 if err := CreateNewAdoptionDataVolume (client , sourceVolumes [i ], targetVolumes [i ], vmCopy .Namespace , log ); err != nil {
474475 return err
475476 }
476477 vmCopy .Spec .Template .Spec .Volumes [j ].DataVolume .Name = targetVolumes [i ]
478+ volumeNameToPVCMap [sourceVolumes [i ]] = targetVolumes [i ]
479+ }
480+ }
481+ for j , dvTemplate := range vmCopy .Spec .DataVolumeTemplates {
482+ if dvTemplate .Name == sourceVolumes [i ] {
483+ log .V (5 ).Info ("Updating DataVolumeTemplate" , "source" , sourceVolumes [i ], "target" , targetVolumes [i ])
484+ vmCopy .Spec .DataVolumeTemplates [j ].Name = targetVolumes [i ]
485+ pvcName := volumeNameToPVCMap [sourceVolumes [i ]]
486+ sc , err := getStorageClassFromName (client , pvcName , vmCopy .Namespace )
487+ if err != nil {
488+ return err
489+ }
490+ vmCopy .Spec .DataVolumeTemplates [j ].Spec .Storage .StorageClassName = ptr .To (sc )
477491 }
478492 }
479493 }
@@ -488,6 +502,35 @@ func updateVM(client k8sclient.Client, vm *virtv1.VirtualMachine, sourceVolumes,
488502 return nil
489503}
490504
505+ func getStorageClassFromName (client k8sclient.Client , name , namespace string ) (string , error ) {
506+ volume := & corev1.PersistentVolumeClaim {}
507+ if err := client .Get (context .TODO (), k8sclient.ObjectKey {Namespace : namespace , Name : name }, volume ); err != nil {
508+ return "" , err
509+ }
510+ if volume .Spec .StorageClassName == nil {
511+ // Find the default storage class
512+ scList := & storagev1.StorageClassList {}
513+ if err := client .List (context .TODO (), scList ); err != nil {
514+ return "" , err
515+ }
516+ defaultStorageClass := ""
517+ for _ , sc := range scList .Items {
518+ if sc .Annotations != nil && sc .Annotations [defaultK8sStorageClass ] == "true" {
519+ defaultStorageClass = sc .Name
520+ }
521+ if sc .Annotations != nil && sc .Annotations [defaultVirtStorageClass ] == "true" {
522+ return sc .Name , nil
523+ }
524+ }
525+ if defaultStorageClass != "" {
526+ return defaultStorageClass , nil
527+ }
528+ // No default storage class found, return blank
529+ return "" , nil
530+ }
531+ return * volume .Spec .StorageClassName , nil
532+ }
533+
491534func createBlankDataVolumeFromPVC (client k8sclient.Client , targetPvc * corev1.PersistentVolumeClaim ) error {
492535 dv := & cdiv1.DataVolume {
493536 ObjectMeta : metav1.ObjectMeta {
0 commit comments