diff --git a/images/virtualization-artifact/pkg/controller/vd/internal/source/object_ref_cvi_test.go b/images/virtualization-artifact/pkg/controller/vd/internal/source/object_ref_cvi_test.go index a88ae1cdfa..bba5d04a43 100644 --- a/images/virtualization-artifact/pkg/controller/vd/internal/source/object_ref_cvi_test.go +++ b/images/virtualization-artifact/pkg/controller/vd/internal/source/object_ref_cvi_test.go @@ -184,6 +184,13 @@ var _ = Describe("ObjectRef ClusterVirtualImage", func() { It("waits for the first consumer", func() { dv.Status.Phase = cdiv1.PendingPopulation + dv.Status.Conditions = []cdiv1.DataVolumeCondition{ + { + Type: cdiv1.DataVolumeRunning, + Status: corev1.ConditionFalse, + Reason: "", + }, + } sc.VolumeBindingMode = ptr.To(storagev1.VolumeBindingWaitForFirstConsumer) client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(pvc, dv, sc).Build() diff --git a/images/virtualization-artifact/pkg/controller/vd/internal/source/object_ref_vi_test.go b/images/virtualization-artifact/pkg/controller/vd/internal/source/object_ref_vi_test.go index 0ecff188f1..5eacabf594 100644 --- a/images/virtualization-artifact/pkg/controller/vd/internal/source/object_ref_vi_test.go +++ b/images/virtualization-artifact/pkg/controller/vd/internal/source/object_ref_vi_test.go @@ -184,6 +184,13 @@ var _ = Describe("ObjectRef VirtualImage", func() { It("waits for the first consumer", func() { dv.Status.Phase = cdiv1.PendingPopulation + dv.Status.Conditions = []cdiv1.DataVolumeCondition{ + { + Type: cdiv1.DataVolumeRunning, + Status: corev1.ConditionFalse, + Reason: "", + }, + } sc.VolumeBindingMode = ptr.To(storagev1.VolumeBindingWaitForFirstConsumer) client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(pvc, dv, sc).Build() diff --git a/images/virtualization-artifact/pkg/controller/vd/internal/source/sources.go b/images/virtualization-artifact/pkg/controller/vd/internal/source/sources.go index 14ffe3cbd4..8c6606df3d 100644 --- a/images/virtualization-artifact/pkg/controller/vd/internal/source/sources.go +++ b/images/virtualization-artifact/pkg/controller/vd/internal/source/sources.go @@ -182,7 +182,9 @@ func setPhaseConditionForPVCProvisioningDisk( Message("Waiting for the pvc importer to be created") return nil } - if isStorageClassWFFC(sc) && (dv.Status.Phase == cdiv1.PendingPopulation || dv.Status.Phase == cdiv1.WaitForFirstConsumer) { + + dvRunningCond, _ := conditions.GetDataVolumeCondition(conditions.DVRunningConditionType, dv.Status.Conditions) + if isStorageClassWFFC(sc) && (dv.Status.Phase == cdiv1.PendingPopulation || dv.Status.Phase == cdiv1.WaitForFirstConsumer) && dvRunningCond.Reason == "" { vd.Status.Phase = v1alpha2.DiskWaitForFirstConsumer cb. Status(metav1.ConditionFalse). diff --git a/images/virtualization-artifact/pkg/controller/vd/internal/source/step/wait_for_dv_step.go b/images/virtualization-artifact/pkg/controller/vd/internal/source/step/wait_for_dv_step.go index 656d60dd72..0833ea1d0b 100644 --- a/images/virtualization-artifact/pkg/controller/vd/internal/source/step/wait_for_dv_step.go +++ b/images/virtualization-artifact/pkg/controller/vd/internal/source/step/wait_for_dv_step.go @@ -126,13 +126,18 @@ func (s WaitForDVStep) setForProvisioning(vd *v1alpha2.VirtualDisk) (set bool) { } func (s WaitForDVStep) setForFirstConsumerIsAwaited(ctx context.Context, vd *v1alpha2.VirtualDisk) (set bool, err error) { + if vd.Status.StorageClassName == "" { + return false, fmt.Errorf("StorageClassName is empty, please report a bug") + } + sc, err := object.FetchObject(ctx, types.NamespacedName{Name: vd.Status.StorageClassName}, s.client, &storagev1.StorageClass{}) if err != nil { return false, fmt.Errorf("get sc: %w", err) } + dvRunningCond, _ := conditions.GetDataVolumeCondition(conditions.DVRunningConditionType, s.dv.Status.Conditions) isWFFC := sc != nil && sc.VolumeBindingMode != nil && *sc.VolumeBindingMode == storagev1.VolumeBindingWaitForFirstConsumer - if isWFFC && (s.dv.Status.Phase == cdiv1.PendingPopulation || s.dv.Status.Phase == cdiv1.WaitForFirstConsumer) { + if isWFFC && (s.dv.Status.Phase == cdiv1.PendingPopulation || s.dv.Status.Phase == cdiv1.WaitForFirstConsumer) && dvRunningCond.Reason == "" { vd.Status.Phase = v1alpha2.DiskWaitForFirstConsumer s.cb. Status(metav1.ConditionFalse). diff --git a/images/virtualization-artifact/pkg/controller/vd/internal/watcher/datavolume_watcher.go b/images/virtualization-artifact/pkg/controller/vd/internal/watcher/datavolume_watcher.go index ffbaccf88d..c03cbfd6f2 100644 --- a/images/virtualization-artifact/pkg/controller/vd/internal/watcher/datavolume_watcher.go +++ b/images/virtualization-artifact/pkg/controller/vd/internal/watcher/datavolume_watcher.go @@ -28,7 +28,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/source" "github.com/deckhouse/virtualization-controller/pkg/controller/conditions" - "github.com/deckhouse/virtualization-controller/pkg/controller/service" "github.com/deckhouse/virtualization/api/core/v1alpha2" ) @@ -73,8 +72,14 @@ func (w *DataVolumeWatcher) Watch(mgr manager.Manager, ctr controller.Controller return true } - dvRunning := service.GetDataVolumeCondition(cdiv1.DataVolumeRunning, e.ObjectNew.Status.Conditions) - return dvRunning != nil && (dvRunning.Reason == "Error" || dvRunning.Reason == "ImagePullFailed") + oldDVRunning, _ := conditions.GetDataVolumeCondition(conditions.DVRunningConditionType, e.ObjectOld.Status.Conditions) + newDVRunning, _ := conditions.GetDataVolumeCondition(conditions.DVRunningConditionType, e.ObjectNew.Status.Conditions) + + if oldDVRunning.Reason != newDVRunning.Reason { + return true + } + + return newDVRunning.Reason == "Error" || newDVRunning.Reason == "ImagePullFailed" }, }, ),