Repository navigation
Description
A VMDisk whose PVC never binds reports WorkloadsReady=True with the message "All workloads are operational". The condition is not merely uninformative here, it states the opposite of what is happening, and it stays that way for as long as the disk sits unbound.
internal/controller/workloadmonitor_controller.go derives the aggregate from ready pods counted against minReplicas. A vm-disk release declares no pods, so the comparison is 0 against 0 and comes out satisfied. The Workload object that the unbound PVC produces already carries operational: false, and the aggregation drops it rather than folding it in, so the one signal that knows the truth is the one that does not reach the condition.
The obvious repair does not work. Adding "an unbound PVC means not operational" would report every unattached blank disk as broken, because a WaitForFirstConsumer volume is legitimately unbound until a VM attaches to it, which is the normal state for a disk created ahead of the VM that will use it. So the fix has to distinguish "unbound and waiting for a consumer that has not arrived" from "unbound and never going to bind", and the controller as written has no input that separates them.
The same 0/0 shape exists for bucket, so whatever lands here should be checked against that one rather than written for disks alone.
Found while looking at #2908, where a cross-StorageClass clone leaves a disk unbound indefinitely. That issue is about the failure being invisible; this is about the status actively asserting health while it happens, which is the part that survives even after the clone case itself is addressed.
Activity
lexfrei commentedon Sep 23, 2026
The vm-disk half of this is fixed by #4380 once it merges. Paths below are at its head b0ff186. The monitor now reads the DataVolume phase and reports not operational while CDI is still working on the disk (
internal/controller/workloadmonitor_controller.go:103-131, applied at:866-868). That phase is the input this issue said the controller was missing.At CDI v1.66.1 an unbound target PVC on the populator path goes to
PendingPopulationonly when the class is WaitForFirstConsumer, no node is selected yet and immediate binding was not requested (shouldBeMarkedPendingPopulationinpkg/controller/datavolume/controller-base.go). Otherwise the DataVolume takes a populator phase such asCloneScheduled,CSICloneInProgressorPrepClaimInProgress, and #4380 counts every one of them as in flight. So a disk waiting for its first VM stays green, and a clone that never binds, as in #2908, turnsWorkloadsReadyFalse. The phase table inTestReconcile_DataVolumePhaseDecidesOperationalpins both sides (internal/controller/workloadmonitor_controller_test.go:1234).I'm narrowing this issue to what #4380 leaves open. The aggregate still ignores the per-object
Workload.Status.Operational(workloadmonitor_controller.go:862-865), so a bucket monitor withminReplicas: 0reports operational whatever its BucketClaims say. That is the 0/0 shape from the description, and it is untouched.There is also a smaller vm-disk gap. On a StorageClass without a CSI driver CDI does not use populators, and a pending PVC on a WaitForFirstConsumer class reads
WaitForFirstConsumereven when immediate binding was requested (updateStatusPVCPendingin the same CDI file). #4380 counts that phase as settled, so a disk stuck there stays green. I don't know of a cozystack default class that takes this path.lexfrei commentedon Sep 24, 2026
The disagreement also goes the other way for a disk that waits for its first VM. With
bindImmediately: falseon a WaitForFirstConsumer class, the DataVolume rests inPendingPopulationorWaitForFirstConsumer, which #4380 counts as settled, soWorkloadsReadyis True. The PVC is still Pending andisPVCReadychecks bind state only, so thepvc-<name>Workload of the same monitor reads not operational. #4380 aligns that Workload with its DataVolume only when the DataVolume is not ready, so this direction stays. Reading a PVC controlled by a settled DataVolume as operational would close it.