-
Notifications
You must be signed in to change notification settings - Fork 2
fix(vd): prevent VirtualDisk from stuck in WaitForFirstConsumer phase when VM is attached #1516
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Reviewer's GuideUpdates to WFFC handling in VirtualDisk controller: logic now dynamically fetches StorageClass binding mode, excludes disks with attached VMs from staying in WaitForFirstConsumer phase, and corresponding test adjustments were made. Sequence diagram for VirtualDisk phase update after VM attachmentsequenceDiagram
participant VDController
participant VirtualDisk
participant StorageClass
participant VM
participant DataVolume
VDController->>VirtualDisk: Check Status.Phase
VDController->>StorageClass: Fetch by StorageClassName
StorageClass-->>VDController: Return VolumeBindingMode
VDController->>VirtualDisk: Check AttachedToVirtualMachines
alt VolumeBindingMode is WaitForFirstConsumer and no VM attached
VDController->>VirtualDisk: Set Phase to WaitForFirstConsumer
else VM is attached
VDController->>VirtualDisk: Do not set Phase to WaitForFirstConsumer
end
Class diagram for updated VirtualDisk WaitForFirstConsumer logicclassDiagram
class BlockDeviceHandler {
+checkVirtualDisksToBeWFFC(ctx, s)
client
}
class VirtualDisk {
Status
Status.Phase
Status.StorageClassName
Status.Conditions
Status.AttachedToVirtualMachines
}
class StorageClass {
VolumeBindingMode
}
BlockDeviceHandler --> VirtualDisk : checks
BlockDeviceHandler --> StorageClass : fetches
VirtualDisk --> StorageClass : references by StorageClassName
class WaitForDVStep {
+setForFirstConsumerIsAwaited(ctx, vd)
dv
cb
}
WaitForDVStep --> VirtualDisk : updates phase
WaitForDVStep --> StorageClass : checks binding mode
class DataVolume {
Status.Phase
}
WaitForDVStep --> DataVolume : checks phase
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Signed-off-by: Daniil Loktev <[email protected]>
7cb3b44
to
1909f13
Compare
Signed-off-by: Daniil Loktev <[email protected]>
Signed-off-by: Daniil Loktev <[email protected]>
Signed-off-by: Daniil Loktev <[email protected]>
Signed-off-by: Daniil Loktev <[email protected]>
Workflow has started. The target step completed with status: failure. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey there - I've reviewed your changes and they look great!
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location> `images/virtualization-artifact/pkg/controller/vm/internal/block_device_condition.go:60-66` </location>
<code_context>
for _, vd := range vds {
- if vd.Status.Phase == v1alpha2.DiskWaitForFirstConsumer {
- return true, nil
+ scName := vd.Status.StorageClassName
+ sc, err := object.FetchObject(ctx, types.NamespacedName{Name: scName}, h.client, &storagev1.StorageClass{})
+ if err != nil {
+ return false, fmt.Errorf("fetch storage class %s: %w", scName, err)
+ }
+
+ if sc != nil && sc.VolumeBindingMode != nil && *sc.VolumeBindingMode == storagev1.VolumeBindingWaitForFirstConsumer {
+ readyCondition, _ := conditions.GetCondition(vdcondition.ReadyType, vd.Status.Conditions)
+ if readyCondition.Status != metav1.ConditionTrue {
</code_context>
<issue_to_address>
**suggestion:** Consider handling missing or empty StorageClassName more explicitly.
If vd.Status.StorageClassName is empty, FetchObject will try to fetch a storage class with an empty name, which could cause errors or unnecessary log entries. Consider adding a check to handle this case before calling FetchObject.
</issue_to_address>
### Comment 2
<location> `images/virtualization-artifact/pkg/controller/vm/internal/block_device_condition.go:68` </location>
<code_context>
+ readyCondition, _ := conditions.GetCondition(vdcondition.ReadyType, vd.Status.Conditions)
</code_context>
<issue_to_address>
**issue (bug_risk):** Check for nil readyCondition before accessing Status.
Add a nil check for readyCondition before accessing its Status to prevent a potential panic.
</issue_to_address>
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
scName := vd.Status.StorageClassName | ||
sc, err := object.FetchObject(ctx, types.NamespacedName{Name: scName}, h.client, &storagev1.StorageClass{}) | ||
if err != nil { | ||
return false, fmt.Errorf("fetch storage class %s: %w", scName, err) | ||
} | ||
|
||
if sc != nil && sc.VolumeBindingMode != nil && *sc.VolumeBindingMode == storagev1.VolumeBindingWaitForFirstConsumer { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: Consider handling missing or empty StorageClassName more explicitly.
If vd.Status.StorageClassName is empty, FetchObject will try to fetch a storage class with an empty name, which could cause errors or unnecessary log entries. Consider adding a check to handle this case before calling FetchObject.
|
||
if sc != nil && sc.VolumeBindingMode != nil && *sc.VolumeBindingMode == storagev1.VolumeBindingWaitForFirstConsumer { | ||
readyCondition, _ := conditions.GetCondition(vdcondition.ReadyType, vd.Status.Conditions) | ||
if readyCondition.Status != metav1.ConditionTrue { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (bug_risk): Check for nil readyCondition before accessing Status.
Add a nil check for readyCondition before accessing its Status to prevent a potential panic.
for _, vd := range vds { | ||
if vd.Status.Phase == v1alpha2.DiskWaitForFirstConsumer { | ||
return true, nil | ||
scName := vd.Status.StorageClassName |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we check the SC type of the disk in VM? Why can't we trust the VD phase?
Description
Fix VirtualDisk remaining in
WaitForFirstConsumer
phase even after VM attachment and provisioning has started.Why do we need it, and what problem does it solve?
When using WFFC storage class with volume populators:
WaitForFirstConsumer
waiting for VMWaitForFirstConsumer
because DataVolume is inPendingPopulation
state, even though the "first consumer" (VM) already existsThis creates perception of "hanging" - users see VD stuck in WFFC for minutes while provisioning is actually running.
What is the expected result?
Checklist
Changelog entries