From 7ad7e8903b9bc33dcb229f0bbcafc450415aa899 Mon Sep 17 00:00:00 2001 From: Pavel Tishkov Date: Tue, 30 Jun 2026 12:31:36 +0300 Subject: [PATCH 01/25] fix(vm): make condition messages user-friendly Reword VirtualMachine status condition messages so they describe the state in user terms and stop leaking internals: drop launcher pod wording from migration progress, replace the underlying PVC reference with disk storage, fix agent/provisioning wording and use full resource name with quoted disk names. Signed-off-by: Pavel Tishkov --- .../pkg/controller/vm/internal/agent.go | 4 ++-- .../controller/vm/internal/block_device_condition.go | 4 ++-- .../pkg/controller/vm/internal/block_devices_test.go | 10 +++++----- .../pkg/controller/vm/internal/migrating.go | 6 +++--- .../pkg/controller/vm/internal/migrating_test.go | 4 ++-- .../pkg/controller/vm/internal/provisioning.go | 4 ++-- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/agent.go b/images/virtualization-artifact/pkg/controller/vm/internal/agent.go index d7aa3c5595..034100820c 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/agent.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/agent.go @@ -131,14 +131,14 @@ func (h *AgentHandler) syncAgentVersionNotSupport(vm *v1alpha2.VirtualMachine, k if kvvmi == nil { cb.Status(metav1.ConditionFalse). Reason(vmcondition.ReasonAgentNotReady). - Message("Failed to check version, because Vm is not running.") + Message("Cannot check the agent version: the VirtualMachine is not running.") return } for _, c := range kvvmi.Status.Conditions { status := conditionStatus(string(c.Status)) if c.Type == virtv1.VirtualMachineInstanceUnsupportedAgent && status == metav1.ConditionTrue { - cb.Status(status).Reason(vmcondition.ReasonAgentNotSupported).Message(c.Reason) + cb.Status(status).Reason(vmcondition.ReasonAgentNotSupported).Message("The guest agent version is not supported.") return } } diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/block_device_condition.go b/images/virtualization-artifact/pkg/controller/vm/internal/block_device_condition.go index 37b48c91b3..5cb3a6a6fa 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/block_device_condition.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/block_device_condition.go @@ -324,9 +324,9 @@ func (h *BlockDeviceHandler) countReadyBlockDevices(vm *v1alpha2.VirtualMachine, } else { var msg string if wffc && vm.Status.Phase == v1alpha2.MachineStopped { - msg = fmt.Sprintf("Virtual disk %s is waiting for the virtual machine to be starting", vd.Name) + msg = fmt.Sprintf("Virtual disk %q is waiting for the virtual machine to start", vd.Name) } else { - msg = fmt.Sprintf("Virtual disk %s is waiting for the underlying PVC to be bound", vd.Name) + msg = fmt.Sprintf("Virtual disk %q is waiting for its storage to be provisioned", vd.Name) } warnings = append(warnings, msg) diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/block_devices_test.go b/images/virtualization-artifact/pkg/controller/vm/internal/block_devices_test.go index 6d521d5bbf..91794ff144 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/block_devices_test.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/block_devices_test.go @@ -243,21 +243,21 @@ var _ = Describe("Test BlockDeviceReady condition", func() { getWFFCVD(metav1.ConditionTrue, vdcondition.AttachedToVirtualMachine.String()), getVMWithOneVD(v1alpha2.MachinePending), metav1.ConditionFalse, - "Waiting for block device \"vd1\" to be ready; Virtual disk vd1 is waiting for the underlying PVC to be bound.", + "Waiting for block device \"vd1\" to be ready; Virtual disk \"vd1\" is waiting for its storage to be provisioned.", ), Entry( "vd AttachedToVirtualMachine & Running VM", getWFFCVD(metav1.ConditionTrue, vdcondition.AttachedToVirtualMachine.String()), getVMWithOneVD(v1alpha2.MachineRunning), metav1.ConditionFalse, - "Waiting for block device \"vd1\" to be ready; Virtual disk vd1 is waiting for the underlying PVC to be bound.", + "Waiting for block device \"vd1\" to be ready; Virtual disk \"vd1\" is waiting for its storage to be provisioned.", ), Entry( "vd AttachedToVirtualMachine & Stopped VM", getWFFCVD(metav1.ConditionTrue, vdcondition.AttachedToVirtualMachine.String()), getVMWithOneVD(v1alpha2.MachineStopped), metav1.ConditionFalse, - "Waiting for block device \"vd1\" to be ready; Virtual disk vd1 is waiting for the virtual machine to be starting.", + "Waiting for block device \"vd1\" to be ready; Virtual disk \"vd1\" is waiting for the virtual machine to start.", ), // -- Entry( @@ -279,7 +279,7 @@ var _ = Describe("Test BlockDeviceReady condition", func() { getWFFCVD(metav1.ConditionFalse, vdcondition.NotInUse.String()), getVMWithOneVD(v1alpha2.MachineStopped), metav1.ConditionFalse, - "Waiting for block device \"vd1\" to be ready; Virtual disk vd1 is waiting for the virtual machine to be starting.", + "Waiting for block device \"vd1\" to be ready; Virtual disk \"vd1\" is waiting for the virtual machine to start.", ), ) @@ -1156,7 +1156,7 @@ var _ = Describe("Test BlockDeviceReady condition", func() { Expect(err).NotTo(HaveOccurred()) bdCond, _ := conditions.GetCondition(vmcondition.TypeBlockDevicesReady, vmState.VirtualMachine().Changed().Status.Conditions) - Expect(bdCond.Message).To(Equal("Waiting for block device \"vd1\" to be ready; Virtual disk vd1 is waiting for the underlying PVC to be bound.")) + Expect(bdCond.Message).To(Equal("Waiting for block device \"vd1\" to be ready; Virtual disk \"vd1\" is waiting for its storage to be provisioned.")) Expect(bdCond.Status).To(Equal(metav1.ConditionFalse)) Expect(bdCond.Reason).To(Equal(vmcondition.ReasonBlockDevicesNotReady.String())) }) diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/migrating.go b/images/virtualization-artifact/pkg/controller/vm/internal/migrating.go index 7ea604eb01..09fba85f2e 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/migrating.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/migrating.go @@ -166,13 +166,13 @@ func (h *MigratingHandler) syncMigrating(ctx context.Context, s state.VirtualMac cb.Message("Migration is awaiting start.") case vmopcondition.ReasonTargetScheduling.String(): - cb.Message("Migration is in progress: target pod is being scheduled.") + cb.Message("Migration is in progress: scheduling the migration target.") case vmopcondition.ReasonQuotaExceeded.String(): cb.Message(fmt.Sprintf("Migration is pending: %s.", completed.Message)) case vmopcondition.ReasonMigrationPrepareTarget.String(), vmopcondition.ReasonTargetPreparing.String(), vmopcondition.ReasonDisksPreparing.String(): - cb.Message("Migration is in progress: target pod is being scheduled and prepared.") + cb.Message("Migration is in progress: preparing the migration target.") case vmopcondition.ReasonMigrationTargetReady.String(), vmopcondition.ReasonSyncing.String(), vmopcondition.ReasonSourceSuspended.String(), vmopcondition.ReasonTargetResumed.String(): cb.Message("Migration is in progress: source and target are being synchronized.") @@ -229,7 +229,7 @@ func (h *MigratingHandler) syncWaitingForVMToBeReadyMigrate(ctx context.Context, } if !synced { - cb.Message("Target persistent volume claims are not synced yet.") + cb.Message("The virtual machine disks are not synchronized to the migration target yet.") return nil } diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/migrating_test.go b/images/virtualization-artifact/pkg/controller/vm/internal/migrating_test.go index 6eef76e17f..a94d5f0915 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/migrating_test.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/migrating_test.go @@ -196,7 +196,7 @@ var _ = Describe("MigratingHandler", func() { Expect(exists).To(BeTrue()) Expect(cond.Status).To(Equal(metav1.ConditionFalse)) Expect(cond.Reason).To(Equal(vmcondition.ReasonMigratingPending.String())) - Expect(cond.Message).To(Equal("Migration is in progress: target pod is being scheduled.")) + Expect(cond.Message).To(Equal("Migration is in progress: scheduling the migration target.")) }) It("Should set active progress message when vmop is in progress with target preparing reason", func() { @@ -215,7 +215,7 @@ var _ = Describe("MigratingHandler", func() { Expect(exists).To(BeTrue()) Expect(cond.Status).To(Equal(metav1.ConditionFalse)) Expect(cond.Reason).To(Equal(vmcondition.ReasonMigratingPending.String())) - Expect(cond.Message).To(Equal("Migration is in progress: target pod is being scheduled and prepared.")) + Expect(cond.Message).To(Equal("Migration is in progress: preparing the migration target.")) }) It("Should set active progress message when vmop is in progress with target ready reason", func() { diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/provisioning.go b/images/virtualization-artifact/pkg/controller/vm/internal/provisioning.go index b3511b33a2..6940771fa5 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/provisioning.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/provisioning.go @@ -84,7 +84,7 @@ func (h *ProvisioningHandler) Handle(ctx context.Context, s state.VirtualMachine if p.UserDataRef == nil || p.UserDataRef.Kind != v1alpha2.UserDataRefKindSecret { cb.Status(metav1.ConditionFalse). Reason(vmcondition.ReasonProvisioningNotReady). - Message(fmt.Sprintf("userdataRef must be %q", v1alpha2.UserDataRefKindSecret)) + Message(fmt.Sprintf("spec.provisioning.userDataRef.kind must be %q", v1alpha2.UserDataRefKindSecret)) } key := types.NamespacedName{Name: p.UserDataRef.Name, Namespace: current.GetNamespace()} err := h.genConditionFromSecret(ctx, cb, key) @@ -96,7 +96,7 @@ func (h *ProvisioningHandler) Handle(ctx context.Context, s state.VirtualMachine if p.SysprepRef == nil || p.SysprepRef.Kind != v1alpha2.SysprepRefKindSecret { cb.Status(metav1.ConditionFalse). Reason(vmcondition.ReasonProvisioningNotReady). - Message(fmt.Sprintf("sysprepRef must be %q", v1alpha2.SysprepRefKindSecret)) + Message(fmt.Sprintf("spec.provisioning.sysprepRef.kind must be %q", v1alpha2.SysprepRefKindSecret)) } key := types.NamespacedName{Name: p.SysprepRef.Name, Namespace: current.GetNamespace()} err := h.genConditionFromSecret(ctx, cb, key) From 897d126fcccc620d7d4742bc0fc2ab38c0d7b663 Mon Sep 17 00:00:00 2001 From: Pavel Tishkov Date: Tue, 30 Jun 2026 12:41:05 +0300 Subject: [PATCH 02/25] fix(vmbda): make condition messages user-friendly Reword VirtualMachineBlockDeviceAttachment status messages to describe the state in user terms: drop InternalVirtualization* and underlying PVC/PersistentVolume wording in favour of the VirtualMachine and the disk/image storage, fix grammar and the limit message. Signed-off-by: Pavel Tishkov --- .../vmbda/internal/block_device_limiter.go | 2 +- .../vmbda/internal/block_device_ready.go | 20 +++++++++---------- .../controller/vmbda/internal/life_cycle.go | 10 +++++----- .../vmbda/internal/virtual_machine_ready.go | 4 ++-- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/images/virtualization-artifact/pkg/controller/vmbda/internal/block_device_limiter.go b/images/virtualization-artifact/pkg/controller/vmbda/internal/block_device_limiter.go index 7dc4e24049..24485a7efb 100644 --- a/images/virtualization-artifact/pkg/controller/vmbda/internal/block_device_limiter.go +++ b/images/virtualization-artifact/pkg/controller/vmbda/internal/block_device_limiter.go @@ -61,7 +61,7 @@ func (h *BlockDeviceLimiter) Handle(ctx context.Context, vmbda *v1alpha2.Virtual cb. Status(metav1.ConditionFalse). Reason(vmbdacondition.CapacityReached). - Message(fmt.Sprintf("Can not attach %d block devices (%d is maximum) to `VirtualMachine` %q", blockDeviceAttachedCount, common.VMBlockDeviceAttachedLimit, vmbda.Spec.VirtualMachineName)) + Message(fmt.Sprintf("Cannot attach %d block devices to VirtualMachine %q: the maximum is %d.", blockDeviceAttachedCount, vmbda.Spec.VirtualMachineName, common.VMBlockDeviceAttachedLimit)) } return reconcile.Result{}, nil diff --git a/images/virtualization-artifact/pkg/controller/vmbda/internal/block_device_ready.go b/images/virtualization-artifact/pkg/controller/vmbda/internal/block_device_ready.go index 97e4c247f4..552b40b275 100644 --- a/images/virtualization-artifact/pkg/controller/vmbda/internal/block_device_ready.go +++ b/images/virtualization-artifact/pkg/controller/vmbda/internal/block_device_ready.go @@ -89,7 +89,7 @@ func (h BlockDeviceReadyHandler) Handle(ctx context.Context, vmbda *v1alpha2.Vir cb. Status(metav1.ConditionFalse). Reason(vmbdacondition.BlockDeviceNotReady). - Message(fmt.Sprintf("Waiting for the VirtualImage %q to be observed in its latest state generation.", viKey.String())) + Message(fmt.Sprintf("Waiting for the VirtualImage %q changes to be processed.", viKey.String())) return reconcile.Result{}, nil } @@ -106,7 +106,7 @@ func (h BlockDeviceReadyHandler) Handle(ctx context.Context, vmbda *v1alpha2.Vir cb. Status(metav1.ConditionFalse). Reason(vmbdacondition.BlockDeviceNotReady). - Message("Waiting until VirtualImage has associated PersistentVolumeClaim name.") + Message(fmt.Sprintf("Waiting for the VirtualImage %q storage to be provisioned.", viKey.String())) return reconcile.Result{}, nil } ad := service.NewAttachmentDiskFromVirtualImage(vi) @@ -119,7 +119,7 @@ func (h BlockDeviceReadyHandler) Handle(ctx context.Context, vmbda *v1alpha2.Vir cb. Status(metav1.ConditionFalse). Reason(vmbdacondition.BlockDeviceNotReady). - Message(fmt.Sprintf("Underlying PersistentVolumeClaim %q not found.", vi.Status.Target.PersistentVolumeClaim)) + Message(fmt.Sprintf("The VirtualImage %q storage is not ready.", viKey.String())) return reconcile.Result{}, nil } @@ -127,7 +127,7 @@ func (h BlockDeviceReadyHandler) Handle(ctx context.Context, vmbda *v1alpha2.Vir cb. Status(metav1.ConditionFalse). Reason(vmbdacondition.BlockDeviceNotReady). - Message(fmt.Sprintf("Underlying PersistentVolumeClaim %q not bound.", vi.Status.Target.PersistentVolumeClaim)) + Message(fmt.Sprintf("The VirtualImage %q storage is not bound yet.", viKey.String())) return reconcile.Result{}, nil } @@ -138,7 +138,7 @@ func (h BlockDeviceReadyHandler) Handle(ctx context.Context, vmbda *v1alpha2.Vir cb. Status(metav1.ConditionFalse). Reason(vmbdacondition.BlockDeviceNotReady). - Message("Waiting until VirtualImage has associated RegistryUrl.") + Message(fmt.Sprintf("Waiting for the VirtualImage %q to be published and become available.", viKey.String())) return reconcile.Result{}, nil } } @@ -175,7 +175,7 @@ func (h BlockDeviceReadyHandler) Handle(ctx context.Context, vmbda *v1alpha2.Vir cb. Status(metav1.ConditionFalse). Reason(vmbdacondition.BlockDeviceNotReady). - Message(fmt.Sprintf("Waiting for the ClusterVirtualImage %q to be observed in its latest state generation.", cviKey.String())) + Message(fmt.Sprintf("Waiting for the ClusterVirtualImage %q changes to be processed.", cviKey.String())) return reconcile.Result{}, nil } @@ -191,7 +191,7 @@ func (h BlockDeviceReadyHandler) Handle(ctx context.Context, vmbda *v1alpha2.Vir cb. Status(metav1.ConditionFalse). Reason(vmbdacondition.BlockDeviceNotReady). - Message("Waiting until VirtualImage has associated RegistryUrl.") + Message(fmt.Sprintf("Waiting for the ClusterVirtualImage %q to be published and become available.", cviKey.String())) return reconcile.Result{}, nil } @@ -261,7 +261,7 @@ func (h BlockDeviceReadyHandler) ValidateVirtualDiskReady(ctx context.Context, v cb. Status(metav1.ConditionFalse). Reason(vmbdacondition.BlockDeviceNotReady). - Message("Waiting until VirtualDisk has associated PersistentVolumeClaim name.") + Message(fmt.Sprintf("Waiting for the VirtualDisk %q storage to be provisioned.", vdKey.String())) return nil } @@ -275,7 +275,7 @@ func (h BlockDeviceReadyHandler) ValidateVirtualDiskReady(ctx context.Context, v cb. Status(metav1.ConditionFalse). Reason(vmbdacondition.BlockDeviceNotReady). - Message(fmt.Sprintf("Underlying PersistentVolumeClaim %q not found.", vd.Status.Target)) + Message(fmt.Sprintf("The VirtualDisk %q storage is not ready.", vdKey.String())) return nil } @@ -283,7 +283,7 @@ func (h BlockDeviceReadyHandler) ValidateVirtualDiskReady(ctx context.Context, v cb. Status(metav1.ConditionFalse). Reason(vmbdacondition.BlockDeviceNotReady). - Message(fmt.Sprintf("Underlying PersistentVolumeClaim %q not bound.", vd.Status.Target)) + Message(fmt.Sprintf("The VirtualDisk %q storage is not bound yet.", vdKey.String())) return nil } diff --git a/images/virtualization-artifact/pkg/controller/vmbda/internal/life_cycle.go b/images/virtualization-artifact/pkg/controller/vmbda/internal/life_cycle.go index 9d5dea04be..54062c5e1a 100644 --- a/images/virtualization-artifact/pkg/controller/vmbda/internal/life_cycle.go +++ b/images/virtualization-artifact/pkg/controller/vmbda/internal/life_cycle.go @@ -155,7 +155,7 @@ func (h LifeCycleHandler) Handle(ctx context.Context, vmbda *v1alpha2.VirtualMac cb. Status(metav1.ConditionFalse). Reason(vmbdacondition.NotAttached). - Message(fmt.Sprintf("AttachmentDisk %q not found.", vmbda.Spec.BlockDeviceRef.Name)) + Message(fmt.Sprintf("Block device %q not found.", vmbda.Spec.BlockDeviceRef.Name)) return reconcile.Result{}, nil } @@ -173,7 +173,7 @@ func (h LifeCycleHandler) Handle(ctx context.Context, vmbda *v1alpha2.VirtualMac cb. Status(metav1.ConditionFalse). Reason(vmbdacondition.NotAttached). - Message(fmt.Sprintf("InternalVirtualizationVirtualMachine %q not found.", vm.Name)) + Message(fmt.Sprintf("VirtualMachine %q is not fully started yet.", vm.Name)) return reconcile.Result{}, nil } @@ -187,7 +187,7 @@ func (h LifeCycleHandler) Handle(ctx context.Context, vmbda *v1alpha2.VirtualMac cb. Status(metav1.ConditionFalse). Reason(vmbdacondition.NotAttached). - Message(fmt.Sprintf("InternalVirtualizationVirtualMachineInstance %q not found.", vm.Name)) + Message(fmt.Sprintf("VirtualMachine %q is not fully started yet.", vm.Name)) return reconcile.Result{}, nil } @@ -263,7 +263,7 @@ func (h LifeCycleHandler) Handle(ctx context.Context, vmbda *v1alpha2.VirtualMac cb. Status(metav1.ConditionFalse). Reason(vmbdacondition.DeviceNotAvailableOnNode). - Message(fmt.Sprintf("PersistentVolume %q is not available on node %q where the virtual machine is running", pvc.Spec.VolumeName, kvvmi.Status.NodeName)) + Message("The disk storage is not available on the node where the VirtualMachine is currently running.") return reconcile.Result{}, nil } } @@ -286,7 +286,7 @@ func (h LifeCycleHandler) Handle(ctx context.Context, vmbda *v1alpha2.VirtualMac cb. Status(metav1.ConditionFalse). Reason(vmbdacondition.AttachmentRequestSent). - Message("Attachment request has sent: attachment is in progress.") + Message("Attachment request has been sent: attachment is in progress.") return reconcile.Result{}, nil case errors.Is(canErr, service.ErrHotPlugRequestAlreadySent): log.Info("Attachment request sent: attachment is in progress.") diff --git a/images/virtualization-artifact/pkg/controller/vmbda/internal/virtual_machine_ready.go b/images/virtualization-artifact/pkg/controller/vmbda/internal/virtual_machine_ready.go index 2cd8f710cc..769c918359 100644 --- a/images/virtualization-artifact/pkg/controller/vmbda/internal/virtual_machine_ready.go +++ b/images/virtualization-artifact/pkg/controller/vmbda/internal/virtual_machine_ready.go @@ -97,7 +97,7 @@ func (h VirtualMachineReadyHandler) Handle(ctx context.Context, vmbda *v1alpha2. cb. Status(metav1.ConditionFalse). Reason(vmbdacondition.VirtualMachineNotReady). - Message(fmt.Sprintf("VirtualMachine %q Running, but underlying InternalVirtualizationVirtualMachine not found.", vmKey.String())) + Message(fmt.Sprintf("VirtualMachine %q is Running, but its underlying virtualization instance is not ready yet.", vmKey.String())) return reconcile.Result{}, nil } @@ -110,7 +110,7 @@ func (h VirtualMachineReadyHandler) Handle(ctx context.Context, vmbda *v1alpha2. cb. Status(metav1.ConditionFalse). Reason(vmbdacondition.VirtualMachineNotReady). - Message(fmt.Sprintf("VirtualMachine %q Running, but underlying InternalVirtualizationVirtualMachineInstance not found.", vmKey.String())) + Message(fmt.Sprintf("VirtualMachine %q is Running, but its underlying virtualization instance is not ready yet.", vmKey.String())) return reconcile.Result{}, nil } From 5574240401875fa6d2f410518a1e91ab07419d84 Mon Sep 17 00:00:00 2001 From: Pavel Tishkov Date: Tue, 30 Jun 2026 12:46:08 +0300 Subject: [PATCH 03/25] fix(vd): make condition messages user-friendly Reword VirtualDisk status messages to describe provisioning in user terms: drop pvc importer / PVC provisioner / StorageProfile wording in favour of disk provisioning and StorageClass, and stop printing internal PVC/PV object names. Signed-off-by: Pavel Tishkov --- .../pkg/controller/vd/internal/migration.go | 2 +- .../pkg/controller/vd/internal/source/sources.go | 14 +++++++------- .../vd/internal/source/step/create_dv_step.go | 2 +- .../source/step/create_pvc_from_vdsnapshot_step.go | 2 +- .../internal/source/step/ensure_node_placement.go | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/images/virtualization-artifact/pkg/controller/vd/internal/migration.go b/images/virtualization-artifact/pkg/controller/vd/internal/migration.go index 211d6f05a6..4685568721 100644 --- a/images/virtualization-artifact/pkg/controller/vd/internal/migration.go +++ b/images/virtualization-artifact/pkg/controller/vd/internal/migration.go @@ -533,7 +533,7 @@ func (h MigrationHandler) handleMigrateSync(ctx context.Context, vd *v1alpha2.Vi } } - cb.Message("Target persistent volume claim is not bound or not waiting for first consumer.") + cb.Message("Waiting for the target PersistentVolumeClaim to be provisioned.") conditions.SetCondition(cb, &vd.Status.Conditions) return nil } 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 bbac959659..85d0c02f8a 100644 --- a/images/virtualization-artifact/pkg/controller/vd/internal/source/sources.go +++ b/images/virtualization-artifact/pkg/controller/vd/internal/source/sources.go @@ -111,14 +111,14 @@ func setPhaseConditionForFinishedDisk( switch { case pvc == nil: newPhase = v1alpha2.DiskLost - setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Lost, fmt.Sprintf("PVC %s not found.", supgen.PersistentVolumeClaim().String())) + setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Lost, "The underlying PersistentVolumeClaim was not found.") case pvc.Status.Phase == corev1.ClaimLost: if pvc.GetAnnotations()[annotations.AnnDataExportRequest] == "true" { newPhase = v1alpha2.DiskExporting setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Exporting, "PV is being exported") } else { newPhase = v1alpha2.DiskLost - setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Lost, fmt.Sprintf("PV %s not found.", pvc.Spec.VolumeName)) + setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Lost, "The underlying PersistentVolume was not found.") } default: newPhase = v1alpha2.DiskReady @@ -144,7 +144,7 @@ func setPhaseConditionFromStorageError(err error, vd *v1alpha2.VirtualDisk, cb * cb, metav1.ConditionFalse, vdcondition.ProvisioningFailed, - "StorageProfile not found in the cluster: Please check a StorageClass name in the cluster or set a default StorageClass.", + "The StorageClass is not fully configured in the cluster. Check the StorageClass name or set a default StorageClass.", ) return true, nil case errors.Is(err, service.ErrDefaultStorageClassNotFound): @@ -176,7 +176,7 @@ func setPhaseConditionForPVCProvisioningDisk( case err == nil: if dv == nil { vd.Status.Phase = v1alpha2.DiskProvisioning - setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Provisioning, "Waiting for the pvc importer to be created") + setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Provisioning, "Waiting for the disk provisioning to start.") return nil } @@ -191,7 +191,7 @@ func setPhaseConditionForPVCProvisioningDisk( } vd.Status.Phase = v1alpha2.DiskProvisioning - setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Provisioning, "Import is in the process of provisioning to PVC.") + setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Provisioning, "Importing data into the PersistentVolumeClaim.") return nil case errors.Is(err, service.ErrDataVolumeNotRunning): vd.Status.Phase = v1alpha2.DiskFailed @@ -333,9 +333,9 @@ func setPhaseConditionFromProvisioningError( return err } - setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Provisioning, "PVC provisioner recreation due to a changes in the virtual machine tolerations.") + setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Provisioning, "Recreating the disk provisioner due to changes in the virtual machine tolerations.") } else { - setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Provisioning, "Trying to schedule the PVC provisioner.") + setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Provisioning, "Scheduling the disk provisioner.") } return nil diff --git a/images/virtualization-artifact/pkg/controller/vd/internal/source/step/create_dv_step.go b/images/virtualization-artifact/pkg/controller/vd/internal/source/step/create_dv_step.go index f05746f5dc..680d3703bc 100644 --- a/images/virtualization-artifact/pkg/controller/vd/internal/source/step/create_dv_step.go +++ b/images/virtualization-artifact/pkg/controller/vd/internal/source/step/create_dv_step.go @@ -106,7 +106,7 @@ func (s CreateDataVolumeStep) Take(ctx context.Context, vd *v1alpha2.VirtualDisk s.cb. Status(metav1.ConditionFalse). Reason(vicondition.ProvisioningFailed). - Message("StorageProfile not found in the cluster: Please check a StorageProfile name in the cluster.") + Message("The StorageClass is not fully configured in the cluster. Check the StorageClass name or set a default StorageClass.") return &reconcile.Result{}, nil default: return nil, fmt.Errorf("start immediate: %w", err) diff --git a/images/virtualization-artifact/pkg/controller/vd/internal/source/step/create_pvc_from_vdsnapshot_step.go b/images/virtualization-artifact/pkg/controller/vd/internal/source/step/create_pvc_from_vdsnapshot_step.go index 891d5b5108..9cc280a0c6 100644 --- a/images/virtualization-artifact/pkg/controller/vd/internal/source/step/create_pvc_from_vdsnapshot_step.go +++ b/images/virtualization-artifact/pkg/controller/vd/internal/source/step/create_pvc_from_vdsnapshot_step.go @@ -149,7 +149,7 @@ func (s CreatePVCFromVDSnapshotStep) Take(ctx context.Context, vd *v1alpha2.Virt s.cb. Status(metav1.ConditionFalse). Reason(vdcondition.Provisioning). - Message("PVC has created: waiting to be Bound.") + Message("The PersistentVolumeClaim has been created; waiting for it to be Bound.") vd.Status.Progress = "0%" vd.Status.SourceUID = ptr.To(vdSnapshot.UID) diff --git a/images/virtualization-artifact/pkg/controller/vd/internal/source/step/ensure_node_placement.go b/images/virtualization-artifact/pkg/controller/vd/internal/source/step/ensure_node_placement.go index 120505af0f..c0a9d3a881 100644 --- a/images/virtualization-artifact/pkg/controller/vd/internal/source/step/ensure_node_placement.go +++ b/images/virtualization-artifact/pkg/controller/vd/internal/source/step/ensure_node_placement.go @@ -98,7 +98,7 @@ func (s EnsureNodePlacementStep) Take(ctx context.Context, vd *v1alpha2.VirtualD s.cb. Status(metav1.ConditionFalse). Reason(vdcondition.Provisioning). - Message("Trying to schedule the PersistentVolumeClaim provisioner.") + Message("Scheduling the disk provisioner.") return &reconcile.Result{}, nil } @@ -112,6 +112,6 @@ func (s EnsureNodePlacementStep) Take(ctx context.Context, vd *v1alpha2.VirtualD s.cb. Status(metav1.ConditionFalse). Reason(vdcondition.Provisioning). - Message("The PersistentVolumeClaim provisioner will be recreated due to changes in the virtual machine tolerations.") + Message("The disk provisioner will be recreated due to changes in the virtual machine tolerations.") return &reconcile.Result{}, nil } From 2a0055d7809d5d051389f3cda56a07b91f2c03c7 Mon Sep 17 00:00:00 2001 From: Pavel Tishkov Date: Tue, 30 Jun 2026 12:50:20 +0300 Subject: [PATCH 04/25] fix(vi): make condition messages user-friendly Reword VirtualImage status messages to user terms: replace DVCR/PVC provisioner and importer/bounder pod wording with image import and disk storage, drop the internal registry URL, use the full StorageClass/ PersistentVolumeClaim names and fix grammar. Signed-off-by: Pavel Tishkov --- .../pkg/controller/vi/internal/image_presence.go | 2 +- .../pkg/controller/vi/internal/life_cycle.go | 2 +- .../pkg/controller/vi/internal/source/http.go | 10 +++++----- .../pkg/controller/vi/internal/source/object_ref.go | 10 +++++----- .../pkg/controller/vi/internal/source/object_ref_vd.go | 6 +++--- .../vi/internal/source/object_ref_vi_on_pvc.go | 6 +++--- .../pkg/controller/vi/internal/source/registry.go | 10 +++++----- .../pkg/controller/vi/internal/source/sources.go | 2 +- .../pkg/controller/vi/internal/source/sources_test.go | 2 +- .../vi/internal/source/step/create_bounder_pod_step.go | 2 +- .../source/step/create_bounder_pod_step_test.go | 2 +- .../vi/internal/source/step/wait_for_pod_step.go | 6 +++--- .../vi/internal/source/step/wait_for_pod_step_test.go | 6 +++--- .../vi/internal/source/step/wait_for_pvc_step.go | 4 ++-- .../vi/internal/source/step/wait_for_pvc_step_test.go | 4 ++-- .../pkg/controller/vi/internal/source/upload.go | 10 +++++----- 16 files changed, 42 insertions(+), 42 deletions(-) diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/image_presence.go b/images/virtualization-artifact/pkg/controller/vi/internal/image_presence.go index 89fbf511f3..a7dace4fb8 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/image_presence.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/image_presence.go @@ -76,7 +76,7 @@ func (h *ImagePresenceHandler) Handle(ctx context.Context, vi *v1alpha2.VirtualI Generation(vi.Generation). Status(metav1.ConditionFalse). Reason(vicondition.ImageLost). - Message(fmt.Sprintf("Image %q not found in DVCR.", registryURL)) + Message("The image data is no longer available in the cluster registry.") conditions.SetCondition(cb, &vi.Status.Conditions) } diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/life_cycle.go b/images/virtualization-artifact/pkg/controller/vi/internal/life_cycle.go index 7e443b0c57..671e1d0ac2 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/life_cycle.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/life_cycle.go @@ -112,7 +112,7 @@ func (h LifeCycleHandler) Handle(ctx context.Context, vi *v1alpha2.VirtualImage) cb. Status(metav1.ConditionFalse). Reason(vicondition.StorageClassNotReady). - Message("Storage class in not ready") + Message("Storage class is not ready.") conditions.SetCondition(cb, &vi.Status.Conditions) return reconcile.Result{}, nil diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/http.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/http.go index fb5e3915a5..29f3c17966 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/http.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/http.go @@ -124,7 +124,7 @@ func (ds HTTPDataSource) StoreToDVCR(ctx context.Context, vi *v1alpha2.VirtualIm cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("DVCR Provisioner not found: create the new one.") + Message("Importing the image.") log.Info("Create importer pod...", "progress", vi.Status.Progress, "pod.phase", "nil") @@ -175,7 +175,7 @@ func (ds HTTPDataSource) StoreToDVCR(ctx context.Context, vi *v1alpha2.VirtualIm cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Import is in the process of provisioning to DVCR.") + Message("The image is being imported.") vi.Status.Phase = v1alpha2.ImageProvisioning vi.Status.Progress = ds.statService.GetProgress(vi.GetUID(), pod, vi.Status.Progress) @@ -263,7 +263,7 @@ func (ds HTTPDataSource) StoreToPVC(ctx context.Context, vi *v1alpha2.VirtualIma cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("DVCR Provisioner not found: create the new one.") + Message("Importing the image.") log.Info("Create importer pod...", "progress", vi.Status.Progress, "pod.phase", "nil") @@ -285,7 +285,7 @@ func (ds HTTPDataSource) StoreToPVC(ctx context.Context, vi *v1alpha2.VirtualIma cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Import is in the process of provisioning to DVCR.") + Message("The image is being imported.") vi.Status.Progress = ds.statService.GetProgress(vi.GetUID(), pod, vi.Status.Progress, service.NewScaleOption(0, 50)) vi.Status.DownloadSpeed = ds.statService.GetDownloadSpeed(vi.GetUID(), pod) @@ -345,7 +345,7 @@ func (ds HTTPDataSource) StoreToPVC(ctx context.Context, vi *v1alpha2.VirtualIma cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("DVCR Provisioner not found: create the new one.") + Message("Importing the image.") return reconcile.Result{RequeueAfter: time.Second}, nil case dvQuotaNotExceededCondition != nil && dvQuotaNotExceededCondition.Status == corev1.ConditionFalse: diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref.go index ed1b52f60f..2d9c97bc9f 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref.go @@ -185,7 +185,7 @@ func (ds ObjectRefDataSource) StoreToPVC(ctx context.Context, vi *v1alpha2.Virtu cb. Status(metav1.ConditionFalse). Reason(vicondition.ProvisioningFailed). - Message("Failed to get stats from non-ready datasource: waiting for the DataSource to be ready.") + Message("Waiting for the source DataSource to become ready.") return reconcile.Result{}, nil } @@ -224,7 +224,7 @@ func (ds ObjectRefDataSource) StoreToPVC(ctx context.Context, vi *v1alpha2.Virtu cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("PVC Provisioner not found: create the new one.") + Message("Preparing the disk storage for the image.") return reconcile.Result{RequeueAfter: time.Second}, nil case dvQuotaNotExceededCondition != nil && dvQuotaNotExceededCondition.Status == corev1.ConditionFalse: @@ -397,7 +397,7 @@ func (ds ObjectRefDataSource) StoreToDVCR(ctx context.Context, vi *v1alpha2.Virt cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("DVCR Provisioner not found: create the new one.") + Message("Importing the image.") log.Info("Ready", "progress", vi.Status.Progress, "pod.phase", "nil") @@ -429,7 +429,7 @@ func (ds ObjectRefDataSource) StoreToDVCR(ctx context.Context, vi *v1alpha2.Virt cb. Status(metav1.ConditionFalse). Reason(vicondition.ProvisioningFailed). - Message("Failed to get stats from non-ready datasource: waiting for the DataSource to be ready.") + Message("Waiting for the source DataSource to become ready.") return reconcile.Result{}, nil } @@ -455,7 +455,7 @@ func (ds ObjectRefDataSource) StoreToDVCR(ctx context.Context, vi *v1alpha2.Virt cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Import is in the process of provisioning to DVCR.") + Message("The image is being imported.") vi.Status.Phase = v1alpha2.ImageProvisioning vi.Status.Target.RegistryURL = ds.statService.GetDVCRImageName(pod) diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vd.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vd.go index 9a0840fe42..fa9500bbe2 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vd.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vd.go @@ -138,7 +138,7 @@ func (ds ObjectRefVirtualDisk) StoreToDVCR(ctx context.Context, vi *v1alpha2.Vir cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("DVCR Provisioner not found: create the new one.") + Message("Importing the image.") log.Info("Create importer pod...", "progress", vi.Status.Progress, "pod.phase", "nil") @@ -206,7 +206,7 @@ func (ds ObjectRefVirtualDisk) StoreToDVCR(ctx context.Context, vi *v1alpha2.Vir cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Import is in the process of provisioning to DVCR.") + Message("The image is being imported.") vi.Status.Phase = v1alpha2.ImageProvisioning vi.Status.Progress = ds.statService.GetProgress(vi.GetUID(), pod, vi.Status.Progress) @@ -298,7 +298,7 @@ func (ds ObjectRefVirtualDisk) StoreToPVC(ctx context.Context, vi *v1alpha2.Virt cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("PVC Provisioner not found: create the new one.") + Message("Preparing the disk storage for the image.") return reconcile.Result{RequeueAfter: time.Second}, nil case dvQuotaNotExceededCondition != nil && dvQuotaNotExceededCondition.Status == corev1.ConditionFalse: diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vi_on_pvc.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vi_on_pvc.go index ad56a5175c..f1e92f4ca9 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vi_on_pvc.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vi_on_pvc.go @@ -129,7 +129,7 @@ func (ds ObjectRefDataVirtualImageOnPVC) StoreToDVCR(ctx context.Context, vi, vi cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("DVCR Provisioner not found: create the new one.") + Message("Importing the image.") log.Info("Create importer pod...", "progress", vi.Status.Progress, "pod.phase", "nil") @@ -179,7 +179,7 @@ func (ds ObjectRefDataVirtualImageOnPVC) StoreToDVCR(ctx context.Context, vi, vi cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Import is in the process of provisioning to DVCR.") + Message("The image is being imported.") vi.Status.Phase = v1alpha2.ImageProvisioning vi.Status.Progress = ds.statService.GetProgress(vi.GetUID(), pod, vi.Status.Progress) @@ -276,7 +276,7 @@ func (ds ObjectRefDataVirtualImageOnPVC) StoreToPVC(ctx context.Context, vi, viR cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("PVC Provisioner not found: create the new one.") + Message("Preparing the disk storage for the image.") return reconcile.Result{RequeueAfter: time.Second}, nil case dvQuotaNotExceededCondition != nil && dvQuotaNotExceededCondition.Status == corev1.ConditionFalse: diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/registry.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/registry.go index 6669fc7f6b..7b9bc0f6b8 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/registry.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/registry.go @@ -152,7 +152,7 @@ func (ds RegistryDataSource) StoreToPVC(ctx context.Context, vi *v1alpha2.Virtua cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("DVCR Provisioner not found: create the new one.") + Message("Importing the image.") return reconcile.Result{RequeueAfter: time.Second}, nil case !podutil.IsPodComplete(pod): @@ -167,7 +167,7 @@ func (ds RegistryDataSource) StoreToPVC(ctx context.Context, vi *v1alpha2.Virtua cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("DVCR Provisioner not found: create the new one.") + Message("Importing the image.") vi.Status.Progress = ds.statService.GetProgress(vi.GetUID(), pod, vi.Status.Progress, service.NewScaleOption(0, 50)) @@ -225,7 +225,7 @@ func (ds RegistryDataSource) StoreToPVC(ctx context.Context, vi *v1alpha2.Virtua cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("PVC Provisioner not found: create the new one.") + Message("Preparing the disk storage for the image.") return reconcile.Result{RequeueAfter: time.Second}, nil case dvQuotaNotExceededCondition != nil && dvQuotaNotExceededCondition.Status == corev1.ConditionFalse: @@ -340,7 +340,7 @@ func (ds RegistryDataSource) StoreToDVCR(ctx context.Context, vi *v1alpha2.Virtu cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("DVCR Provisioner not found: create the new one.") + Message("Importing the image.") log.Info("Create importer pod...", "progress", vi.Status.Progress, "pod.phase", "nil") @@ -392,7 +392,7 @@ func (ds RegistryDataSource) StoreToDVCR(ctx context.Context, vi *v1alpha2.Virtu cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Import is in the process of provisioning to DVCR.") + Message("The image is being imported.") vi.Status.Phase = v1alpha2.ImageProvisioning vi.Status.Progress = "0%" diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/sources.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/sources.go index 5292845849..ec3b0f9f05 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/sources.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/sources.go @@ -156,7 +156,7 @@ func setPhaseConditionForPVCProvisioningImage( cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Waiting for the pvc importer to be created") + Message("Preparing to provision the disk storage.") return nil } diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/sources_test.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/sources_test.go index 76686dc8dd..d5a12a9454 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/sources_test.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/sources_test.go @@ -242,7 +242,7 @@ var _ = Describe("Sources helpers", func() { Expect(cb.Condition().Reason).To(Equal(expectedReason)) Expect(cb.Condition().Message).To(Equal(expectedMessage)) }, - Entry("waits for pvc importer creation when dv is absent", nil, nil, v1alpha2.ImageProvisioning, metav1.ConditionFalse, vicondition.Provisioning.String(), "Waiting for the pvc importer to be created", nil), + Entry("waits for pvc importer creation when dv is absent", nil, nil, v1alpha2.ImageProvisioning, metav1.ConditionFalse, vicondition.Provisioning.String(), "Preparing to provision the disk storage.", nil), Entry("reports provisioning in progress", &cdiv1.DataVolume{}, nil, v1alpha2.ImageProvisioning, metav1.ConditionFalse, vicondition.Provisioning.String(), "Import is in the process of provisioning to PVC.", nil), Entry("handles data volume not running", &cdiv1.DataVolume{}, service.ErrDataVolumeNotRunning, v1alpha2.ImageProvisioning, metav1.ConditionFalse, vicondition.ProvisioningFailed.String(), "Pvc importer is not running", nil), Entry("handles missing default storage class", &cdiv1.DataVolume{}, service.ErrDefaultStorageClassNotFound, v1alpha2.ImagePending, metav1.ConditionFalse, vicondition.ProvisioningFailed.String(), "Default StorageClass not found in the cluster: please provide a StorageClass name or set a default StorageClass.", nil), diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/step/create_bounder_pod_step.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/step/create_bounder_pod_step.go index 5e6719959d..4526ec1877 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/step/create_bounder_pod_step.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/step/create_bounder_pod_step.go @@ -99,7 +99,7 @@ func (s CreateBounderPodStep) Take(ctx context.Context, vi *v1alpha2.VirtualImag s.cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Bounder pod has created: waiting to be Bound.") + Message("Waiting for the disk storage to be Bound.") return nil, nil } diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/step/create_bounder_pod_step_test.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/step/create_bounder_pod_step_test.go index fe1552ab81..5dd453ea9f 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/step/create_bounder_pod_step_test.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/step/create_bounder_pod_step_test.go @@ -166,7 +166,7 @@ var _ = Describe("CreateBounderPodStep", func() { 0, v1alpha2.ImagePhase(""), vicondition.Provisioning.String(), - "Bounder pod has created: waiting to be Bound.", + "Waiting for the disk storage to be Bound.", time.Duration(0), ), Entry("handles quota exceeded error", diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/step/wait_for_pod_step.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/step/wait_for_pod_step.go index bc8ee88471..f17c8ce298 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/step/wait_for_pod_step.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/step/wait_for_pod_step.go @@ -66,7 +66,7 @@ func (s WaitForPodStep) Take(_ context.Context, vi *v1alpha2.VirtualImage) (*rec s.cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Waiting for the importer pod to be created by controller.") + Message("Preparing to import the image.") return &reconcile.Result{}, nil } @@ -112,7 +112,7 @@ func (s WaitForPodStep) Take(_ context.Context, vi *v1alpha2.VirtualImage) (*rec s.cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Preparing to start import to DVCR.") + Message("Preparing to import the image.") vi.Status.Phase = v1alpha2.ImageProvisioning vi.Status.Target.RegistryURL = s.stat.GetDVCRImageName(s.pod) @@ -123,7 +123,7 @@ func (s WaitForPodStep) Take(_ context.Context, vi *v1alpha2.VirtualImage) (*rec s.cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Import is in the process of provisioning to DVCR.") + Message("The image is being imported.") vi.Status.Phase = v1alpha2.ImageProvisioning vi.Status.Progress = s.stat.GetProgress(vi.GetUID(), s.pod, vi.Status.Progress) diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/step/wait_for_pod_step_test.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/step/wait_for_pod_step_test.go index ac53665bed..456ca09d19 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/step/wait_for_pod_step_test.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/step/wait_for_pod_step_test.go @@ -103,7 +103,7 @@ var _ = Describe("WaitForPodStep", func() { reconcile.Result{}, v1alpha2.ImageProvisioning, vicondition.Provisioning.String(), - "Waiting for the importer pod to be created by controller.", + "Preparing to import the image.", "", "", ), @@ -158,7 +158,7 @@ var _ = Describe("WaitForPodStep", func() { reconcile.Result{}, v1alpha2.ImageProvisioning, vicondition.Provisioning.String(), - "Preparing to start import to DVCR.", + "Preparing to import the image.", "registry/image:pending", "", ), @@ -169,7 +169,7 @@ var _ = Describe("WaitForPodStep", func() { reconcile.Result{RequeueAfter: 2 * time.Second}, v1alpha2.ImageProvisioning, vicondition.Provisioning.String(), - "Import is in the process of provisioning to DVCR.", + "The image is being imported.", "registry/image:running", "45%", ), diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/step/wait_for_pvc_step.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/step/wait_for_pvc_step.go index 5dc2e51e66..8089cfb63a 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/step/wait_for_pvc_step.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/step/wait_for_pvc_step.go @@ -51,7 +51,7 @@ func (s WaitForPVCStep) Take(_ context.Context, vi *v1alpha2.VirtualImage) (*rec s.cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Waiting for the underlying PersistentVolumeClaim to be created by controller.") + Message("Waiting for the underlying PersistentVolumeClaim to be created.") return &reconcile.Result{}, nil } @@ -64,7 +64,7 @@ func (s WaitForPVCStep) Take(_ context.Context, vi *v1alpha2.VirtualImage) (*rec s.cb. Status(metav1.ConditionFalse). Reason(vdcondition.Provisioning). - Message(fmt.Sprintf("Waiting for the PVC %s to be Bound.", s.pvc.Name)) + Message(fmt.Sprintf("Waiting for the PersistentVolumeClaim %q to be Bound.", s.pvc.Name)) return &reconcile.Result{}, nil } diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/step/wait_for_pvc_step_test.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/step/wait_for_pvc_step_test.go index a514e04c5b..d4b1f10769 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/step/wait_for_pvc_step_test.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/step/wait_for_pvc_step_test.go @@ -63,7 +63,7 @@ var _ = Describe("WaitForPVCStep", func() { v1alpha2.ImageProvisioning, metav1.ConditionFalse, vicondition.Provisioning.String(), - "Waiting for the underlying PersistentVolumeClaim to be created by controller.", + "Waiting for the underlying PersistentVolumeClaim to be created.", true, ), Entry("returns nil for bound pvc", @@ -82,7 +82,7 @@ var _ = Describe("WaitForPVCStep", func() { v1alpha2.ImageProvisioning, metav1.ConditionFalse, vdcondition.Provisioning.String(), - "Waiting for the PVC image-pvc to be Bound.", + "Waiting for the PersistentVolumeClaim \"image-pvc\" to be Bound.", true, ), ) diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/upload.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/upload.go index 2404cccea4..4310905899 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/upload.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/upload.go @@ -174,7 +174,7 @@ func (ds UploadDataSource) StoreToPVC(ctx context.Context, vi *v1alpha2.VirtualI cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("DVCR Provisioner not found: create the new one.") + Message("Importing the image.") return reconcile.Result{RequeueAfter: time.Second}, nil case !podutil.IsPodComplete(pod): @@ -216,7 +216,7 @@ func (ds UploadDataSource) StoreToPVC(ctx context.Context, vi *v1alpha2.VirtualI cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Import is in the process of provisioning to DVCR.") + Message("The image is being imported.") vi.Status.Progress = ds.statService.GetProgress(vi.GetUID(), pod, vi.Status.Progress, service.NewScaleOption(0, 50)) vi.Status.DownloadSpeed = ds.statService.GetDownloadSpeed(vi.GetUID(), pod) @@ -281,7 +281,7 @@ func (ds UploadDataSource) StoreToPVC(ctx context.Context, vi *v1alpha2.VirtualI cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("PVC Provisioner not found: create the new one.") + Message("Preparing the disk storage for the image.") return reconcile.Result{RequeueAfter: time.Second}, nil case dvQuotaNotExceededCondition != nil && dvQuotaNotExceededCondition.Status == corev1.ConditionFalse: @@ -420,7 +420,7 @@ func (ds UploadDataSource) StoreToDVCR(ctx context.Context, vi *v1alpha2.Virtual cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("DVCR Provisioner not found: create the new one.") + Message("Importing the image.") log.Info("Create uploader pod...", "progress", vi.Status.Progress, "pod.phase", nil) @@ -465,7 +465,7 @@ func (ds UploadDataSource) StoreToDVCR(ctx context.Context, vi *v1alpha2.Virtual cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Import is in the process of provisioning to DVCR.") + Message("The image is being imported.") vi.Status.Phase = v1alpha2.ImageProvisioning vi.Status.Progress = ds.statService.GetProgress(vi.GetUID(), pod, vi.Status.Progress) From 5c66cdbb61eede3cef37a49de4d32e9cf75ddecc Mon Sep 17 00:00:00 2001 From: Pavel Tishkov Date: Tue, 30 Jun 2026 12:51:21 +0300 Subject: [PATCH 05/25] fix(cvi): make condition messages user-friendly Reword ClusterVirtualImage status messages to user terms: replace DVCR provisioner and PVC wording with image provisioning and snapshot volume restore, drop the internal registry URL, and fix the upload-wait text. Signed-off-by: Pavel Tishkov --- .../pkg/controller/cvi/internal/image_presence.go | 2 +- .../pkg/controller/cvi/internal/source/http.go | 4 ++-- .../pkg/controller/cvi/internal/source/object_ref.go | 6 +++--- .../pkg/controller/cvi/internal/source/object_ref_vd.go | 4 ++-- .../cvi/internal/source/object_ref_vdsnapshot.go | 8 ++++---- .../cvi/internal/source/object_ref_vi_on_pvc.go | 4 ++-- .../pkg/controller/cvi/internal/source/registry.go | 4 ++-- .../pkg/controller/cvi/internal/source/upload.go | 6 +++--- 8 files changed, 19 insertions(+), 19 deletions(-) diff --git a/images/virtualization-artifact/pkg/controller/cvi/internal/image_presence.go b/images/virtualization-artifact/pkg/controller/cvi/internal/image_presence.go index a9a2901936..53622d0c86 100644 --- a/images/virtualization-artifact/pkg/controller/cvi/internal/image_presence.go +++ b/images/virtualization-artifact/pkg/controller/cvi/internal/image_presence.go @@ -61,7 +61,7 @@ func (h *ImagePresenceHandler) Handle(ctx context.Context, cvi *v1alpha2.Cluster Generation(cvi.Generation). Status(metav1.ConditionFalse). Reason(cvicondition.ImageLost). - Message(fmt.Sprintf("Image %q not found in DVCR.", registryURL)) + Message("The image data is no longer available in the cluster storage and needs to be recreated.") conditions.SetCondition(cb, &cvi.Status.Conditions) } diff --git a/images/virtualization-artifact/pkg/controller/cvi/internal/source/http.go b/images/virtualization-artifact/pkg/controller/cvi/internal/source/http.go index d6b105c4b8..4656a5fb66 100644 --- a/images/virtualization-artifact/pkg/controller/cvi/internal/source/http.go +++ b/images/virtualization-artifact/pkg/controller/cvi/internal/source/http.go @@ -136,7 +136,7 @@ func (ds HTTPDataSource) Sync(ctx context.Context, cvi *v1alpha2.ClusterVirtualI cvi.Status.Phase = v1alpha2.ImageProvisioning cb.Status(metav1.ConditionFalse). Reason(cvicondition.Provisioning). - Message("DVCR Provisioner not found: create the new one.") + Message("Image provisioning has started.") log.Info("Create importer pod...", "progress", cvi.Status.Progress, "pod.phase", "nil") @@ -207,7 +207,7 @@ func (ds HTTPDataSource) Sync(ctx context.Context, cvi *v1alpha2.ClusterVirtualI cb.Status(metav1.ConditionFalse). Reason(cvicondition.Provisioning). - Message("Import is in the process of provisioning to DVCR.") + Message("The image is being provisioned.") cvi.Status.Phase = v1alpha2.ImageProvisioning cvi.Status.Progress = ds.statService.GetProgress(cvi.GetUID(), pod, cvi.Status.Progress) diff --git a/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref.go b/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref.go index a2d6dc4c5d..794195d10a 100644 --- a/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref.go +++ b/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref.go @@ -205,7 +205,7 @@ func (ds ObjectRefDataSource) Sync(ctx context.Context, cvi *v1alpha2.ClusterVir cb. Status(metav1.ConditionFalse). Reason(cvicondition.Provisioning). - Message("DVCR Provisioner not found: create the new one.") + Message("Image provisioning has started.") log.Info("Ready", "progress", cvi.Status.Progress, "pod.phase", "nil") @@ -245,7 +245,7 @@ func (ds ObjectRefDataSource) Sync(ctx context.Context, cvi *v1alpha2.ClusterVir cb. Status(metav1.ConditionFalse). Reason(cvicondition.ProvisioningFailed). - Message("Failed to get stats from non-ready datasource: waiting for the DataSource to be ready.") + Message("Waiting for the source data to become ready.") return reconcile.Result{}, nil } @@ -283,7 +283,7 @@ func (ds ObjectRefDataSource) Sync(ctx context.Context, cvi *v1alpha2.ClusterVir cb. Status(metav1.ConditionFalse). Reason(cvicondition.Provisioning). - Message("Import is in the process of provisioning to DVCR.") + Message("The image is being provisioned.") cvi.Status.Phase = v1alpha2.ImageProvisioning cvi.Status.Target.RegistryURL = ds.statService.GetDVCRImageName(pod) diff --git a/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vd.go b/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vd.go index 98ed958994..61f28d3b60 100644 --- a/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vd.go +++ b/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vd.go @@ -136,7 +136,7 @@ func (ds ObjectRefVirtualDisk) Sync(ctx context.Context, cvi *v1alpha2.ClusterVi cb. Status(metav1.ConditionFalse). Reason(cvicondition.Provisioning). - Message("DVCR Provisioner not found: create the new one.") + Message("Image provisioning has started.") log.Info("Create importer pod...", "progress", cvi.Status.Progress, "pod.phase", "nil") @@ -204,7 +204,7 @@ func (ds ObjectRefVirtualDisk) Sync(ctx context.Context, cvi *v1alpha2.ClusterVi cb. Status(metav1.ConditionFalse). Reason(cvicondition.Provisioning). - Message("Import is in the process of provisioning to DVCR.") + Message("The image is being provisioned.") cvi.Status.Phase = v1alpha2.ImageProvisioning cvi.Status.Progress = ds.statService.GetProgress(cvi.GetUID(), pod, cvi.Status.Progress) diff --git a/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vdsnapshot.go b/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vdsnapshot.go index 55e5a34afc..876078b96d 100644 --- a/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vdsnapshot.go +++ b/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vdsnapshot.go @@ -196,7 +196,7 @@ func (ds ObjectRefVirtualDiskSnapshot) Sync(ctx context.Context, cvi *v1alpha2.C cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("PVC has created: waiting to be Bound.") + Message("Restoring data from the snapshot. Waiting for the volume to be ready.") cvi.Status.Progress = "0%" cvi.Status.SourceUID = ptr.To(vs.UID) @@ -226,7 +226,7 @@ func (ds ObjectRefVirtualDiskSnapshot) Sync(ctx context.Context, cvi *v1alpha2.C cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("DVCR Provisioner not found: create the new one.") + Message("Image provisioning has started.") log.Info("Create importer pod...", "progress", cvi.Status.Progress, "pod.phase", "nil") @@ -274,7 +274,7 @@ func (ds ObjectRefVirtualDiskSnapshot) Sync(ctx context.Context, cvi *v1alpha2.C cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Waiting for PVC to be bound") + Message("Restoring data from the snapshot. Waiting for the volume to be provisioned.") return reconcile.Result{RequeueAfter: time.Second}, nil } @@ -304,7 +304,7 @@ func (ds ObjectRefVirtualDiskSnapshot) Sync(ctx context.Context, cvi *v1alpha2.C cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Import is in the process of provisioning to DVCR.") + Message("The image is being provisioned.") cvi.Status.Phase = v1alpha2.ImageProvisioning cvi.Status.Progress = ds.statService.GetProgress(cvi.GetUID(), pod, cvi.Status.Progress) diff --git a/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vi_on_pvc.go b/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vi_on_pvc.go index f53550cbab..d6c6eff6ac 100644 --- a/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vi_on_pvc.go +++ b/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vi_on_pvc.go @@ -125,7 +125,7 @@ func (ds ObjectRefVirtualImageOnPvc) Sync(ctx context.Context, cvi *v1alpha2.Clu cb. Status(metav1.ConditionFalse). Reason(cvicondition.Provisioning). - Message("DVCR Provisioner not found: create the new one.") + Message("Image provisioning has started.") log.Info("Create importer pod...", "progress", cvi.Status.Progress, "pod.phase", "nil") @@ -193,7 +193,7 @@ func (ds ObjectRefVirtualImageOnPvc) Sync(ctx context.Context, cvi *v1alpha2.Clu cb. Status(metav1.ConditionFalse). Reason(cvicondition.Provisioning). - Message("Import is in the process of provisioning to DVCR.") + Message("The image is being provisioned.") cvi.Status.Phase = v1alpha2.ImageProvisioning cvi.Status.Progress = ds.statService.GetProgress(cvi.GetUID(), pod, cvi.Status.Progress) diff --git a/images/virtualization-artifact/pkg/controller/cvi/internal/source/registry.go b/images/virtualization-artifact/pkg/controller/cvi/internal/source/registry.go index f3566eba60..e4f09e2bdb 100644 --- a/images/virtualization-artifact/pkg/controller/cvi/internal/source/registry.go +++ b/images/virtualization-artifact/pkg/controller/cvi/internal/source/registry.go @@ -142,7 +142,7 @@ func (ds RegistryDataSource) Sync(ctx context.Context, cvi *v1alpha2.ClusterVirt cb. Status(metav1.ConditionFalse). Reason(cvicondition.Provisioning). - Message("DVCR Provisioner not found: create the new one.") + Message("Image provisioning has started.") log.Info("Create importer pod...", "progress", cvi.Status.Progress, "pod.phase", "nil") @@ -212,7 +212,7 @@ func (ds RegistryDataSource) Sync(ctx context.Context, cvi *v1alpha2.ClusterVirt cb. Status(metav1.ConditionFalse). Reason(cvicondition.Provisioning). - Message("Import is in the process of provisioning to DVCR.") + Message("The image is being provisioned.") cvi.Status.Phase = v1alpha2.ImageProvisioning cvi.Status.Progress = "0%" diff --git a/images/virtualization-artifact/pkg/controller/cvi/internal/source/upload.go b/images/virtualization-artifact/pkg/controller/cvi/internal/source/upload.go index 5f3d5c6d0b..cffdf6392a 100644 --- a/images/virtualization-artifact/pkg/controller/cvi/internal/source/upload.go +++ b/images/virtualization-artifact/pkg/controller/cvi/internal/source/upload.go @@ -151,7 +151,7 @@ func (ds UploadDataSource) Sync(ctx context.Context, cvi *v1alpha2.ClusterVirtua cb. Status(metav1.ConditionFalse). Reason(cvicondition.Provisioning). - Message("DVCR Provisioner not found: create the new one.") + Message("Image provisioning has started.") log.Info("Create uploader pod...", "progress", cvi.Status.Progress, "pod.phase", nil) @@ -222,7 +222,7 @@ func (ds UploadDataSource) Sync(ctx context.Context, cvi *v1alpha2.ClusterVirtua cb. Status(metav1.ConditionFalse). Reason(cvicondition.Provisioning). - Message("Import is in the process of provisioning to DVCR.") + Message("The image is being provisioned.") cvi.Status.Phase = v1alpha2.ImageProvisioning cvi.Status.Progress = ds.statService.GetProgress(cvi.GetUID(), pod, cvi.Status.Progress) @@ -239,7 +239,7 @@ func (ds UploadDataSource) Sync(ctx context.Context, cvi *v1alpha2.ClusterVirtua cb. Status(metav1.ConditionFalse). Reason(cvicondition.WaitForUserUpload). - Message("Waiting for the user upload.") + Message("Waiting for the user to upload image data.") cvi.Status.Phase = v1alpha2.ImageWaitForUserUpload cvi.Status.Target.RegistryURL = ds.statService.GetDVCRImageName(pod) From 3f2aeaed47604fa6e4b07ccf9f5889934f5bee32 Mon Sep 17 00:00:00 2001 From: Pavel Tishkov Date: Tue, 30 Jun 2026 12:54:34 +0300 Subject: [PATCH 06/25] fix(vdsnapshot): fix grammar in condition messages Fix grammar and a typo in VirtualDiskSnapshot status messages and stop referencing the internal volume snapshot object. Signed-off-by: Pavel Tishkov --- .../pkg/controller/vdsnapshot/internal/life_cycle.go | 4 ++-- .../pkg/controller/vdsnapshot/internal/virtual_disk_ready.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/images/virtualization-artifact/pkg/controller/vdsnapshot/internal/life_cycle.go b/images/virtualization-artifact/pkg/controller/vdsnapshot/internal/life_cycle.go index 04f9863892..21b396744d 100644 --- a/images/virtualization-artifact/pkg/controller/vdsnapshot/internal/life_cycle.go +++ b/images/virtualization-artifact/pkg/controller/vdsnapshot/internal/life_cycle.go @@ -109,7 +109,7 @@ func (h LifeCycleHandler) Handle(ctx context.Context, vdSnapshot *v1alpha2.Virtu cb. Status(metav1.ConditionFalse). Reason(vdscondition.VolumeSnapshotLost). - Message(fmt.Sprintf("The underlying volume snapshot %q is not ready to use.", vdSnapshot.Status.VolumeSnapshotName)) + Message("The snapshot is no longer available.") return reconcile.Result{Requeue: true}, nil } @@ -392,7 +392,7 @@ func (h LifeCycleHandler) Handle(ctx context.Context, vdSnapshot *v1alpha2.Virtu cb. Status(metav1.ConditionFalse). Reason(vdscondition.Snapshotting). - Message(fmt.Sprintf("Waiting fot the volume snapshot %q to be ready to use.", vdSnapshot.Name)) + Message(fmt.Sprintf("Waiting for the snapshot of virtual disk %q to be ready to use.", vdSnapshot.Name)) return reconcile.Result{}, nil default: log.Debug("The volume snapshot is ready to use") diff --git a/images/virtualization-artifact/pkg/controller/vdsnapshot/internal/virtual_disk_ready.go b/images/virtualization-artifact/pkg/controller/vdsnapshot/internal/virtual_disk_ready.go index 29af8d6d7a..586b932191 100644 --- a/images/virtualization-artifact/pkg/controller/vdsnapshot/internal/virtual_disk_ready.go +++ b/images/virtualization-artifact/pkg/controller/vdsnapshot/internal/virtual_disk_ready.go @@ -69,7 +69,7 @@ func (h VirtualDiskReadyHandler) Handle(ctx context.Context, vdSnapshot *v1alpha cb. Status(metav1.ConditionFalse). Reason(vdscondition.VirtualDiskNotReadyForSnapshotting). - Message(fmt.Sprintf("The virtual disk %q not found.", vdSnapshot.Spec.VirtualDiskName)) + Message(fmt.Sprintf("The virtual disk %q was not found.", vdSnapshot.Spec.VirtualDiskName)) return reconcile.Result{}, nil } @@ -77,7 +77,7 @@ func (h VirtualDiskReadyHandler) Handle(ctx context.Context, vdSnapshot *v1alpha cb. Status(metav1.ConditionFalse). Reason(vdscondition.VirtualDiskNotReadyForSnapshotting). - Message(fmt.Sprintf("The virtual disk %q is in process of deletion.", vd.Name)) + Message(fmt.Sprintf("The virtual disk %q is in the process of deletion.", vd.Name)) return reconcile.Result{}, nil } From 78fb85ed685ac9c20dbf7c2c39c5dbc63282be3f Mon Sep 17 00:00:00 2001 From: Pavel Tishkov Date: Tue, 30 Jun 2026 12:54:34 +0300 Subject: [PATCH 07/25] fix(vmsnapshot): fix grammar in condition messages Fix grammar in VirtualMachineSnapshot status messages ("was not found", "in the process of deletion"). Signed-off-by: Pavel Tishkov --- .../controller/vmsnapshot/internal/virtual_machine_ready.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/images/virtualization-artifact/pkg/controller/vmsnapshot/internal/virtual_machine_ready.go b/images/virtualization-artifact/pkg/controller/vmsnapshot/internal/virtual_machine_ready.go index 9bd8cecda8..894c678b17 100644 --- a/images/virtualization-artifact/pkg/controller/vmsnapshot/internal/virtual_machine_ready.go +++ b/images/virtualization-artifact/pkg/controller/vmsnapshot/internal/virtual_machine_ready.go @@ -70,7 +70,7 @@ func (h VirtualMachineReadyHandler) Handle(ctx context.Context, vmSnapshot *v1al cb. Status(metav1.ConditionFalse). Reason(vmscondition.VirtualMachineNotReadyForSnapshotting). - Message(fmt.Sprintf("The virtual machine %q not found.", vmSnapshot.Spec.VirtualMachineName)) + Message(fmt.Sprintf("The virtual machine %q was not found.", vmSnapshot.Spec.VirtualMachineName)) return reconcile.Result{}, nil } @@ -78,7 +78,7 @@ func (h VirtualMachineReadyHandler) Handle(ctx context.Context, vmSnapshot *v1al cb. Status(metav1.ConditionFalse). Reason(vmscondition.VirtualMachineNotReadyForSnapshotting). - Message(fmt.Sprintf("The virtual machine %q is in process of deletion.", vm.Name)) + Message(fmt.Sprintf("The virtual machine %q is in the process of deletion.", vm.Name)) return reconcile.Result{}, nil } From 48f8f2603e5efa9e01a5c85b95f6de2252c180f0 Mon Sep 17 00:00:00 2001 From: Pavel Tishkov Date: Tue, 30 Jun 2026 13:01:17 +0300 Subject: [PATCH 08/25] fix(vmbda): say the VirtualMachine is not running The attach-precondition messages now state that the VirtualMachine is not running, instead of implying it is mid-start, which is misleading for a stopped machine and inconsistent with the rest of the wording. Signed-off-by: Pavel Tishkov --- .../pkg/controller/vmbda/internal/life_cycle.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/images/virtualization-artifact/pkg/controller/vmbda/internal/life_cycle.go b/images/virtualization-artifact/pkg/controller/vmbda/internal/life_cycle.go index 54062c5e1a..2abc766061 100644 --- a/images/virtualization-artifact/pkg/controller/vmbda/internal/life_cycle.go +++ b/images/virtualization-artifact/pkg/controller/vmbda/internal/life_cycle.go @@ -173,7 +173,7 @@ func (h LifeCycleHandler) Handle(ctx context.Context, vmbda *v1alpha2.VirtualMac cb. Status(metav1.ConditionFalse). Reason(vmbdacondition.NotAttached). - Message(fmt.Sprintf("VirtualMachine %q is not fully started yet.", vm.Name)) + Message(fmt.Sprintf("VirtualMachine %q is not running.", vm.Name)) return reconcile.Result{}, nil } @@ -187,7 +187,7 @@ func (h LifeCycleHandler) Handle(ctx context.Context, vmbda *v1alpha2.VirtualMac cb. Status(metav1.ConditionFalse). Reason(vmbdacondition.NotAttached). - Message(fmt.Sprintf("VirtualMachine %q is not fully started yet.", vm.Name)) + Message(fmt.Sprintf("VirtualMachine %q is not running.", vm.Name)) return reconcile.Result{}, nil } From 5f564fa763517946b78728d1b4a362bb2f2f7771 Mon Sep 17 00:00:00 2001 From: Pavel Tishkov Date: Tue, 30 Jun 2026 13:03:55 +0300 Subject: [PATCH 09/25] fix(vmbda): keep the node name in the storage-availability message Keep the node name where the disk storage is missing: it is the actionable detail an operator needs to debug the attachment, and the node is a public object the user can inspect. Signed-off-by: Pavel Tishkov --- .../pkg/controller/vmbda/internal/life_cycle.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/virtualization-artifact/pkg/controller/vmbda/internal/life_cycle.go b/images/virtualization-artifact/pkg/controller/vmbda/internal/life_cycle.go index 2abc766061..f17d6bff94 100644 --- a/images/virtualization-artifact/pkg/controller/vmbda/internal/life_cycle.go +++ b/images/virtualization-artifact/pkg/controller/vmbda/internal/life_cycle.go @@ -263,7 +263,7 @@ func (h LifeCycleHandler) Handle(ctx context.Context, vmbda *v1alpha2.VirtualMac cb. Status(metav1.ConditionFalse). Reason(vmbdacondition.DeviceNotAvailableOnNode). - Message("The disk storage is not available on the node where the VirtualMachine is currently running.") + Message(fmt.Sprintf("The disk storage is not available on node %q where the VirtualMachine is running.", kvvmi.Status.NodeName)) return reconcile.Result{}, nil } } From 9477ff3d81361184ab5dbd9393c1d14674c9753f Mon Sep 17 00:00:00 2001 From: Pavel Tishkov Date: Tue, 30 Jun 2026 13:07:56 +0300 Subject: [PATCH 10/25] fix(vi, cvi): unify image provisioning and image-lost wording Use the same user-facing wording for the same state across VirtualImage and ClusterVirtualImage: image import preparing/in-progress and the image-no-longer-available message now read identically. Signed-off-by: Pavel Tishkov --- .../pkg/controller/cvi/internal/image_presence.go | 2 +- .../pkg/controller/cvi/internal/source/http.go | 4 ++-- .../pkg/controller/cvi/internal/source/object_ref.go | 4 ++-- .../pkg/controller/cvi/internal/source/object_ref_vd.go | 4 ++-- .../controller/cvi/internal/source/object_ref_vdsnapshot.go | 4 ++-- .../controller/cvi/internal/source/object_ref_vi_on_pvc.go | 4 ++-- .../pkg/controller/cvi/internal/source/registry.go | 4 ++-- .../pkg/controller/cvi/internal/source/upload.go | 4 ++-- .../pkg/controller/vi/internal/image_presence.go | 2 +- .../pkg/controller/vi/internal/source/http.go | 6 +++--- .../pkg/controller/vi/internal/source/object_ref.go | 2 +- .../pkg/controller/vi/internal/source/object_ref_vd.go | 2 +- .../controller/vi/internal/source/object_ref_vi_on_pvc.go | 2 +- .../pkg/controller/vi/internal/source/registry.go | 6 +++--- .../pkg/controller/vi/internal/source/upload.go | 4 ++-- 15 files changed, 27 insertions(+), 27 deletions(-) diff --git a/images/virtualization-artifact/pkg/controller/cvi/internal/image_presence.go b/images/virtualization-artifact/pkg/controller/cvi/internal/image_presence.go index 53622d0c86..22fcf1ad26 100644 --- a/images/virtualization-artifact/pkg/controller/cvi/internal/image_presence.go +++ b/images/virtualization-artifact/pkg/controller/cvi/internal/image_presence.go @@ -61,7 +61,7 @@ func (h *ImagePresenceHandler) Handle(ctx context.Context, cvi *v1alpha2.Cluster Generation(cvi.Generation). Status(metav1.ConditionFalse). Reason(cvicondition.ImageLost). - Message("The image data is no longer available in the cluster storage and needs to be recreated.") + Message("The image data is no longer available and needs to be recreated.") conditions.SetCondition(cb, &cvi.Status.Conditions) } diff --git a/images/virtualization-artifact/pkg/controller/cvi/internal/source/http.go b/images/virtualization-artifact/pkg/controller/cvi/internal/source/http.go index 4656a5fb66..d42aed6db9 100644 --- a/images/virtualization-artifact/pkg/controller/cvi/internal/source/http.go +++ b/images/virtualization-artifact/pkg/controller/cvi/internal/source/http.go @@ -136,7 +136,7 @@ func (ds HTTPDataSource) Sync(ctx context.Context, cvi *v1alpha2.ClusterVirtualI cvi.Status.Phase = v1alpha2.ImageProvisioning cb.Status(metav1.ConditionFalse). Reason(cvicondition.Provisioning). - Message("Image provisioning has started.") + Message("Preparing to import the image.") log.Info("Create importer pod...", "progress", cvi.Status.Progress, "pod.phase", "nil") @@ -207,7 +207,7 @@ func (ds HTTPDataSource) Sync(ctx context.Context, cvi *v1alpha2.ClusterVirtualI cb.Status(metav1.ConditionFalse). Reason(cvicondition.Provisioning). - Message("The image is being provisioned.") + Message("The image is being imported.") cvi.Status.Phase = v1alpha2.ImageProvisioning cvi.Status.Progress = ds.statService.GetProgress(cvi.GetUID(), pod, cvi.Status.Progress) diff --git a/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref.go b/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref.go index 794195d10a..1db6dffcb5 100644 --- a/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref.go +++ b/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref.go @@ -205,7 +205,7 @@ func (ds ObjectRefDataSource) Sync(ctx context.Context, cvi *v1alpha2.ClusterVir cb. Status(metav1.ConditionFalse). Reason(cvicondition.Provisioning). - Message("Image provisioning has started.") + Message("Preparing to import the image.") log.Info("Ready", "progress", cvi.Status.Progress, "pod.phase", "nil") @@ -283,7 +283,7 @@ func (ds ObjectRefDataSource) Sync(ctx context.Context, cvi *v1alpha2.ClusterVir cb. Status(metav1.ConditionFalse). Reason(cvicondition.Provisioning). - Message("The image is being provisioned.") + Message("The image is being imported.") cvi.Status.Phase = v1alpha2.ImageProvisioning cvi.Status.Target.RegistryURL = ds.statService.GetDVCRImageName(pod) diff --git a/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vd.go b/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vd.go index 61f28d3b60..72159c783d 100644 --- a/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vd.go +++ b/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vd.go @@ -136,7 +136,7 @@ func (ds ObjectRefVirtualDisk) Sync(ctx context.Context, cvi *v1alpha2.ClusterVi cb. Status(metav1.ConditionFalse). Reason(cvicondition.Provisioning). - Message("Image provisioning has started.") + Message("Preparing to import the image.") log.Info("Create importer pod...", "progress", cvi.Status.Progress, "pod.phase", "nil") @@ -204,7 +204,7 @@ func (ds ObjectRefVirtualDisk) Sync(ctx context.Context, cvi *v1alpha2.ClusterVi cb. Status(metav1.ConditionFalse). Reason(cvicondition.Provisioning). - Message("The image is being provisioned.") + Message("The image is being imported.") cvi.Status.Phase = v1alpha2.ImageProvisioning cvi.Status.Progress = ds.statService.GetProgress(cvi.GetUID(), pod, cvi.Status.Progress) diff --git a/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vdsnapshot.go b/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vdsnapshot.go index 876078b96d..a829ac6f28 100644 --- a/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vdsnapshot.go +++ b/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vdsnapshot.go @@ -226,7 +226,7 @@ func (ds ObjectRefVirtualDiskSnapshot) Sync(ctx context.Context, cvi *v1alpha2.C cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Image provisioning has started.") + Message("Preparing to import the image.") log.Info("Create importer pod...", "progress", cvi.Status.Progress, "pod.phase", "nil") @@ -304,7 +304,7 @@ func (ds ObjectRefVirtualDiskSnapshot) Sync(ctx context.Context, cvi *v1alpha2.C cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("The image is being provisioned.") + Message("The image is being imported.") cvi.Status.Phase = v1alpha2.ImageProvisioning cvi.Status.Progress = ds.statService.GetProgress(cvi.GetUID(), pod, cvi.Status.Progress) diff --git a/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vi_on_pvc.go b/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vi_on_pvc.go index d6c6eff6ac..43fee2c235 100644 --- a/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vi_on_pvc.go +++ b/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vi_on_pvc.go @@ -125,7 +125,7 @@ func (ds ObjectRefVirtualImageOnPvc) Sync(ctx context.Context, cvi *v1alpha2.Clu cb. Status(metav1.ConditionFalse). Reason(cvicondition.Provisioning). - Message("Image provisioning has started.") + Message("Preparing to import the image.") log.Info("Create importer pod...", "progress", cvi.Status.Progress, "pod.phase", "nil") @@ -193,7 +193,7 @@ func (ds ObjectRefVirtualImageOnPvc) Sync(ctx context.Context, cvi *v1alpha2.Clu cb. Status(metav1.ConditionFalse). Reason(cvicondition.Provisioning). - Message("The image is being provisioned.") + Message("The image is being imported.") cvi.Status.Phase = v1alpha2.ImageProvisioning cvi.Status.Progress = ds.statService.GetProgress(cvi.GetUID(), pod, cvi.Status.Progress) diff --git a/images/virtualization-artifact/pkg/controller/cvi/internal/source/registry.go b/images/virtualization-artifact/pkg/controller/cvi/internal/source/registry.go index e4f09e2bdb..9bf03d71a7 100644 --- a/images/virtualization-artifact/pkg/controller/cvi/internal/source/registry.go +++ b/images/virtualization-artifact/pkg/controller/cvi/internal/source/registry.go @@ -142,7 +142,7 @@ func (ds RegistryDataSource) Sync(ctx context.Context, cvi *v1alpha2.ClusterVirt cb. Status(metav1.ConditionFalse). Reason(cvicondition.Provisioning). - Message("Image provisioning has started.") + Message("Preparing to import the image.") log.Info("Create importer pod...", "progress", cvi.Status.Progress, "pod.phase", "nil") @@ -212,7 +212,7 @@ func (ds RegistryDataSource) Sync(ctx context.Context, cvi *v1alpha2.ClusterVirt cb. Status(metav1.ConditionFalse). Reason(cvicondition.Provisioning). - Message("The image is being provisioned.") + Message("The image is being imported.") cvi.Status.Phase = v1alpha2.ImageProvisioning cvi.Status.Progress = "0%" diff --git a/images/virtualization-artifact/pkg/controller/cvi/internal/source/upload.go b/images/virtualization-artifact/pkg/controller/cvi/internal/source/upload.go index cffdf6392a..fe568da5c5 100644 --- a/images/virtualization-artifact/pkg/controller/cvi/internal/source/upload.go +++ b/images/virtualization-artifact/pkg/controller/cvi/internal/source/upload.go @@ -151,7 +151,7 @@ func (ds UploadDataSource) Sync(ctx context.Context, cvi *v1alpha2.ClusterVirtua cb. Status(metav1.ConditionFalse). Reason(cvicondition.Provisioning). - Message("Image provisioning has started.") + Message("Preparing to import the image.") log.Info("Create uploader pod...", "progress", cvi.Status.Progress, "pod.phase", nil) @@ -222,7 +222,7 @@ func (ds UploadDataSource) Sync(ctx context.Context, cvi *v1alpha2.ClusterVirtua cb. Status(metav1.ConditionFalse). Reason(cvicondition.Provisioning). - Message("The image is being provisioned.") + Message("The image is being imported.") cvi.Status.Phase = v1alpha2.ImageProvisioning cvi.Status.Progress = ds.statService.GetProgress(cvi.GetUID(), pod, cvi.Status.Progress) diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/image_presence.go b/images/virtualization-artifact/pkg/controller/vi/internal/image_presence.go index a7dace4fb8..3050700afc 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/image_presence.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/image_presence.go @@ -76,7 +76,7 @@ func (h *ImagePresenceHandler) Handle(ctx context.Context, vi *v1alpha2.VirtualI Generation(vi.Generation). Status(metav1.ConditionFalse). Reason(vicondition.ImageLost). - Message("The image data is no longer available in the cluster registry.") + Message("The image data is no longer available and needs to be recreated.") conditions.SetCondition(cb, &vi.Status.Conditions) } diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/http.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/http.go index 29f3c17966..95ea9110a2 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/http.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/http.go @@ -124,7 +124,7 @@ func (ds HTTPDataSource) StoreToDVCR(ctx context.Context, vi *v1alpha2.VirtualIm cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Importing the image.") + Message("Preparing to import the image.") log.Info("Create importer pod...", "progress", vi.Status.Progress, "pod.phase", "nil") @@ -263,7 +263,7 @@ func (ds HTTPDataSource) StoreToPVC(ctx context.Context, vi *v1alpha2.VirtualIma cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Importing the image.") + Message("Preparing to import the image.") log.Info("Create importer pod...", "progress", vi.Status.Progress, "pod.phase", "nil") @@ -345,7 +345,7 @@ func (ds HTTPDataSource) StoreToPVC(ctx context.Context, vi *v1alpha2.VirtualIma cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Importing the image.") + Message("Preparing to import the image.") return reconcile.Result{RequeueAfter: time.Second}, nil case dvQuotaNotExceededCondition != nil && dvQuotaNotExceededCondition.Status == corev1.ConditionFalse: diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref.go index 2d9c97bc9f..647c0f51a6 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref.go @@ -397,7 +397,7 @@ func (ds ObjectRefDataSource) StoreToDVCR(ctx context.Context, vi *v1alpha2.Virt cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Importing the image.") + Message("Preparing to import the image.") log.Info("Ready", "progress", vi.Status.Progress, "pod.phase", "nil") diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vd.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vd.go index fa9500bbe2..3933245223 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vd.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vd.go @@ -138,7 +138,7 @@ func (ds ObjectRefVirtualDisk) StoreToDVCR(ctx context.Context, vi *v1alpha2.Vir cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Importing the image.") + Message("Preparing to import the image.") log.Info("Create importer pod...", "progress", vi.Status.Progress, "pod.phase", "nil") diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vi_on_pvc.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vi_on_pvc.go index f1e92f4ca9..d4b4097401 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vi_on_pvc.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vi_on_pvc.go @@ -129,7 +129,7 @@ func (ds ObjectRefDataVirtualImageOnPVC) StoreToDVCR(ctx context.Context, vi, vi cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Importing the image.") + Message("Preparing to import the image.") log.Info("Create importer pod...", "progress", vi.Status.Progress, "pod.phase", "nil") diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/registry.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/registry.go index 7b9bc0f6b8..2a3192a048 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/registry.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/registry.go @@ -152,7 +152,7 @@ func (ds RegistryDataSource) StoreToPVC(ctx context.Context, vi *v1alpha2.Virtua cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Importing the image.") + Message("Preparing to import the image.") return reconcile.Result{RequeueAfter: time.Second}, nil case !podutil.IsPodComplete(pod): @@ -167,7 +167,7 @@ func (ds RegistryDataSource) StoreToPVC(ctx context.Context, vi *v1alpha2.Virtua cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Importing the image.") + Message("Preparing to import the image.") vi.Status.Progress = ds.statService.GetProgress(vi.GetUID(), pod, vi.Status.Progress, service.NewScaleOption(0, 50)) @@ -340,7 +340,7 @@ func (ds RegistryDataSource) StoreToDVCR(ctx context.Context, vi *v1alpha2.Virtu cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Importing the image.") + Message("Preparing to import the image.") log.Info("Create importer pod...", "progress", vi.Status.Progress, "pod.phase", "nil") diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/upload.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/upload.go index 4310905899..dfb443e43a 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/upload.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/upload.go @@ -174,7 +174,7 @@ func (ds UploadDataSource) StoreToPVC(ctx context.Context, vi *v1alpha2.VirtualI cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Importing the image.") + Message("Preparing to import the image.") return reconcile.Result{RequeueAfter: time.Second}, nil case !podutil.IsPodComplete(pod): @@ -420,7 +420,7 @@ func (ds UploadDataSource) StoreToDVCR(ctx context.Context, vi *v1alpha2.Virtual cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Importing the image.") + Message("Preparing to import the image.") log.Info("Create uploader pod...", "progress", vi.Status.Progress, "pod.phase", nil) From daf7219c035086ce678bf621ebcfc75c4744cf97 Mon Sep 17 00:00:00 2001 From: Pavel Tishkov Date: Tue, 30 Jun 2026 13:26:09 +0300 Subject: [PATCH 11/25] fix(vd, vi, cvi, vmbda): make storage wording consistent Use one consistent vocabulary for storage states across disk, image and attachment resources: name the PersistentVolumeClaim/PersistentVolume in full (never PVC/PV abbreviations), say disk/image storage where the object is incidental, and use "ready" instead of the Bound phase term in storage phrasing. Also fixes two VirtualImage messages that still read PVC and leaked the internal claim name. Signed-off-by: Pavel Tishkov --- .../pkg/controller/vd/internal/migration.go | 10 +++++----- .../pkg/controller/vd/internal/source/http.go | 4 ++-- .../pkg/controller/vd/internal/source/registry.go | 4 ++-- .../controller/vd/internal/source/step/ready_step.go | 2 +- .../pkg/controller/vd/internal/source/upload.go | 4 ++-- .../pkg/controller/vi/internal/source/http.go | 2 +- .../pkg/controller/vi/internal/source/object_ref.go | 4 ++-- .../pkg/controller/vi/internal/source/object_ref_vd.go | 4 ++-- .../vi/internal/source/object_ref_vi_on_pvc.go | 4 ++-- .../pkg/controller/vi/internal/source/registry.go | 4 ++-- .../pkg/controller/vi/internal/source/sources.go | 6 +++--- .../pkg/controller/vi/internal/source/sources_test.go | 6 +++--- .../vi/internal/source/step/create_bounder_pod_step.go | 2 +- .../source/step/create_bounder_pod_step_test.go | 2 +- .../pkg/controller/vi/internal/source/upload.go | 4 ++-- .../controller/vmbda/internal/block_device_ready.go | 4 ++-- 16 files changed, 33 insertions(+), 33 deletions(-) diff --git a/images/virtualization-artifact/pkg/controller/vd/internal/migration.go b/images/virtualization-artifact/pkg/controller/vd/internal/migration.go index 4685568721..174e258ef9 100644 --- a/images/virtualization-artifact/pkg/controller/vd/internal/migration.go +++ b/images/virtualization-artifact/pkg/controller/vd/internal/migration.go @@ -492,13 +492,13 @@ func (h MigrationHandler) handleMigrateSync(ctx context.Context, vd *v1alpha2.Vi Reason(vdcondition.MigratingWaitForTargetReadyReason) if pvc == nil { - cb.Message("Target persistent volume claim is not found.") + cb.Message("The target PersistentVolumeClaim is not found.") conditions.SetCondition(cb, &vd.Status.Conditions) return nil } if pvc.Status.Phase == corev1.ClaimBound { - cb.Status(metav1.ConditionTrue).Reason(vdcondition.InProgress).Message("Target persistent volume claim is bound.") + cb.Status(metav1.ConditionTrue).Reason(vdcondition.InProgress).Message("The target PersistentVolumeClaim is bound.") conditions.SetCondition(cb, &vd.Status.Conditions) return nil } @@ -509,7 +509,7 @@ func (h MigrationHandler) handleMigrateSync(ctx context.Context, vd *v1alpha2.Vi storageClassName = *sc } if storageClassName == "" { - cb.Message("Target persistent volume claim is pending.") + cb.Message("The target PersistentVolumeClaim is pending.") conditions.SetCondition(cb, &vd.Status.Conditions) return nil } @@ -518,7 +518,7 @@ func (h MigrationHandler) handleMigrateSync(ctx context.Context, vd *v1alpha2.Vi err = h.client.Get(ctx, types.NamespacedName{Name: storageClassName}, sc) if err != nil { if k8serrors.IsNotFound(err) { - cb.Message("Target persistent volume claim is pending, StorageClass is not found.") + cb.Message("The target PersistentVolumeClaim is pending; the StorageClass is not found.") conditions.SetCondition(cb, &vd.Status.Conditions) return nil } @@ -527,7 +527,7 @@ func (h MigrationHandler) handleMigrateSync(ctx context.Context, vd *v1alpha2.Vi isWaitForFistConsumer := sc.VolumeBindingMode == nil || *sc.VolumeBindingMode == storagev1.VolumeBindingWaitForFirstConsumer if isWaitForFistConsumer { - cb.Status(metav1.ConditionTrue).Reason(vdcondition.InProgress).Message("Target persistent volume claim is waiting for first consumer.") + cb.Status(metav1.ConditionTrue).Reason(vdcondition.InProgress).Message("The target PersistentVolumeClaim is waiting for the first consumer.") conditions.SetCondition(cb, &vd.Status.Conditions) return nil } diff --git a/images/virtualization-artifact/pkg/controller/vd/internal/source/http.go b/images/virtualization-artifact/pkg/controller/vd/internal/source/http.go index ba2f910fac..1eb228523c 100644 --- a/images/virtualization-artifact/pkg/controller/vd/internal/source/http.go +++ b/images/virtualization-artifact/pkg/controller/vd/internal/source/http.go @@ -259,7 +259,7 @@ func (ds HTTPDataSource) Sync(ctx context.Context, vd *v1alpha2.VirtualDisk) (re } vd.Status.Phase = v1alpha2.DiskProvisioning - setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Provisioning, "PVC Provisioner not found: create the new one.") + setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Provisioning, "Preparing the disk storage.") return reconcile.Result{RequeueAfter: time.Second}, nil case dvQuotaNotExceededCondition != nil && dvQuotaNotExceededCondition.Status == corev1.ConditionFalse: @@ -279,7 +279,7 @@ func (ds HTTPDataSource) Sync(ctx context.Context, vd *v1alpha2.VirtualDisk) (re return reconcile.Result{}, nil case pvc == nil: vd.Status.Phase = v1alpha2.DiskProvisioning - setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Provisioning, "PVC not found: waiting for creation.") + setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Provisioning, "Waiting for the PersistentVolumeClaim to be created.") return reconcile.Result{RequeueAfter: time.Second}, nil case ds.diskService.IsImportDone(dv, pvc): log.Info("Import has completed", "dvProgress", dv.Status.Progress, "dvPhase", dv.Status.Phase, "pvcPhase", pvc.Status.Phase) diff --git a/images/virtualization-artifact/pkg/controller/vd/internal/source/registry.go b/images/virtualization-artifact/pkg/controller/vd/internal/source/registry.go index 2c2bf4119c..59340dbaa6 100644 --- a/images/virtualization-artifact/pkg/controller/vd/internal/source/registry.go +++ b/images/virtualization-artifact/pkg/controller/vd/internal/source/registry.go @@ -264,7 +264,7 @@ func (ds RegistryDataSource) Sync(ctx context.Context, vd *v1alpha2.VirtualDisk) return reconcile.Result{}, err } vd.Status.Phase = v1alpha2.DiskProvisioning - setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Provisioning, "PVC Provisioner not found: create the new one.") + setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Provisioning, "Preparing the disk storage.") return reconcile.Result{RequeueAfter: time.Second}, nil case dvQuotaNotExceededCondition != nil && dvQuotaNotExceededCondition.Status == corev1.ConditionFalse: @@ -284,7 +284,7 @@ func (ds RegistryDataSource) Sync(ctx context.Context, vd *v1alpha2.VirtualDisk) return reconcile.Result{}, nil case pvc == nil: vd.Status.Phase = v1alpha2.DiskProvisioning - setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Provisioning, "PVC not found: waiting for creation.") + setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Provisioning, "Waiting for the PersistentVolumeClaim to be created.") return reconcile.Result{RequeueAfter: time.Second}, nil case ds.diskService.IsImportDone(dv, pvc): log.Info("Import has completed", "dvProgress", dv.Status.Progress, "dvPhase", dv.Status.Phase, "pvcPhase", pvc.Status.Phase) diff --git a/images/virtualization-artifact/pkg/controller/vd/internal/source/step/ready_step.go b/images/virtualization-artifact/pkg/controller/vd/internal/source/step/ready_step.go index 1889ced6ce..093cd1e423 100644 --- a/images/virtualization-artifact/pkg/controller/vd/internal/source/step/ready_step.go +++ b/images/virtualization-artifact/pkg/controller/vd/internal/source/step/ready_step.go @@ -86,7 +86,7 @@ func (s ReadyStep) Take(ctx context.Context, vd *v1alpha2.VirtualDisk) (*reconci s.cb.Status(metav1.ConditionFalse) if s.pvc.GetAnnotations()[annotations.AnnDataExportRequest] == "true" { vd.Status.Phase = v1alpha2.DiskExporting - s.cb.Reason(vdcondition.Exporting).Message("PV is being exported") + s.cb.Reason(vdcondition.Exporting).Message("The PersistentVolume is being exported.") } else { vd.Status.Phase = v1alpha2.DiskLost s.cb. diff --git a/images/virtualization-artifact/pkg/controller/vd/internal/source/upload.go b/images/virtualization-artifact/pkg/controller/vd/internal/source/upload.go index a13fbbb404..7f2cd69fe0 100644 --- a/images/virtualization-artifact/pkg/controller/vd/internal/source/upload.go +++ b/images/virtualization-artifact/pkg/controller/vd/internal/source/upload.go @@ -304,7 +304,7 @@ func (ds UploadDataSource) Sync(ctx context.Context, vd *v1alpha2.VirtualDisk) ( } vd.Status.Phase = v1alpha2.DiskProvisioning - setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Provisioning, "PVC Provisioner not found: create the new one.") + setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Provisioning, "Preparing the disk storage.") return reconcile.Result{RequeueAfter: time.Second}, nil case dvQuotaNotExceededCondition != nil && dvQuotaNotExceededCondition.Status == corev1.ConditionFalse: @@ -324,7 +324,7 @@ func (ds UploadDataSource) Sync(ctx context.Context, vd *v1alpha2.VirtualDisk) ( return reconcile.Result{}, nil case pvc == nil: vd.Status.Phase = v1alpha2.DiskProvisioning - setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Provisioning, "PVC not found: waiting for creation.") + setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Provisioning, "Waiting for the PersistentVolumeClaim to be created.") return reconcile.Result{RequeueAfter: time.Second}, nil case ds.diskService.IsImportDone(dv, pvc): log.Info("Import has completed", "dvProgress", dv.Status.Progress, "dvPhase", dv.Status.Phase, "pvcPhase", pvc.Status.Phase) diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/http.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/http.go index 95ea9110a2..763caa784a 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/http.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/http.go @@ -368,7 +368,7 @@ func (ds HTTPDataSource) StoreToPVC(ctx context.Context, vi *v1alpha2.VirtualIma cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("PVC not found: waiting for creation.") + Message("Waiting for the PersistentVolumeClaim to be created.") return reconcile.Result{RequeueAfter: time.Second}, nil case ds.diskService.IsImportDone(dv, pvc): log.Info("Import has completed", "dvProgress", dv.Status.Progress, "dvPhase", dv.Status.Phase, "pvcPhase", pvc.Status.Phase) diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref.go index 647c0f51a6..cc3c9da056 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref.go @@ -224,7 +224,7 @@ func (ds ObjectRefDataSource) StoreToPVC(ctx context.Context, vi *v1alpha2.Virtu cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Preparing the disk storage for the image.") + Message("Preparing the image storage.") return reconcile.Result{RequeueAfter: time.Second}, nil case dvQuotaNotExceededCondition != nil && dvQuotaNotExceededCondition.Status == corev1.ConditionFalse: @@ -247,7 +247,7 @@ func (ds ObjectRefDataSource) StoreToPVC(ctx context.Context, vi *v1alpha2.Virtu cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("PVC not found: waiting for creation.") + Message("Waiting for the PersistentVolumeClaim to be created.") return reconcile.Result{RequeueAfter: time.Second}, nil case ds.diskService.IsImportDone(dv, pvc): log.Info("Import has completed", "dvProgress", dv.Status.Progress, "dvPhase", dv.Status.Phase, "pvcPhase", pvc.Status.Phase) diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vd.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vd.go index 3933245223..db04ee7e4a 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vd.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vd.go @@ -298,7 +298,7 @@ func (ds ObjectRefVirtualDisk) StoreToPVC(ctx context.Context, vi *v1alpha2.Virt cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Preparing the disk storage for the image.") + Message("Preparing the image storage.") return reconcile.Result{RequeueAfter: time.Second}, nil case dvQuotaNotExceededCondition != nil && dvQuotaNotExceededCondition.Status == corev1.ConditionFalse: @@ -321,7 +321,7 @@ func (ds ObjectRefVirtualDisk) StoreToPVC(ctx context.Context, vi *v1alpha2.Virt cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("PVC not found: waiting for creation.") + Message("Waiting for the PersistentVolumeClaim to be created.") return reconcile.Result{RequeueAfter: time.Second}, nil case ds.diskService.IsImportDone(dv, pvc): log.Info("Import has completed", "dvProgress", dv.Status.Progress, "dvPhase", dv.Status.Phase, "pvcPhase", pvc.Status.Phase) diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vi_on_pvc.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vi_on_pvc.go index d4b4097401..0405b88484 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vi_on_pvc.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vi_on_pvc.go @@ -276,7 +276,7 @@ func (ds ObjectRefDataVirtualImageOnPVC) StoreToPVC(ctx context.Context, vi, viR cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Preparing the disk storage for the image.") + Message("Preparing the image storage.") return reconcile.Result{RequeueAfter: time.Second}, nil case dvQuotaNotExceededCondition != nil && dvQuotaNotExceededCondition.Status == corev1.ConditionFalse: @@ -299,7 +299,7 @@ func (ds ObjectRefDataVirtualImageOnPVC) StoreToPVC(ctx context.Context, vi, viR cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("PVC not found: waiting for creation.") + Message("Waiting for the PersistentVolumeClaim to be created.") return reconcile.Result{RequeueAfter: time.Second}, nil case ds.diskService.IsImportDone(dv, pvc): log.Info("Import has completed", "dvProgress", dv.Status.Progress, "dvPhase", dv.Status.Phase, "pvcPhase", pvc.Status.Phase) diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/registry.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/registry.go index 2a3192a048..ac3a990ce4 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/registry.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/registry.go @@ -225,7 +225,7 @@ func (ds RegistryDataSource) StoreToPVC(ctx context.Context, vi *v1alpha2.Virtua cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Preparing the disk storage for the image.") + Message("Preparing the image storage.") return reconcile.Result{RequeueAfter: time.Second}, nil case dvQuotaNotExceededCondition != nil && dvQuotaNotExceededCondition.Status == corev1.ConditionFalse: @@ -248,7 +248,7 @@ func (ds RegistryDataSource) StoreToPVC(ctx context.Context, vi *v1alpha2.Virtua cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("PVC not found: waiting for creation.") + Message("Waiting for the PersistentVolumeClaim to be created.") return reconcile.Result{RequeueAfter: time.Second}, nil case ds.diskService.IsImportDone(dv, pvc): log.Info("Import has completed", "dvProgress", dv.Status.Progress, "dvPhase", dv.Status.Phase, "pvcPhase", pvc.Status.Phase) diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/sources.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/sources.go index ec3b0f9f05..54d9196fd0 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/sources.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/sources.go @@ -122,7 +122,7 @@ func setPhaseConditionForFinishedImage( cb. Status(metav1.ConditionFalse). Reason(vicondition.PVCLost). - Message(fmt.Sprintf("PVC %s not found.", supgen.PersistentVolumeClaim().String())) + Message("The underlying PersistentVolumeClaim was not found.") default: *phase = v1alpha2.ImageReady cb. @@ -156,7 +156,7 @@ func setPhaseConditionForPVCProvisioningImage( cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Preparing to provision the disk storage.") + Message("Preparing the image storage.") return nil } @@ -164,7 +164,7 @@ func setPhaseConditionForPVCProvisioningImage( cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Import is in the process of provisioning to PVC.") + Message("Importing data into the PersistentVolumeClaim.") return nil case errors.Is(err, service.ErrDataVolumeNotRunning): vi.Status.Phase = v1alpha2.ImageProvisioning diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/sources_test.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/sources_test.go index d5a12a9454..7e31bdb82a 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/sources_test.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/sources_test.go @@ -212,7 +212,7 @@ var _ = Describe("Sources helpers", func() { Expect(cb.Condition().Reason).To(Equal(expectedReason)) Expect(cb.Condition().Message).To(Equal(expectedMessage)) }, - Entry("marks pvc lost when pvc is missing", nil, v1alpha2.ImagePVCLost, metav1.ConditionFalse, vicondition.PVCLost.String(), "PVC default/d8v-vi-image-uid not found."), + Entry("marks pvc lost when pvc is missing", nil, v1alpha2.ImagePVCLost, metav1.ConditionFalse, vicondition.PVCLost.String(), "The underlying PersistentVolumeClaim was not found."), Entry("marks image ready when pvc exists", &corev1.PersistentVolumeClaim{}, v1alpha2.ImageReady, metav1.ConditionTrue, vicondition.Ready.String(), ""), ) @@ -242,8 +242,8 @@ var _ = Describe("Sources helpers", func() { Expect(cb.Condition().Reason).To(Equal(expectedReason)) Expect(cb.Condition().Message).To(Equal(expectedMessage)) }, - Entry("waits for pvc importer creation when dv is absent", nil, nil, v1alpha2.ImageProvisioning, metav1.ConditionFalse, vicondition.Provisioning.String(), "Preparing to provision the disk storage.", nil), - Entry("reports provisioning in progress", &cdiv1.DataVolume{}, nil, v1alpha2.ImageProvisioning, metav1.ConditionFalse, vicondition.Provisioning.String(), "Import is in the process of provisioning to PVC.", nil), + Entry("waits for pvc importer creation when dv is absent", nil, nil, v1alpha2.ImageProvisioning, metav1.ConditionFalse, vicondition.Provisioning.String(), "Preparing the image storage.", nil), + Entry("reports provisioning in progress", &cdiv1.DataVolume{}, nil, v1alpha2.ImageProvisioning, metav1.ConditionFalse, vicondition.Provisioning.String(), "Importing data into the PersistentVolumeClaim.", nil), Entry("handles data volume not running", &cdiv1.DataVolume{}, service.ErrDataVolumeNotRunning, v1alpha2.ImageProvisioning, metav1.ConditionFalse, vicondition.ProvisioningFailed.String(), "Pvc importer is not running", nil), Entry("handles missing default storage class", &cdiv1.DataVolume{}, service.ErrDefaultStorageClassNotFound, v1alpha2.ImagePending, metav1.ConditionFalse, vicondition.ProvisioningFailed.String(), "Default StorageClass not found in the cluster: please provide a StorageClass name or set a default StorageClass.", nil), Entry("returns unexpected error", &cdiv1.DataVolume{}, errors.New("boom"), v1alpha2.ImagePhase(""), metav1.ConditionUnknown, conditions.ReasonUnknown.String(), "", errors.New("boom")), diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/step/create_bounder_pod_step.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/step/create_bounder_pod_step.go index 4526ec1877..e90dd0c6dc 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/step/create_bounder_pod_step.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/step/create_bounder_pod_step.go @@ -99,7 +99,7 @@ func (s CreateBounderPodStep) Take(ctx context.Context, vi *v1alpha2.VirtualImag s.cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Waiting for the disk storage to be Bound.") + Message("Waiting for the image storage to be ready.") return nil, nil } diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/step/create_bounder_pod_step_test.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/step/create_bounder_pod_step_test.go index 5dd453ea9f..36b38c241f 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/step/create_bounder_pod_step_test.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/step/create_bounder_pod_step_test.go @@ -166,7 +166,7 @@ var _ = Describe("CreateBounderPodStep", func() { 0, v1alpha2.ImagePhase(""), vicondition.Provisioning.String(), - "Waiting for the disk storage to be Bound.", + "Waiting for the image storage to be ready.", time.Duration(0), ), Entry("handles quota exceeded error", diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/upload.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/upload.go index dfb443e43a..f856e7db29 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/upload.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/upload.go @@ -281,7 +281,7 @@ func (ds UploadDataSource) StoreToPVC(ctx context.Context, vi *v1alpha2.VirtualI cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Preparing the disk storage for the image.") + Message("Preparing the image storage.") return reconcile.Result{RequeueAfter: time.Second}, nil case dvQuotaNotExceededCondition != nil && dvQuotaNotExceededCondition.Status == corev1.ConditionFalse: @@ -304,7 +304,7 @@ func (ds UploadDataSource) StoreToPVC(ctx context.Context, vi *v1alpha2.VirtualI cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("PVC not found: waiting for creation.") + Message("Waiting for the PersistentVolumeClaim to be created.") return reconcile.Result{RequeueAfter: time.Second}, nil case ds.diskService.IsImportDone(dv, pvc): log.Info("Import has completed", "dvProgress", dv.Status.Progress, "dvPhase", dv.Status.Phase, "pvcPhase", pvc.Status.Phase) diff --git a/images/virtualization-artifact/pkg/controller/vmbda/internal/block_device_ready.go b/images/virtualization-artifact/pkg/controller/vmbda/internal/block_device_ready.go index 552b40b275..cb1fc747a5 100644 --- a/images/virtualization-artifact/pkg/controller/vmbda/internal/block_device_ready.go +++ b/images/virtualization-artifact/pkg/controller/vmbda/internal/block_device_ready.go @@ -127,7 +127,7 @@ func (h BlockDeviceReadyHandler) Handle(ctx context.Context, vmbda *v1alpha2.Vir cb. Status(metav1.ConditionFalse). Reason(vmbdacondition.BlockDeviceNotReady). - Message(fmt.Sprintf("The VirtualImage %q storage is not bound yet.", viKey.String())) + Message(fmt.Sprintf("The VirtualImage %q storage is not ready yet.", viKey.String())) return reconcile.Result{}, nil } @@ -283,7 +283,7 @@ func (h BlockDeviceReadyHandler) ValidateVirtualDiskReady(ctx context.Context, v cb. Status(metav1.ConditionFalse). Reason(vmbdacondition.BlockDeviceNotReady). - Message(fmt.Sprintf("The VirtualDisk %q storage is not bound yet.", vdKey.String())) + Message(fmt.Sprintf("The VirtualDisk %q storage is not ready yet.", vdKey.String())) return nil } From e800d8cfa5663b888eec3066655201d41122e451 Mon Sep 17 00:00:00 2001 From: Pavel Tishkov Date: Tue, 30 Jun 2026 13:28:50 +0300 Subject: [PATCH 12/25] fix(vi): name the PersistentVolumeClaim in the bind-wait message Replace the vague "Waiting for the image storage to be ready" with the concrete "Waiting for the PersistentVolumeClaim to be Bound": the PVC is a public object the user can inspect, and the phase is its real status. Signed-off-by: Pavel Tishkov --- .../vi/internal/source/step/create_bounder_pod_step.go | 2 +- .../vi/internal/source/step/create_bounder_pod_step_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/step/create_bounder_pod_step.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/step/create_bounder_pod_step.go index e90dd0c6dc..8404e798ac 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/step/create_bounder_pod_step.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/step/create_bounder_pod_step.go @@ -99,7 +99,7 @@ func (s CreateBounderPodStep) Take(ctx context.Context, vi *v1alpha2.VirtualImag s.cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Waiting for the image storage to be ready.") + Message("Waiting for the PersistentVolumeClaim to be Bound.") return nil, nil } diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/step/create_bounder_pod_step_test.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/step/create_bounder_pod_step_test.go index 36b38c241f..c8855ac8d8 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/step/create_bounder_pod_step_test.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/step/create_bounder_pod_step_test.go @@ -166,7 +166,7 @@ var _ = Describe("CreateBounderPodStep", func() { 0, v1alpha2.ImagePhase(""), vicondition.Provisioning.String(), - "Waiting for the image storage to be ready.", + "Waiting for the PersistentVolumeClaim to be Bound.", time.Duration(0), ), Entry("handles quota exceeded error", From d150ba076aaea0e465b47730d45cf372882f3fc1 Mon Sep 17 00:00:00 2001 From: Pavel Tishkov Date: Tue, 30 Jun 2026 13:32:51 +0300 Subject: [PATCH 13/25] fix(vm, vd, vi, cvi): align wording across condition messages Consistency pass over the reworded messages: say "guest agent version", "StorageClass" and the "Bound" phase uniformly, use the same text for the same state across VirtualImage and ClusterVirtualImage, and name the PersistentVolumeClaim in the snapshot-restore wait instead of a vague volume. Signed-off-by: Pavel Tishkov --- .../controller/cvi/internal/source/object_ref_vdsnapshot.go | 4 ++-- .../pkg/controller/vd/internal/life_cycle.go | 2 +- .../pkg/controller/vd/internal/migration.go | 2 +- .../pkg/controller/vd/internal/resizing.go | 2 +- .../pkg/controller/vi/internal/life_cycle.go | 2 +- .../pkg/controller/vi/internal/source/object_ref.go | 4 ++-- .../pkg/controller/vm/internal/agent.go | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vdsnapshot.go b/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vdsnapshot.go index a829ac6f28..8db4ab7abe 100644 --- a/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vdsnapshot.go +++ b/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vdsnapshot.go @@ -196,7 +196,7 @@ func (ds ObjectRefVirtualDiskSnapshot) Sync(ctx context.Context, cvi *v1alpha2.C cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Restoring data from the snapshot. Waiting for the volume to be ready.") + Message("Restoring data from the snapshot. Waiting for the PersistentVolumeClaim to be Bound.") cvi.Status.Progress = "0%" cvi.Status.SourceUID = ptr.To(vs.UID) @@ -274,7 +274,7 @@ func (ds ObjectRefVirtualDiskSnapshot) Sync(ctx context.Context, cvi *v1alpha2.C cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Restoring data from the snapshot. Waiting for the volume to be provisioned.") + Message("Restoring data from the snapshot. Waiting for the PersistentVolumeClaim to be Bound.") return reconcile.Result{RequeueAfter: time.Second}, nil } diff --git a/images/virtualization-artifact/pkg/controller/vd/internal/life_cycle.go b/images/virtualization-artifact/pkg/controller/vd/internal/life_cycle.go index 5c0f0a01ad..d9ea5290e8 100644 --- a/images/virtualization-artifact/pkg/controller/vd/internal/life_cycle.go +++ b/images/virtualization-artifact/pkg/controller/vd/internal/life_cycle.go @@ -128,7 +128,7 @@ func (h LifeCycleHandler) Handle(ctx context.Context, vd *v1alpha2.VirtualDisk) cb. Status(metav1.ConditionFalse). Reason(vdcondition.StorageClassIsNotReady). - Message("Storage class is not ready.") + Message("The StorageClass is not ready.") conditions.SetCondition(cb, &vd.Status.Conditions) return reconcile.Result{}, nil diff --git a/images/virtualization-artifact/pkg/controller/vd/internal/migration.go b/images/virtualization-artifact/pkg/controller/vd/internal/migration.go index 174e258ef9..c3010c3e5f 100644 --- a/images/virtualization-artifact/pkg/controller/vd/internal/migration.go +++ b/images/virtualization-artifact/pkg/controller/vd/internal/migration.go @@ -498,7 +498,7 @@ func (h MigrationHandler) handleMigrateSync(ctx context.Context, vd *v1alpha2.Vi } if pvc.Status.Phase == corev1.ClaimBound { - cb.Status(metav1.ConditionTrue).Reason(vdcondition.InProgress).Message("The target PersistentVolumeClaim is bound.") + cb.Status(metav1.ConditionTrue).Reason(vdcondition.InProgress).Message("The target PersistentVolumeClaim is Bound.") conditions.SetCondition(cb, &vd.Status.Conditions) return nil } diff --git a/images/virtualization-artifact/pkg/controller/vd/internal/resizing.go b/images/virtualization-artifact/pkg/controller/vd/internal/resizing.go index ece1e1090f..c1e9d91a32 100644 --- a/images/virtualization-artifact/pkg/controller/vd/internal/resizing.go +++ b/images/virtualization-artifact/pkg/controller/vd/internal/resizing.go @@ -214,7 +214,7 @@ func (h ResizingHandler) ResizeNeeded( cb. Status(metav1.ConditionFalse). Reason(vdcondition.ResizingNotAvailable). - Message("Disk resizing is not allowed: Storage class is not ready") + Message("Disk resizing is not allowed: the StorageClass is not ready.") conditions.SetCondition(cb, &vd.Status.Conditions) } diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/life_cycle.go b/images/virtualization-artifact/pkg/controller/vi/internal/life_cycle.go index 671e1d0ac2..f2df5c2cb6 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/life_cycle.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/life_cycle.go @@ -112,7 +112,7 @@ func (h LifeCycleHandler) Handle(ctx context.Context, vi *v1alpha2.VirtualImage) cb. Status(metav1.ConditionFalse). Reason(vicondition.StorageClassNotReady). - Message("Storage class is not ready.") + Message("The StorageClass is not ready.") conditions.SetCondition(cb, &vi.Status.Conditions) return reconcile.Result{}, nil diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref.go index cc3c9da056..9d7d7cccb6 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref.go @@ -185,7 +185,7 @@ func (ds ObjectRefDataSource) StoreToPVC(ctx context.Context, vi *v1alpha2.Virtu cb. Status(metav1.ConditionFalse). Reason(vicondition.ProvisioningFailed). - Message("Waiting for the source DataSource to become ready.") + Message("Waiting for the source data to become ready.") return reconcile.Result{}, nil } @@ -429,7 +429,7 @@ func (ds ObjectRefDataSource) StoreToDVCR(ctx context.Context, vi *v1alpha2.Virt cb. Status(metav1.ConditionFalse). Reason(vicondition.ProvisioningFailed). - Message("Waiting for the source DataSource to become ready.") + Message("Waiting for the source data to become ready.") return reconcile.Result{}, nil } diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/agent.go b/images/virtualization-artifact/pkg/controller/vm/internal/agent.go index 034100820c..e542806b3f 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/agent.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/agent.go @@ -131,7 +131,7 @@ func (h *AgentHandler) syncAgentVersionNotSupport(vm *v1alpha2.VirtualMachine, k if kvvmi == nil { cb.Status(metav1.ConditionFalse). Reason(vmcondition.ReasonAgentNotReady). - Message("Cannot check the agent version: the VirtualMachine is not running.") + Message("Cannot check the guest agent version: the VirtualMachine is not running.") return } From 4987f699c5cb1a70172eed759b262f34443a9848 Mon Sep 17 00:00:00 2001 From: Pavel Tishkov Date: Tue, 30 Jun 2026 14:01:02 +0300 Subject: [PATCH 14/25] fix(vmbda): do not report a missing volume as not-ready A missing backing volume (PVC absent) was reported with the same "storage is not ready" wording as a not-yet-bound one, hiding that the storage is actually gone. Say it was not found instead. Signed-off-by: Pavel Tishkov --- .../pkg/controller/vmbda/internal/block_device_ready.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/images/virtualization-artifact/pkg/controller/vmbda/internal/block_device_ready.go b/images/virtualization-artifact/pkg/controller/vmbda/internal/block_device_ready.go index cb1fc747a5..81a1694329 100644 --- a/images/virtualization-artifact/pkg/controller/vmbda/internal/block_device_ready.go +++ b/images/virtualization-artifact/pkg/controller/vmbda/internal/block_device_ready.go @@ -119,7 +119,7 @@ func (h BlockDeviceReadyHandler) Handle(ctx context.Context, vmbda *v1alpha2.Vir cb. Status(metav1.ConditionFalse). Reason(vmbdacondition.BlockDeviceNotReady). - Message(fmt.Sprintf("The VirtualImage %q storage is not ready.", viKey.String())) + Message(fmt.Sprintf("The VirtualImage %q storage was not found.", viKey.String())) return reconcile.Result{}, nil } @@ -275,7 +275,7 @@ func (h BlockDeviceReadyHandler) ValidateVirtualDiskReady(ctx context.Context, v cb. Status(metav1.ConditionFalse). Reason(vmbdacondition.BlockDeviceNotReady). - Message(fmt.Sprintf("The VirtualDisk %q storage is not ready.", vdKey.String())) + Message(fmt.Sprintf("The VirtualDisk %q storage was not found.", vdKey.String())) return nil } From df27e993ffcf5202d54e15e5acac44e2bbb088c7 Mon Sep 17 00:00:00 2001 From: Pavel Tishkov Date: Tue, 30 Jun 2026 14:19:32 +0300 Subject: [PATCH 15/25] fix(vm): add trailing period to provisioning condition messages Signed-off-by: Pavel Tishkov --- .../pkg/controller/vm/internal/provisioning.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/provisioning.go b/images/virtualization-artifact/pkg/controller/vm/internal/provisioning.go index 6940771fa5..a48a5d87a8 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/provisioning.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/provisioning.go @@ -84,7 +84,7 @@ func (h *ProvisioningHandler) Handle(ctx context.Context, s state.VirtualMachine if p.UserDataRef == nil || p.UserDataRef.Kind != v1alpha2.UserDataRefKindSecret { cb.Status(metav1.ConditionFalse). Reason(vmcondition.ReasonProvisioningNotReady). - Message(fmt.Sprintf("spec.provisioning.userDataRef.kind must be %q", v1alpha2.UserDataRefKindSecret)) + Message(fmt.Sprintf("spec.provisioning.userDataRef.kind must be %q.", v1alpha2.UserDataRefKindSecret)) } key := types.NamespacedName{Name: p.UserDataRef.Name, Namespace: current.GetNamespace()} err := h.genConditionFromSecret(ctx, cb, key) @@ -96,7 +96,7 @@ func (h *ProvisioningHandler) Handle(ctx context.Context, s state.VirtualMachine if p.SysprepRef == nil || p.SysprepRef.Kind != v1alpha2.SysprepRefKindSecret { cb.Status(metav1.ConditionFalse). Reason(vmcondition.ReasonProvisioningNotReady). - Message(fmt.Sprintf("spec.provisioning.sysprepRef.kind must be %q", v1alpha2.SysprepRefKindSecret)) + Message(fmt.Sprintf("spec.provisioning.sysprepRef.kind must be %q.", v1alpha2.SysprepRefKindSecret)) } key := types.NamespacedName{Name: p.SysprepRef.Name, Namespace: current.GetNamespace()} err := h.genConditionFromSecret(ctx, cb, key) From 86d877dfb7972bc299c140addb27312263fbba21 Mon Sep 17 00:00:00 2001 From: Pavel Tishkov Date: Tue, 30 Jun 2026 14:32:43 +0300 Subject: [PATCH 16/25] fix(vm, vmclass, vmop, vdsnapshot): clean up condition message text Text-only cleanups (no logic change): full resource names (VirtualMachineClass, VirtualMachineIPAddress), correct IP-address casing/grammar, trailing periods, migration progress in user terms (node/VirtualMachine instead of target pod), clearer snapshot/operation wording, and name the VolumeSnapshot when it is lost. Signed-off-by: Pavel Tishkov --- .../pkg/controller/vdsnapshot/internal/life_cycle.go | 2 +- .../pkg/controller/vm/internal/ipam.go | 10 +++++----- .../pkg/controller/vm/internal/mac.go | 2 +- .../pkg/controller/vm/internal/size_policy.go | 2 +- .../pkg/controller/vmclass/internal/lifecycle.go | 2 +- .../vmop/migration/internal/handler/lifecycle.go | 10 +++++----- .../vmop/migration/internal/handler/lifecycle_test.go | 2 +- .../vmop/powerstate/internal/handler/lifecycle.go | 2 +- .../vmop/snapshot/internal/handler/lifecycle.go | 2 +- .../snapshot/internal/step/create_snapshot_step.go | 2 +- .../snapshot/internal/step/waiting_disk_ready_step.go | 6 +++--- 11 files changed, 21 insertions(+), 21 deletions(-) diff --git a/images/virtualization-artifact/pkg/controller/vdsnapshot/internal/life_cycle.go b/images/virtualization-artifact/pkg/controller/vdsnapshot/internal/life_cycle.go index 21b396744d..e2bd72c1cc 100644 --- a/images/virtualization-artifact/pkg/controller/vdsnapshot/internal/life_cycle.go +++ b/images/virtualization-artifact/pkg/controller/vdsnapshot/internal/life_cycle.go @@ -109,7 +109,7 @@ func (h LifeCycleHandler) Handle(ctx context.Context, vdSnapshot *v1alpha2.Virtu cb. Status(metav1.ConditionFalse). Reason(vdscondition.VolumeSnapshotLost). - Message("The snapshot is no longer available.") + Message("The underlying VolumeSnapshot is no longer available.") return reconcile.Result{Requeue: true}, nil } diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/ipam.go b/images/virtualization-artifact/pkg/controller/vm/internal/ipam.go index b427588c17..2f34f3f0f3 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/ipam.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/ipam.go @@ -139,12 +139,12 @@ func (h *IPAMHandler) Handle(ctx context.Context, s state.VirtualMachineState) ( if ipAddress == nil { cb.Reason(vmcondition.ReasonIPAddressNotReady) if vm.Spec.VirtualMachineIPAddress != "" { - log.Info(fmt.Sprintf("The requested ip address (%s) for the virtual machine not found: waiting for the ip address", vm.Spec.VirtualMachineIPAddress)) - cb.Message(fmt.Sprintf("The requested ip address (%s) for the virtual machine not found: waiting for the ip address", vm.Spec.VirtualMachineIPAddress)) + log.Info(fmt.Sprintf("The requested VirtualMachineIPAddress %q was not found: waiting for it to appear.", vm.Spec.VirtualMachineIPAddress)) + cb.Message(fmt.Sprintf("The requested VirtualMachineIPAddress %q was not found: waiting for it to appear.", vm.Spec.VirtualMachineIPAddress)) return reconcile.Result{}, nil } log.Info("VirtualMachineIPAddress not found: create the new one", slog.String("vmipName", vm.GetName())) - cb.Message(fmt.Sprintf("VirtualMachineIPAddress %q not found: it may be in the process of being created", vm.GetName())) + cb.Message(fmt.Sprintf("VirtualMachineIPAddress %q was not found: it may be in the process of being created.", vm.GetName())) return reconcile.Result{}, h.ipam.CreateIPAddress(ctx, vm, h.client) } @@ -160,7 +160,7 @@ func (h *IPAMHandler) Handle(ctx context.Context, s state.VirtualMachineState) ( // 4. Ip address exist and attached to another VirtualMachine if ipAddress.Status.VirtualMachine != "" && ipAddress.Status.VirtualMachine != vm.Name { - msg := fmt.Sprintf("The requested ip address (%s) attached to VirtualMachine '%s': waiting for the ip address", vm.Spec.VirtualMachineIPAddress, ipAddress.Status.VirtualMachine) + msg := fmt.Sprintf("The requested VirtualMachineIPAddress %q is attached to VirtualMachine %q: waiting for it to be released.", vm.Spec.VirtualMachineIPAddress, ipAddress.Status.VirtualMachine) log.Info(msg) cb.Reason(vmcondition.ReasonIPAddressNotReady).Message(msg) return reconcile.Result{}, nil @@ -168,7 +168,7 @@ func (h *IPAMHandler) Handle(ctx context.Context, s state.VirtualMachineState) ( // 5. Ip address exists and available for binding with virtual machine: waiting for the ip address. log.Info("Waiting for the ip address to be bound to VM", "vmipName", vm.Spec.VirtualMachineIPAddress) - cb.Reason(vmcondition.ReasonIPAddressNotReady).Message("Ip address not bound: waiting for the ip address") + cb.Reason(vmcondition.ReasonIPAddressNotReady).Message("The IP address is not bound yet: waiting for it to be assigned.") return reconcile.Result{}, nil } diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/mac.go b/images/virtualization-artifact/pkg/controller/vm/internal/mac.go index 31c216b68d..69e6d77c89 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/mac.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/mac.go @@ -128,7 +128,7 @@ func (h *MACHandler) Handle(ctx context.Context, s state.VirtualMachineState) (r } } - cb.Status(metav1.ConditionFalse).Reason(vmcondition.ReasonMACAddressNotReady).Message(fmt.Sprintf("Waiting for the MAC address to be created %d/%d", len(vmmacs), expectedMACAddresses)) + cb.Status(metav1.ConditionFalse).Reason(vmcondition.ReasonMACAddressNotReady).Message(fmt.Sprintf("Waiting for the MAC address to be created %d/%d.", len(vmmacs), expectedMACAddresses)) return reconcile.Result{}, nil } diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/size_policy.go b/images/virtualization-artifact/pkg/controller/vm/internal/size_policy.go index 936eb65ee7..bcee2a48df 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/size_policy.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/size_policy.go @@ -76,7 +76,7 @@ func (h *SizePolicyHandler) Handle(ctx context.Context, s state.VirtualMachineSt Reason(vmcondition.ReasonVirtualMachineClassNotFound). Status(metav1.ConditionFalse) case vmClass.Status.Phase == v1alpha2.ClassPhaseTerminating: - cb.Message(fmt.Sprintf("Virtual machine class %q is terminating.", vmClass.Name)). + cb.Message(fmt.Sprintf("VirtualMachineClass %q is terminating.", vmClass.Name)). Reason(vmcondition.ReasonVirtualMachineClassTerminating). Status(metav1.ConditionFalse) default: diff --git a/images/virtualization-artifact/pkg/controller/vmclass/internal/lifecycle.go b/images/virtualization-artifact/pkg/controller/vmclass/internal/lifecycle.go index d8f6096a8f..1ded065a56 100644 --- a/images/virtualization-artifact/pkg/controller/vmclass/internal/lifecycle.go +++ b/images/virtualization-artifact/pkg/controller/vmclass/internal/lifecycle.go @@ -70,7 +70,7 @@ func (h *LifeCycleHandler) Handle(_ context.Context, s state.VirtualMachineClass notReady = true } if len(changed.Status.CpuFeatures.Enabled) == 0 { - cb.Message("No cpu feature enabled.") + cb.Message("No CPU features enabled.") cb.Reason(vmclasscondition.ReasonNoCpuFeaturesEnabled) notReady = true } diff --git a/images/virtualization-artifact/pkg/controller/vmop/migration/internal/handler/lifecycle.go b/images/virtualization-artifact/pkg/controller/vmop/migration/internal/handler/lifecycle.go index e493da6147..5375607bed 100644 --- a/images/virtualization-artifact/pkg/controller/vmop/migration/internal/handler/lifecycle.go +++ b/images/virtualization-artifact/pkg/controller/vmop/migration/internal/handler/lifecycle.go @@ -60,11 +60,11 @@ const ( const ( messageMigrationPending = "The VirtualMachineOperation for migrating the virtual machine has been queued. Waiting for the queue to be processed and for this operation to be executed." - messageSyncingSourceAndTarget = "Syncing source and target" - messageTargetPodScheduling = "Target pod is being scheduled" - messageTargetPodPreparing = "Target pod is being prepared" - messageTargetVMResumed = "Target VM resumed" - messageSourceVMSuspended = "Source VM suspended" + messageSyncingSourceAndTarget = "Synchronizing the VirtualMachine to the destination node" + messageTargetPodScheduling = "Selecting a node to migrate the VirtualMachine to" + messageTargetPodPreparing = "Preparing the destination node for the VirtualMachine" + messageTargetVMResumed = "The VirtualMachine has resumed on the destination node" + messageSourceVMSuspended = "The VirtualMachine has been suspended on the source node" ) const ( diff --git a/images/virtualization-artifact/pkg/controller/vmop/migration/internal/handler/lifecycle_test.go b/images/virtualization-artifact/pkg/controller/vmop/migration/internal/handler/lifecycle_test.go index a7458b8dd9..f781a866fb 100644 --- a/images/virtualization-artifact/pkg/controller/vmop/migration/internal/handler/lifecycle_test.go +++ b/images/virtualization-artifact/pkg/controller/vmop/migration/internal/handler/lifecycle_test.go @@ -674,7 +674,7 @@ var _ = Describe("LifecycleHandler", func() { completed, found := conditions.GetCondition(vmopcondition.TypeCompleted, srv.Changed().Status.Conditions) Expect(found).To(BeTrue()) Expect(completed.Message).NotTo(ContainSubstring("Migration info for 7d38a63b-ffa9-4d56-a924-6017f5832110:")) - Expect(completed.Message).To(ContainSubstring("Syncing source and target. TimeElapsed:30s")) + Expect(completed.Message).To(ContainSubstring("Synchronizing the VirtualMachine to the destination node. TimeElapsed:30s")) Expect(completed.Message).To(ContainSubstring("DataProcessed:3529MiB DataRemaining:12049MiB DataTotal:16405MiB")) Expect(completed.Message).To(ContainSubstring("Iteration:1 AutoConvergeThrottleSet:true AutoConvergeThrottle:0")) }) diff --git a/images/virtualization-artifact/pkg/controller/vmop/powerstate/internal/handler/lifecycle.go b/images/virtualization-artifact/pkg/controller/vmop/powerstate/internal/handler/lifecycle.go index 43bd2c31e5..98d72607c1 100644 --- a/images/virtualization-artifact/pkg/controller/vmop/powerstate/internal/handler/lifecycle.go +++ b/images/virtualization-artifact/pkg/controller/vmop/powerstate/internal/handler/lifecycle.go @@ -181,7 +181,7 @@ func (h LifecycleHandler) execute(ctx context.Context, vmop *v1alpha2.VirtualMac conditions.SetCondition( completedCond. Reason(reason). - Message("Wait for operation to complete"). + Message("Waiting for the operation to complete."). Status(metav1.ConditionFalse), &vmop.Status.Conditions) conditions.SetCondition( diff --git a/images/virtualization-artifact/pkg/controller/vmop/snapshot/internal/handler/lifecycle.go b/images/virtualization-artifact/pkg/controller/vmop/snapshot/internal/handler/lifecycle.go index e4a07639a7..22117074e2 100644 --- a/images/virtualization-artifact/pkg/controller/vmop/snapshot/internal/handler/lifecycle.go +++ b/images/virtualization-artifact/pkg/controller/vmop/snapshot/internal/handler/lifecycle.go @@ -122,7 +122,7 @@ func (h LifecycleHandler) Handle(ctx context.Context, vmop *v1alpha2.VirtualMach conditions.NewConditionBuilder(vmopcondition.TypeCompleted). Generation(vmop.GetGeneration()). Reason(reason). - Message("Wait for operation to complete"). + Message("Waiting for the operation to complete."). Status(metav1.ConditionFalse), &vmop.Status.Conditions) diff --git a/images/virtualization-artifact/pkg/controller/vmop/snapshot/internal/step/create_snapshot_step.go b/images/virtualization-artifact/pkg/controller/vmop/snapshot/internal/step/create_snapshot_step.go index 94dec1e91b..dbe5a2fd5c 100644 --- a/images/virtualization-artifact/pkg/controller/vmop/snapshot/internal/step/create_snapshot_step.go +++ b/images/virtualization-artifact/pkg/controller/vmop/snapshot/internal/step/create_snapshot_step.go @@ -67,7 +67,7 @@ func (s CreateSnapshotStep) Take(ctx context.Context, vmop *v1alpha2.VirtualMach switch vmSnapshot.Status.Phase { case v1alpha2.VirtualMachineSnapshotPhaseFailed: conditions.SetCondition( - snapshotConditionBuilder.Status(metav1.ConditionFalse).Reason(vmopcondition.ReasonSnapshotFailed).Message("Snapshot is failed."), + snapshotConditionBuilder.Status(metav1.ConditionFalse).Reason(vmopcondition.ReasonSnapshotFailed).Message("Snapshot creation failed."), &vmop.Status.Conditions, ) vmsReadyCondition, _ := conditions.GetCondition(vmscondition.VirtualMachineSnapshotReadyType, vmSnapshot.Status.Conditions) diff --git a/images/virtualization-artifact/pkg/controller/vmop/snapshot/internal/step/waiting_disk_ready_step.go b/images/virtualization-artifact/pkg/controller/vmop/snapshot/internal/step/waiting_disk_ready_step.go index 28994d0ec5..882fd21090 100644 --- a/images/virtualization-artifact/pkg/controller/vmop/snapshot/internal/step/waiting_disk_ready_step.go +++ b/images/virtualization-artifact/pkg/controller/vmop/snapshot/internal/step/waiting_disk_ready_step.go @@ -77,7 +77,7 @@ func (s WaitingDisksReadyStep) Take(ctx context.Context, vmop *v1alpha2.VirtualM err := s.client.Get(ctx, vdKey, &vd) if err != nil { if k8serrors.IsNotFound(err) { - cb.Message("Waiting for resource readiness.") + cb.Message("Waiting for the virtual disks to become ready.") conditions.SetCondition(cb, &vmop.Status.Conditions) return &reconcile.Result{}, nil } @@ -96,13 +96,13 @@ func (s WaitingDisksReadyStep) Take(ctx context.Context, vmop *v1alpha2.VirtualM continue case v1alpha2.DiskWaitForFirstConsumer: if vmop.Spec.Type == v1alpha2.VMOPTypeClone { - cb.Message("Waiting for resource readiness.") + cb.Message("Waiting for the virtual disks to become ready.") conditions.SetCondition(cb, &vmop.Status.Conditions) return &reconcile.Result{}, nil // Should wait for disk ready. } continue default: - cb.Message("Waiting for resource readiness.") + cb.Message("Waiting for the virtual disks to become ready.") conditions.SetCondition(cb, &vmop.Status.Conditions) return &reconcile.Result{}, nil } From 21165d1bd6dff3efd13aa08c287f1241717acba9 Mon Sep 17 00:00:00 2001 From: Pavel Tishkov Date: Tue, 30 Jun 2026 14:49:15 +0300 Subject: [PATCH 17/25] fix(vd, vi, vdsnapshot): keep the lost object name in the message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Restore the PersistentVolumeClaim/PersistentVolume/VolumeSnapshot name in the *Lost messages: these are public objects (kubectl get pv/pvc/ volumesnapshot) and the name is the actionable detail when one is missing — dropping it loses debuggability. Also align the VirtualImage StorageProfile-missing text with VirtualDisk (StorageClass wording). Signed-off-by: Pavel Tishkov --- .../pkg/controller/vd/internal/source/sources.go | 4 ++-- .../pkg/controller/vdsnapshot/internal/life_cycle.go | 2 +- .../pkg/controller/vi/internal/source/sources.go | 4 ++-- .../pkg/controller/vi/internal/source/sources_test.go | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) 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 85d0c02f8a..9b7b18a6eb 100644 --- a/images/virtualization-artifact/pkg/controller/vd/internal/source/sources.go +++ b/images/virtualization-artifact/pkg/controller/vd/internal/source/sources.go @@ -111,14 +111,14 @@ func setPhaseConditionForFinishedDisk( switch { case pvc == nil: newPhase = v1alpha2.DiskLost - setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Lost, "The underlying PersistentVolumeClaim was not found.") + setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Lost, fmt.Sprintf("The underlying PersistentVolumeClaim %q was not found.", supgen.PersistentVolumeClaim().String())) case pvc.Status.Phase == corev1.ClaimLost: if pvc.GetAnnotations()[annotations.AnnDataExportRequest] == "true" { newPhase = v1alpha2.DiskExporting setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Exporting, "PV is being exported") } else { newPhase = v1alpha2.DiskLost - setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Lost, "The underlying PersistentVolume was not found.") + setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Lost, fmt.Sprintf("The underlying PersistentVolume %q was not found.", pvc.Spec.VolumeName)) } default: newPhase = v1alpha2.DiskReady diff --git a/images/virtualization-artifact/pkg/controller/vdsnapshot/internal/life_cycle.go b/images/virtualization-artifact/pkg/controller/vdsnapshot/internal/life_cycle.go index e2bd72c1cc..ee616e28f0 100644 --- a/images/virtualization-artifact/pkg/controller/vdsnapshot/internal/life_cycle.go +++ b/images/virtualization-artifact/pkg/controller/vdsnapshot/internal/life_cycle.go @@ -109,7 +109,7 @@ func (h LifeCycleHandler) Handle(ctx context.Context, vdSnapshot *v1alpha2.Virtu cb. Status(metav1.ConditionFalse). Reason(vdscondition.VolumeSnapshotLost). - Message("The underlying VolumeSnapshot is no longer available.") + Message(fmt.Sprintf("The underlying VolumeSnapshot %q is no longer available.", vsName)) return reconcile.Result{Requeue: true}, nil } diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/sources.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/sources.go index 54d9196fd0..e27beaa5e1 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/sources.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/sources.go @@ -122,7 +122,7 @@ func setPhaseConditionForFinishedImage( cb. Status(metav1.ConditionFalse). Reason(vicondition.PVCLost). - Message("The underlying PersistentVolumeClaim was not found.") + Message(fmt.Sprintf("The underlying PersistentVolumeClaim %q was not found.", supgen.PersistentVolumeClaim().String())) default: *phase = v1alpha2.ImageReady cb. @@ -215,7 +215,7 @@ func setPhaseConditionFromStorageError(err error, vi *v1alpha2.VirtualImage, cb cb. Status(metav1.ConditionFalse). Reason(vicondition.ProvisioningFailed). - Message("StorageProfile not found in the cluster: Please check a StorageClass name in the cluster or set a default StorageClass.") + Message("The StorageClass is not fully configured in the cluster. Check the StorageClass name or set a default StorageClass.") return true, nil case errors.Is(err, service.ErrDefaultStorageClassNotFound): vi.Status.Phase = v1alpha2.ImagePending diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/sources_test.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/sources_test.go index 7e31bdb82a..8e5529fc39 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/sources_test.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/sources_test.go @@ -212,7 +212,7 @@ var _ = Describe("Sources helpers", func() { Expect(cb.Condition().Reason).To(Equal(expectedReason)) Expect(cb.Condition().Message).To(Equal(expectedMessage)) }, - Entry("marks pvc lost when pvc is missing", nil, v1alpha2.ImagePVCLost, metav1.ConditionFalse, vicondition.PVCLost.String(), "The underlying PersistentVolumeClaim was not found."), + Entry("marks pvc lost when pvc is missing", nil, v1alpha2.ImagePVCLost, metav1.ConditionFalse, vicondition.PVCLost.String(), "The underlying PersistentVolumeClaim \"default/d8v-vi-image-uid\" was not found."), Entry("marks image ready when pvc exists", &corev1.PersistentVolumeClaim{}, v1alpha2.ImageReady, metav1.ConditionTrue, vicondition.Ready.String(), ""), ) @@ -303,7 +303,7 @@ var _ = Describe("Sources helpers", func() { Expect(cb.Condition().Message).To(Equal(expectedMessage)) }, Entry("no error", nil, false, nil, v1alpha2.ImagePhase(""), conditions.ReasonUnknown.String(), ""), - Entry("storage profile missing", volumemode.ErrStorageProfileNotFound, true, nil, v1alpha2.ImageFailed, vicondition.ProvisioningFailed.String(), "StorageProfile not found in the cluster: Please check a StorageClass name in the cluster or set a default StorageClass."), + Entry("storage profile missing", volumemode.ErrStorageProfileNotFound, true, nil, v1alpha2.ImageFailed, vicondition.ProvisioningFailed.String(), "The StorageClass is not fully configured in the cluster. Check the StorageClass name or set a default StorageClass."), Entry("default storage class missing", service.ErrDefaultStorageClassNotFound, true, nil, v1alpha2.ImagePending, vicondition.ProvisioningFailed.String(), "Default StorageClass not found in the cluster: please provide a StorageClass name or set a default StorageClass."), Entry("unexpected error", errors.New("boom"), false, errors.New("boom"), v1alpha2.ImagePhase(""), conditions.ReasonUnknown.String(), ""), ) From 1de05f8fee469998d38a7b76a59a1f1e1dcd0413 Mon Sep 17 00:00:00 2001 From: Pavel Tishkov Date: Tue, 30 Jun 2026 14:51:44 +0300 Subject: [PATCH 18/25] fix(vmop): describe migration progress accurately, not as node moves The in-progress migration messages wrongly invented "destination node" wording. Align them with the actual KubeVirt migration phases and with the VirtualMachine controller wording: scheduling/preparing the migration target, source and target are being synchronized, resumed on the target, suspended on the source. Signed-off-by: Pavel Tishkov --- .../vmop/migration/internal/handler/lifecycle.go | 10 +++++----- .../vmop/migration/internal/handler/lifecycle_test.go | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/images/virtualization-artifact/pkg/controller/vmop/migration/internal/handler/lifecycle.go b/images/virtualization-artifact/pkg/controller/vmop/migration/internal/handler/lifecycle.go index 5375607bed..52c1c2e7b5 100644 --- a/images/virtualization-artifact/pkg/controller/vmop/migration/internal/handler/lifecycle.go +++ b/images/virtualization-artifact/pkg/controller/vmop/migration/internal/handler/lifecycle.go @@ -60,11 +60,11 @@ const ( const ( messageMigrationPending = "The VirtualMachineOperation for migrating the virtual machine has been queued. Waiting for the queue to be processed and for this operation to be executed." - messageSyncingSourceAndTarget = "Synchronizing the VirtualMachine to the destination node" - messageTargetPodScheduling = "Selecting a node to migrate the VirtualMachine to" - messageTargetPodPreparing = "Preparing the destination node for the VirtualMachine" - messageTargetVMResumed = "The VirtualMachine has resumed on the destination node" - messageSourceVMSuspended = "The VirtualMachine has been suspended on the source node" + messageSyncingSourceAndTarget = "Source and target are being synchronized" + messageTargetPodScheduling = "Scheduling the migration target" + messageTargetPodPreparing = "Preparing the migration target" + messageTargetVMResumed = "The virtual machine has resumed on the target" + messageSourceVMSuspended = "The virtual machine has been suspended on the source" ) const ( diff --git a/images/virtualization-artifact/pkg/controller/vmop/migration/internal/handler/lifecycle_test.go b/images/virtualization-artifact/pkg/controller/vmop/migration/internal/handler/lifecycle_test.go index f781a866fb..29dfc6a2a2 100644 --- a/images/virtualization-artifact/pkg/controller/vmop/migration/internal/handler/lifecycle_test.go +++ b/images/virtualization-artifact/pkg/controller/vmop/migration/internal/handler/lifecycle_test.go @@ -674,7 +674,7 @@ var _ = Describe("LifecycleHandler", func() { completed, found := conditions.GetCondition(vmopcondition.TypeCompleted, srv.Changed().Status.Conditions) Expect(found).To(BeTrue()) Expect(completed.Message).NotTo(ContainSubstring("Migration info for 7d38a63b-ffa9-4d56-a924-6017f5832110:")) - Expect(completed.Message).To(ContainSubstring("Synchronizing the VirtualMachine to the destination node. TimeElapsed:30s")) + Expect(completed.Message).To(ContainSubstring("Source and target are being synchronized. TimeElapsed:30s")) Expect(completed.Message).To(ContainSubstring("DataProcessed:3529MiB DataRemaining:12049MiB DataTotal:16405MiB")) Expect(completed.Message).To(ContainSubstring("Iteration:1 AutoConvergeThrottleSet:true AutoConvergeThrottle:0")) }) From eaeb367e9c1013bea102f6895c26d5611449d4fd Mon Sep 17 00:00:00 2001 From: Pavel Tishkov Date: Tue, 30 Jun 2026 15:18:28 +0300 Subject: [PATCH 19/25] fix(usb, vmsop, dvcr): make user-facing condition messages clearer - USBDevice/NodeUSBDevice: drop reconcile internals (NodeUSBDevice condition, USBIP ports, speed) in favour of user terms - VMSOP: rewrite broken English, name the VirtualMachineSnapshot, describe the clone in user terms - dvcr-gc: explain the garbage-collection postpone without the 'create provisioner' internal Signed-off-by: Pavel Tishkov --- .../postponeimporter/postpone_handler.go | 2 +- .../nodeusbdevice/internal/handler/attached.go | 2 +- .../internal/handler/attached_test.go | 2 +- .../usbdevice/internal/handler/lifecycle.go | 8 ++++---- .../vmsop/internal/handler/lifecycle.go | 16 ++++++++-------- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/images/virtualization-artifact/pkg/controller/dvcr-garbage-collection/postponeimporter/postpone_handler.go b/images/virtualization-artifact/pkg/controller/dvcr-garbage-collection/postponeimporter/postpone_handler.go index 006faaca5a..f4b4f6a5be 100644 --- a/images/virtualization-artifact/pkg/controller/dvcr-garbage-collection/postponeimporter/postpone_handler.go +++ b/images/virtualization-artifact/pkg/controller/dvcr-garbage-collection/postponeimporter/postpone_handler.go @@ -102,7 +102,7 @@ func (p *PostponeHandler[T]) Handle(ctx context.Context, obj T) (reconcile.Resul cb := conditions.NewConditionBuilder(getReadyType(obj)).Generation(obj.GetGeneration()) cb.Status(metav1.ConditionFalse). Reason(ProvisioningPostponedReason). - Message("DVCR is in garbage collection mode: wait until it finishes before creating provisioner.") + Message("DVCR is performing garbage collection. The operation is postponed and will continue automatically once it completes.") conditions.SetCondition(cb, conditions.NewConditionsAccessor(obj).Conditions()) } // Garbage collection enabled and resources are postponed: requeue to check garbage collection status later. diff --git a/images/virtualization-artifact/pkg/controller/nodeusbdevice/internal/handler/attached.go b/images/virtualization-artifact/pkg/controller/nodeusbdevice/internal/handler/attached.go index 38cf92a61a..6f9be120ed 100644 --- a/images/virtualization-artifact/pkg/controller/nodeusbdevice/internal/handler/attached.go +++ b/images/virtualization-artifact/pkg/controller/nodeusbdevice/internal/handler/attached.go @@ -79,7 +79,7 @@ func (h *AttachedHandler) Handle(ctx context.Context, s state.NodeUSBDeviceState attachedCondition := meta.FindStatusCondition(usbDevice.Status.Conditions, string(usbdevicecondition.AttachedType)) if attachedCondition == nil { - setAttachedCondition(current, &changed.Status.Conditions, metav1.ConditionFalse, nodeusbdevicecondition.AttachedAvailable, fmt.Sprintf("Attached condition not found in USBDevice %s/%s.", usbDevice.Namespace, usbDevice.Name)) + setAttachedCondition(current, &changed.Status.Conditions, metav1.ConditionFalse, nodeusbdevicecondition.AttachedAvailable, fmt.Sprintf("Waiting for the attachment status of USBDevice %s/%s.", usbDevice.Namespace, usbDevice.Name)) return reconcile.Result{}, nil } diff --git a/images/virtualization-artifact/pkg/controller/nodeusbdevice/internal/handler/attached_test.go b/images/virtualization-artifact/pkg/controller/nodeusbdevice/internal/handler/attached_test.go index 5d1002543d..9c53592b2c 100644 --- a/images/virtualization-artifact/pkg/controller/nodeusbdevice/internal/handler/attached_test.go +++ b/images/virtualization-artifact/pkg/controller/nodeusbdevice/internal/handler/attached_test.go @@ -106,6 +106,6 @@ var _ = Describe("AttachedHandler", func() { }, metav1.ConditionFalse, string(nodeusbdevicecondition.NoFreeUSBIPPort), "No free USBIP ports are available."), Entry("missing attached condition falls back to available", "test-ns", &v1alpha2.USBDevice{ ObjectMeta: metav1.ObjectMeta{Name: "usb-device-1", Namespace: "test-ns"}, - }, metav1.ConditionFalse, string(nodeusbdevicecondition.AttachedAvailable), "Attached condition not found in USBDevice test-ns/usb-device-1."), + }, metav1.ConditionFalse, string(nodeusbdevicecondition.AttachedAvailable), "Waiting for the attachment status of USBDevice test-ns/usb-device-1."), ) }) diff --git a/images/virtualization-artifact/pkg/controller/usbdevice/internal/handler/lifecycle.go b/images/virtualization-artifact/pkg/controller/usbdevice/internal/handler/lifecycle.go index 14b385fee1..47d0431377 100644 --- a/images/virtualization-artifact/pkg/controller/usbdevice/internal/handler/lifecycle.go +++ b/images/virtualization-artifact/pkg/controller/usbdevice/internal/handler/lifecycle.go @@ -95,7 +95,7 @@ func (h *LifecycleHandler) syncReady(ctx context.Context, s state.USBDeviceState } if nodeUSBDevice == nil { - setReadyCondition(current, &changed.Status.Conditions, metav1.ConditionFalse, usbdevicecondition.NotFound, "Corresponding NodeUSBDevice not found.", nil) + setReadyCondition(current, &changed.Status.Conditions, metav1.ConditionFalse, usbdevicecondition.NotFound, "The USB device is no longer present on its node.", nil) return nil } @@ -106,7 +106,7 @@ func (h *LifecycleHandler) syncReady(ctx context.Context, s state.USBDeviceState readyCondition := meta.FindStatusCondition(nodeUSBDevice.Status.Conditions, string(nodeusbdevicecondition.ReadyType)) if readyCondition == nil { - setReadyCondition(current, &changed.Status.Conditions, metav1.ConditionFalse, usbdevicecondition.NotReady, "Ready condition not found in NodeUSBDevice.", nil) + setReadyCondition(current, &changed.Status.Conditions, metav1.ConditionFalse, usbdevicecondition.NotReady, "Waiting for the USB device readiness to be determined.", nil) return nil } @@ -247,8 +247,8 @@ func (h *LifecycleHandler) syncAttached(ctx context.Context, s state.USBDeviceSt } if !hasFreePort { - message := fmt.Sprintf("Device is requested by VirtualMachine %s/%s, but no free USBIP ports are available on node %s for speed %d.", - vm.Namespace, vm.Name, vm.Status.Node, changed.Status.Attributes.Speed) + message := fmt.Sprintf("The USB device is requested by VirtualMachine %s/%s, but node %s has no free USB passthrough capacity for this device.", + vm.Namespace, vm.Name, vm.Status.Node) setAttachedCondition(current, &changed.Status.Conditions, metav1.ConditionFalse, usbdevicecondition.NoFreeUSBIPPort, message) return nil } diff --git a/images/virtualization-artifact/pkg/controller/vmsop/internal/handler/lifecycle.go b/images/virtualization-artifact/pkg/controller/vmsop/internal/handler/lifecycle.go index 7595cc993f..a6faf45dbd 100644 --- a/images/virtualization-artifact/pkg/controller/vmsop/internal/handler/lifecycle.go +++ b/images/virtualization-artifact/pkg/controller/vmsop/internal/handler/lifecycle.go @@ -67,7 +67,7 @@ func (h *LifecycleHandler) Handle(ctx context.Context, vmsop *v1alpha2.VirtualMa } if vmsop.Spec.CreateVirtualMachine == nil { - h.setFailedCondition(cb, vmsop, vmsopcondition.ReasonOperationFailed, "clone specification is mandatory to start creating virtual machine") + h.setFailedCondition(cb, vmsop, vmsopcondition.ReasonOperationFailed, "Cannot start the clone: no parameters for the new virtual machine are specified.") return reconcile.Result{}, nil } @@ -77,40 +77,40 @@ func (h *LifecycleHandler) Handle(ctx context.Context, vmsop *v1alpha2.VirtualMa vms, err := object.FetchObject(ctx, types.NamespacedName{Name: vmsop.Spec.VirtualMachineSnapshotName, Namespace: vmsop.Namespace}, h.client, &v1alpha2.VirtualMachineSnapshot{}) if err != nil { - h.setFailedCondition(cb, vmsop, vmsopcondition.ReasonVirtualMachineSnapshotNotFound, "fail to fetch the virtual machine snapshot") + h.setFailedCondition(cb, vmsop, vmsopcondition.ReasonVirtualMachineSnapshotNotFound, fmt.Sprintf("Failed to read the VirtualMachineSnapshot %q.", vmsop.Spec.VirtualMachineSnapshotName)) return reconcile.Result{}, err } if vms == nil { - h.setFailedCondition(cb, vmsop, vmsopcondition.ReasonVirtualMachineSnapshotNotFound, "virtual machine snapshot not found") + h.setFailedCondition(cb, vmsop, vmsopcondition.ReasonVirtualMachineSnapshotNotFound, fmt.Sprintf("The VirtualMachineSnapshot %q was not found.", vmsop.Spec.VirtualMachineSnapshotName)) return reconcile.Result{}, nil } if vms.Status.Phase != v1alpha2.VirtualMachineSnapshotPhaseReady { - h.setFailedCondition(cb, vmsop, vmsopcondition.ReasonNotReadyToBeExecuted, "virtual machine snapshot is not ready") + h.setFailedCondition(cb, vmsop, vmsopcondition.ReasonNotReadyToBeExecuted, fmt.Sprintf("The VirtualMachineSnapshot %q is not ready yet.", vmsop.Spec.VirtualMachineSnapshotName)) return reconcile.Result{}, nil } restorerSecretKey := types.NamespacedName{Namespace: vms.Namespace, Name: vms.Status.VirtualMachineSnapshotSecretName} restorerSecret, err := object.FetchObject(ctx, restorerSecretKey, h.client, &corev1.Secret{}) if err != nil { - h.setFailedCondition(cb, vmsop, vmsopcondition.ReasonNotReadyToBeExecuted, "fail to fetch the virtual machine snapshot secret") + h.setFailedCondition(cb, vmsop, vmsopcondition.ReasonNotReadyToBeExecuted, "The VirtualMachineSnapshot is not ready to be used yet.") return reconcile.Result{}, err } if restorerSecret == nil { - msg := "fail to fetch the virtual machine snapshot secret: secret is nil" + msg := "The VirtualMachineSnapshot is not ready to be used yet." h.setFailedCondition(cb, vmsop, vmsopcondition.ReasonNotReadyToBeExecuted, msg) return reconcile.Result{}, errors.New(msg) } hasInProgress, err := h.hasOperationsInProgress(ctx, vmsop) if err != nil { - h.setFailedCondition(cb, vmsop, vmsopcondition.ReasonNotReadyToBeExecuted, "fail to check if there is any operation in progress") + h.setFailedCondition(cb, vmsop, vmsopcondition.ReasonNotReadyToBeExecuted, "Failed to check for other operations in progress.") return reconcile.Result{}, err } if hasInProgress { - h.setFailedCondition(cb, vmsop, vmsopcondition.ReasonNotReadyToBeExecuted, "VMSOP cannot be executed now. Previously created operation should finish first") + h.setFailedCondition(cb, vmsop, vmsopcondition.ReasonNotReadyToBeExecuted, "The operation cannot start yet: another operation must finish first.") return reconcile.Result{}, nil } From 3db4cdfbb673733d7b968ccbc90f5f8897d92e7d Mon Sep 17 00:00:00 2001 From: Pavel Tishkov Date: Tue, 30 Jun 2026 15:26:56 +0300 Subject: [PATCH 20/25] fix(vi): describe the PersistentVolumeClaim being prepared, not 'image storage' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a VirtualImage is stored on a PVC, the provisioning message said 'Preparing the image storage.' — vague and inconsistent with the next state 'Importing data into the PersistentVolumeClaim.'. Name the PersistentVolumeClaim being prepared so the message reflects what actually happens. Signed-off-by: Pavel Tishkov --- .../pkg/controller/vi/internal/source/object_ref.go | 2 +- .../pkg/controller/vi/internal/source/object_ref_vd.go | 2 +- .../pkg/controller/vi/internal/source/object_ref_vi_on_pvc.go | 2 +- .../pkg/controller/vi/internal/source/registry.go | 2 +- .../pkg/controller/vi/internal/source/sources.go | 2 +- .../pkg/controller/vi/internal/source/sources_test.go | 2 +- .../pkg/controller/vi/internal/source/upload.go | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref.go index 9d7d7cccb6..2d11d4d410 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref.go @@ -224,7 +224,7 @@ func (ds ObjectRefDataSource) StoreToPVC(ctx context.Context, vi *v1alpha2.Virtu cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Preparing the image storage.") + Message("Preparing the PersistentVolumeClaim for the image.") return reconcile.Result{RequeueAfter: time.Second}, nil case dvQuotaNotExceededCondition != nil && dvQuotaNotExceededCondition.Status == corev1.ConditionFalse: diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vd.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vd.go index db04ee7e4a..e8e87ffdc7 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vd.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vd.go @@ -298,7 +298,7 @@ func (ds ObjectRefVirtualDisk) StoreToPVC(ctx context.Context, vi *v1alpha2.Virt cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Preparing the image storage.") + Message("Preparing the PersistentVolumeClaim for the image.") return reconcile.Result{RequeueAfter: time.Second}, nil case dvQuotaNotExceededCondition != nil && dvQuotaNotExceededCondition.Status == corev1.ConditionFalse: diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vi_on_pvc.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vi_on_pvc.go index 0405b88484..8218e2a304 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vi_on_pvc.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vi_on_pvc.go @@ -276,7 +276,7 @@ func (ds ObjectRefDataVirtualImageOnPVC) StoreToPVC(ctx context.Context, vi, viR cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Preparing the image storage.") + Message("Preparing the PersistentVolumeClaim for the image.") return reconcile.Result{RequeueAfter: time.Second}, nil case dvQuotaNotExceededCondition != nil && dvQuotaNotExceededCondition.Status == corev1.ConditionFalse: diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/registry.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/registry.go index ac3a990ce4..c781e9a03d 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/registry.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/registry.go @@ -225,7 +225,7 @@ func (ds RegistryDataSource) StoreToPVC(ctx context.Context, vi *v1alpha2.Virtua cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Preparing the image storage.") + Message("Preparing the PersistentVolumeClaim for the image.") return reconcile.Result{RequeueAfter: time.Second}, nil case dvQuotaNotExceededCondition != nil && dvQuotaNotExceededCondition.Status == corev1.ConditionFalse: diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/sources.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/sources.go index e27beaa5e1..86b1be6fab 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/sources.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/sources.go @@ -156,7 +156,7 @@ func setPhaseConditionForPVCProvisioningImage( cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Preparing the image storage.") + Message("Preparing the PersistentVolumeClaim for the image.") return nil } diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/sources_test.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/sources_test.go index 8e5529fc39..ddc11b00b5 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/sources_test.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/sources_test.go @@ -242,7 +242,7 @@ var _ = Describe("Sources helpers", func() { Expect(cb.Condition().Reason).To(Equal(expectedReason)) Expect(cb.Condition().Message).To(Equal(expectedMessage)) }, - Entry("waits for pvc importer creation when dv is absent", nil, nil, v1alpha2.ImageProvisioning, metav1.ConditionFalse, vicondition.Provisioning.String(), "Preparing the image storage.", nil), + Entry("waits for pvc importer creation when dv is absent", nil, nil, v1alpha2.ImageProvisioning, metav1.ConditionFalse, vicondition.Provisioning.String(), "Preparing the PersistentVolumeClaim for the image.", nil), Entry("reports provisioning in progress", &cdiv1.DataVolume{}, nil, v1alpha2.ImageProvisioning, metav1.ConditionFalse, vicondition.Provisioning.String(), "Importing data into the PersistentVolumeClaim.", nil), Entry("handles data volume not running", &cdiv1.DataVolume{}, service.ErrDataVolumeNotRunning, v1alpha2.ImageProvisioning, metav1.ConditionFalse, vicondition.ProvisioningFailed.String(), "Pvc importer is not running", nil), Entry("handles missing default storage class", &cdiv1.DataVolume{}, service.ErrDefaultStorageClassNotFound, v1alpha2.ImagePending, metav1.ConditionFalse, vicondition.ProvisioningFailed.String(), "Default StorageClass not found in the cluster: please provide a StorageClass name or set a default StorageClass.", nil), diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/upload.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/upload.go index f856e7db29..dab2dff73b 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/upload.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/upload.go @@ -281,7 +281,7 @@ func (ds UploadDataSource) StoreToPVC(ctx context.Context, vi *v1alpha2.VirtualI cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Preparing the image storage.") + Message("Preparing the PersistentVolumeClaim for the image.") return reconcile.Result{RequeueAfter: time.Second}, nil case dvQuotaNotExceededCondition != nil && dvQuotaNotExceededCondition.Status == corev1.ConditionFalse: From ab6a0b1fe4ea6d56e817588632d480d0759ef20f Mon Sep 17 00:00:00 2001 From: Pavel Tishkov Date: Tue, 30 Jun 2026 15:32:25 +0300 Subject: [PATCH 21/25] fix(vmbda): don't report a running VM as 'not running' on transient instance gap These branches are reached only after the VirtualMachineReady condition is True (VM confirmed Running with its instance present). A subsequent nil read of the underlying instance is a transient gap, not a stopped VM. Saying 'is not running' contradicted both the VM phase and the sibling readiness handler. Align the wording: the VirtualMachine is Running, its underlying instance is just not ready yet. Signed-off-by: Pavel Tishkov --- .../pkg/controller/vmbda/internal/life_cycle.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/images/virtualization-artifact/pkg/controller/vmbda/internal/life_cycle.go b/images/virtualization-artifact/pkg/controller/vmbda/internal/life_cycle.go index f17d6bff94..6dfce1a459 100644 --- a/images/virtualization-artifact/pkg/controller/vmbda/internal/life_cycle.go +++ b/images/virtualization-artifact/pkg/controller/vmbda/internal/life_cycle.go @@ -173,7 +173,7 @@ func (h LifeCycleHandler) Handle(ctx context.Context, vmbda *v1alpha2.VirtualMac cb. Status(metav1.ConditionFalse). Reason(vmbdacondition.NotAttached). - Message(fmt.Sprintf("VirtualMachine %q is not running.", vm.Name)) + Message(fmt.Sprintf("VirtualMachine %q is Running, but its underlying virtualization instance is not ready yet.", vm.Name)) return reconcile.Result{}, nil } @@ -187,7 +187,7 @@ func (h LifeCycleHandler) Handle(ctx context.Context, vmbda *v1alpha2.VirtualMac cb. Status(metav1.ConditionFalse). Reason(vmbdacondition.NotAttached). - Message(fmt.Sprintf("VirtualMachine %q is not running.", vm.Name)) + Message(fmt.Sprintf("VirtualMachine %q is Running, but its underlying virtualization instance is not ready yet.", vm.Name)) return reconcile.Result{}, nil } From 38f2f839048cc4783f57d56f4562cea3bbe14dd4 Mon Sep 17 00:00:00 2001 From: Pavel Tishkov Date: Tue, 30 Jun 2026 15:37:32 +0300 Subject: [PATCH 22/25] fix(vd, vi, vdsnapshot): address PR review comments on condition messages - vd: 'PV is being exported' -> full name 'The PersistentVolume is being exported.' - vi: name and punctuate the PVC-bound wait ('Waiting for the PersistentVolumeClaim to be Bound.'); kept name-less because pvc may be nil on this branch (the %q in the suggestion would render empty/panic) - vdsnapshot: the snapshot-of-disk wait interpolated the snapshot's own name; use spec.virtualDiskName so %q is the disk Signed-off-by: Pavel Tishkov --- .../pkg/controller/vd/internal/source/sources.go | 2 +- .../pkg/controller/vdsnapshot/internal/life_cycle.go | 2 +- .../pkg/controller/vi/internal/source/step/wait_for_pod_step.go | 2 +- .../vi/internal/source/step/wait_for_pod_step_test.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) 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 9b7b18a6eb..be0fd05552 100644 --- a/images/virtualization-artifact/pkg/controller/vd/internal/source/sources.go +++ b/images/virtualization-artifact/pkg/controller/vd/internal/source/sources.go @@ -115,7 +115,7 @@ func setPhaseConditionForFinishedDisk( case pvc.Status.Phase == corev1.ClaimLost: if pvc.GetAnnotations()[annotations.AnnDataExportRequest] == "true" { newPhase = v1alpha2.DiskExporting - setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Exporting, "PV is being exported") + setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Exporting, "The PersistentVolume is being exported.") } else { newPhase = v1alpha2.DiskLost setReadyConditionWithWFFCAccounting(vd, cb, metav1.ConditionFalse, vdcondition.Lost, fmt.Sprintf("The underlying PersistentVolume %q was not found.", pvc.Spec.VolumeName)) diff --git a/images/virtualization-artifact/pkg/controller/vdsnapshot/internal/life_cycle.go b/images/virtualization-artifact/pkg/controller/vdsnapshot/internal/life_cycle.go index ee616e28f0..c0850ab0e8 100644 --- a/images/virtualization-artifact/pkg/controller/vdsnapshot/internal/life_cycle.go +++ b/images/virtualization-artifact/pkg/controller/vdsnapshot/internal/life_cycle.go @@ -392,7 +392,7 @@ func (h LifeCycleHandler) Handle(ctx context.Context, vdSnapshot *v1alpha2.Virtu cb. Status(metav1.ConditionFalse). Reason(vdscondition.Snapshotting). - Message(fmt.Sprintf("Waiting for the snapshot of virtual disk %q to be ready to use.", vdSnapshot.Name)) + Message(fmt.Sprintf("Waiting for the snapshot of virtual disk %q to be ready to use.", vdSnapshot.Spec.VirtualDiskName)) return reconcile.Result{}, nil default: log.Debug("The volume snapshot is ready to use") diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/step/wait_for_pod_step.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/step/wait_for_pod_step.go index f17c8ce298..385c3dd5e1 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/step/wait_for_pod_step.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/step/wait_for_pod_step.go @@ -80,7 +80,7 @@ func (s WaitForPodStep) Take(_ context.Context, vi *v1alpha2.VirtualImage) (*rec s.cb. Status(metav1.ConditionFalse). Reason(vicondition.Provisioning). - Message("Waiting for PersistentVolumeClaim to be Bound") + Message("Waiting for the PersistentVolumeClaim to be Bound.") return &reconcile.Result{Requeue: true}, nil } diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/step/wait_for_pod_step_test.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/step/wait_for_pod_step_test.go index 456ca09d19..31ea23bb64 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/step/wait_for_pod_step_test.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/step/wait_for_pod_step_test.go @@ -114,7 +114,7 @@ var _ = Describe("WaitForPodStep", func() { reconcile.Result{Requeue: true}, v1alpha2.ImageProvisioning, vicondition.Provisioning.String(), - "Waiting for PersistentVolumeClaim to be Bound", + "Waiting for the PersistentVolumeClaim to be Bound.", "", "", ), From 92afada3f2f3a813e02edce346df33630bd0d1c5 Mon Sep 17 00:00:00 2001 From: Pavel Tishkov Date: Tue, 30 Jun 2026 15:55:49 +0300 Subject: [PATCH 23/25] fix(vmsop): satisfy staticcheck ST1005 on the secret-nil error The condition message kept its trailing period (user-facing), but the same string was reused for errors.New, which ST1005 flags. Split them: period for the status message, a plain lowercase Go error for the return. Signed-off-by: Pavel Tishkov --- .../pkg/controller/vmsop/internal/handler/lifecycle.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/images/virtualization-artifact/pkg/controller/vmsop/internal/handler/lifecycle.go b/images/virtualization-artifact/pkg/controller/vmsop/internal/handler/lifecycle.go index a6faf45dbd..e919880cd7 100644 --- a/images/virtualization-artifact/pkg/controller/vmsop/internal/handler/lifecycle.go +++ b/images/virtualization-artifact/pkg/controller/vmsop/internal/handler/lifecycle.go @@ -99,9 +99,8 @@ func (h *LifecycleHandler) Handle(ctx context.Context, vmsop *v1alpha2.VirtualMa } if restorerSecret == nil { - msg := "The VirtualMachineSnapshot is not ready to be used yet." - h.setFailedCondition(cb, vmsop, vmsopcondition.ReasonNotReadyToBeExecuted, msg) - return reconcile.Result{}, errors.New(msg) + h.setFailedCondition(cb, vmsop, vmsopcondition.ReasonNotReadyToBeExecuted, "The VirtualMachineSnapshot is not ready to be used yet.") + return reconcile.Result{}, errors.New("virtual machine snapshot secret is nil") } hasInProgress, err := h.hasOperationsInProgress(ctx, vmsop) From 594636b31ef884a45fc754711bc0bad410336f48 Mon Sep 17 00:00:00 2001 From: Pavel Tishkov Date: Tue, 30 Jun 2026 16:27:02 +0300 Subject: [PATCH 24/25] fix(vm): give actionable guidance in agent and class condition messages - guest agent not responding / version unsupported: tell the user to install/start/update the agent in the guest OS - VirtualMachineClass not found: advise specifying an existing class in spec.virtualMachineClassName (full resource name, period) - sizing-policy mismatch: drop the doubled prefix, lead with the VirtualMachine, keep the concrete details and existing guidance Signed-off-by: Pavel Tishkov --- .../pkg/controller/service/size_policy_service.go | 2 +- .../pkg/controller/vm/internal/agent.go | 6 +++--- .../pkg/controller/vm/internal/class.go | 6 +++--- .../pkg/controller/vm/internal/size_policy.go | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/images/virtualization-artifact/pkg/controller/service/size_policy_service.go b/images/virtualization-artifact/pkg/controller/service/size_policy_service.go index c6e4149600..d098ad3708 100644 --- a/images/virtualization-artifact/pkg/controller/service/size_policy_service.go +++ b/images/virtualization-artifact/pkg/controller/service/size_policy_service.go @@ -65,7 +65,7 @@ func (s *SizePolicyService) CheckVMMatchedSizePolicy(vm *v1alpha2.VirtualMachine } if len(errs) > 0 { - return fmt.Errorf("sizing policy validation has failed: %w: %w", errors.Join(errs...), ErrSizingPolicyValidation) + return fmt.Errorf("does not match the VirtualMachineClass sizing policy: %w: %w", errors.Join(errs...), ErrSizingPolicyValidation) } return nil diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/agent.go b/images/virtualization-artifact/pkg/controller/vm/internal/agent.go index e542806b3f..5665e79fba 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/agent.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/agent.go @@ -95,7 +95,7 @@ func (h *AgentHandler) syncAgentReady(vm *v1alpha2.VirtualMachine, kvvmi *virtv1 case metav1.ConditionTrue: cb.Status(status).Reason(vmcondition.ReasonAgentReady).Message(c.Message) case metav1.ConditionFalse: - cb.Status(status).Reason(vmcondition.ReasonAgentNotReady).Message(c.Message) + cb.Status(status).Reason(vmcondition.ReasonAgentNotReady).Message("The guest agent is not responding. Make sure the guest agent is installed and running in the guest OS.") } return @@ -104,7 +104,7 @@ func (h *AgentHandler) syncAgentReady(vm *v1alpha2.VirtualMachine, kvvmi *virtv1 cb.Status(metav1.ConditionFalse). Reason(vmcondition.ReasonAgentNotReady). - Message("Failed to connect to VM Agent.") + Message("The guest agent is not responding. Make sure the guest agent is installed and running in the guest OS.") } func (h *AgentHandler) syncAgentVersionNotSupport(vm *v1alpha2.VirtualMachine, kvvmi *virtv1.VirtualMachineInstance) { @@ -138,7 +138,7 @@ func (h *AgentHandler) syncAgentVersionNotSupport(vm *v1alpha2.VirtualMachine, k for _, c := range kvvmi.Status.Conditions { status := conditionStatus(string(c.Status)) if c.Type == virtv1.VirtualMachineInstanceUnsupportedAgent && status == metav1.ConditionTrue { - cb.Status(status).Reason(vmcondition.ReasonAgentNotSupported).Message("The guest agent version is not supported.") + cb.Status(status).Reason(vmcondition.ReasonAgentNotSupported).Message("The guest agent version is not supported. Update the guest agent in the guest OS.") return } } diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/class.go b/images/virtualization-artifact/pkg/controller/vm/internal/class.go index a78c5d0cc3..c61fd7f5d2 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/class.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/class.go @@ -78,7 +78,7 @@ func (h *ClassHandler) Handle(ctx context.Context, s state.VirtualMachineState) if class != nil && class.Status.Phase == v1alpha2.ClassPhaseReady { if (class.Spec.CPU.Type == v1alpha2.CPUTypeDiscovery || class.Spec.CPU.Type == v1alpha2.CPUTypeFeatures) && len(class.Status.CpuFeatures.Enabled) == 0 { mgr.Update(cb. - Message("No enabled processor features found"). + Message("The VirtualMachineClass has no enabled CPU features."). Reason(vmcondition.ReasonClassNotReady). Status(metav1.ConditionFalse). Condition()) @@ -90,10 +90,10 @@ func (h *ClassHandler) Handle(ctx context.Context, s state.VirtualMachineState) return reconcile.Result{}, nil } className := current.Spec.VirtualMachineClassName - msg := fmt.Sprintf("VirtualMachineClassName %q is not ready", className) + msg := fmt.Sprintf("VirtualMachineClass %q is not ready yet.", className) reason := vmcondition.ReasonClassNotReady if class == nil { - msg = fmt.Sprintf("VirtualMachineClassName %q not found", className) + msg = fmt.Sprintf("VirtualMachineClass %q not found. Specify an existing VirtualMachineClass in spec.virtualMachineClassName.", className) h.recorder.Event(changed, corev1.EventTypeWarning, reason.String(), "VirtualMachineClass not available: waiting for the VirtualMachineClass") log.Info("VirtualMachineClass not available: waiting for the VirtualMachineClass") } diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/size_policy.go b/images/virtualization-artifact/pkg/controller/vm/internal/size_policy.go index bcee2a48df..896a5b7c67 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/size_policy.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/size_policy.go @@ -72,7 +72,7 @@ func (h *SizePolicyHandler) Handle(ctx context.Context, s state.VirtualMachineSt switch { case vmClass == nil: - cb.Message(fmt.Sprintf("VirtualMachineClass %q not found.", changed.Spec.VirtualMachineClassName)). + cb.Message(fmt.Sprintf("VirtualMachineClass %q not found. Specify an existing VirtualMachineClass in spec.virtualMachineClassName.", changed.Spec.VirtualMachineClassName)). Reason(vmcondition.ReasonVirtualMachineClassNotFound). Status(metav1.ConditionFalse) case vmClass.Status.Phase == v1alpha2.ClassPhaseTerminating: @@ -82,7 +82,7 @@ func (h *SizePolicyHandler) Handle(ctx context.Context, s state.VirtualMachineSt default: err = h.service.CheckVMMatchedSizePolicy(changed, vmClass) if err != nil { - cb.Message(fmt.Sprintf("Size policy matching errors: %s.", err.Error())). + cb.Message(fmt.Sprintf("The VirtualMachine %s.", err.Error())). Reason(vmcondition.ReasonSizingPolicyNotMatched). Status(metav1.ConditionFalse) } From 36a20e806cb4a3e8ebdc99277003479aa874f849 Mon Sep 17 00:00:00 2001 From: Pavel Tishkov Date: Tue, 30 Jun 2026 16:36:15 +0300 Subject: [PATCH 25/25] fix(vm): clarify why live migration is blocked, with applicable guidance - disks: state the ReadWriteMany requirement in user terms and point to the StorageClass to check (no false promise that RWX is available) - non-migratable device: drop the kubevirt 'host devices' jargon and the USB-implying wording (USB is migratable); state the block plainly and advise removing the offending device Signed-off-by: Pavel Tishkov --- .../pkg/controller/vm/internal/migrating.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/migrating.go b/images/virtualization-artifact/pkg/controller/vm/internal/migrating.go index 09fba85f2e..e483a454f8 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/migrating.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/migrating.go @@ -295,14 +295,14 @@ func (h *MigratingHandler) syncMigratable(ctx context.Context, s state.VirtualMa } else { cb.Status(metav1.ConditionFalse). Reason(vmcondition.ReasonDisksNotMigratable). - Message("Live migration requires that all PVCs must be shared (using ReadWriteMany access mode)") + Message("Live migration requires all disks to use ReadWriteMany (shared) storage. Make sure the StorageClass supports the ReadWriteMany access mode.") } conditions.SetCondition(cb, &vm.Status.Conditions) return nil case liveMigratable.Reason == virtv1.VirtualMachineInstanceReasonHostDeviceNotMigratable: cb.Status(metav1.ConditionFalse). Reason(vmcondition.ReasonHostDevicesNotMigratable). - Message("Live migration requires that all Host Devices must be unplugged") + Message("Live migration is blocked because the VirtualMachine has a device that cannot be migrated. Remove it to enable live migration.") conditions.SetCondition(cb, &vm.Status.Conditions) return nil @@ -327,7 +327,7 @@ func (h *MigratingHandler) syncMigratable(ctx context.Context, s state.VirtualMa } else { cb.Status(metav1.ConditionFalse). Reason(vmcondition.ReasonDisksNotMigratable). - Message("Live migration requires that all PVCs must be shared (using ReadWriteMany access mode)") + Message("Live migration requires all disks to use ReadWriteMany (shared) storage. Make sure the StorageClass supports the ReadWriteMany access mode.") } conditions.SetCondition(cb, &vm.Status.Conditions) return nil