Explicitly set model='virtio-scsi' for SCSI controllers on Q35 guests - #193
Explicitly set model='virtio-scsi' for SCSI controllers on Q35 guests#193B-Woody wants to merge 4 commits into
Conversation
| xml.address(:type => "drive", :controller => 0, :bus => 0, :unit => 0) | ||
| end | ||
| end | ||
| if volumes.any? { |v| v.bus == 'scsi' } |
There was a problem hiding this comment.
Tests fail with this:
Error saving the server: undefined method `bus' for <Fog::Libvirt::Compute::Volume
Not sure if this is due to the mock driver we're using, but in the docs I can't find a reference. I can see sometimes we're setting it as part of the target though.
|
Apologies for the test failure! According to the LLM:
When I tested it on a live server I just had a straight device definition without the if condition: I'm a bit out of my depth here, as I'm not a Ruby dev. I'll step out of the way and let some more experienced folks take a look. Hopefully it's almost there. |
|
Hi, Just wondering if this needs any changes to be merged? Initially this was just to fix an edge case in my homelab, but as it turns out, I now have a customer who may run into a similar issues eventually, as they're looking to do image-based provisioning from Satellite with some RHEL KVM/libvirt hosts. If this needs changes I'd be happy to take another look at it. |
Problem
When utilising image-based provisioning via Red Hat Satellite (specifically verified on Satellite 6.19.2 running fog-libvirt 0.14.0) onto a libvirt provider, cloud-init user-data fails to execute.
The breakdown occurs because Satellite/fog-libvirt targets a SCSI bus (bus='scsi') to attach the user-data ISO payload on modern Q35 machine types. However, because no explicit controller model is provided in the generated XML, libvirt defaults to a legacy controller emulation type (it was
lsilogicon my system).Modern Red Hat Enterprise Linux (RHEL) minimal/cloud images don't load legacy storage drivers for
lsilogic. As a result, the guest kernel cannot see the underlying storage controller, /dev/sda is never initialized inside the VM, and cloud-init fails to detect its datasource.Solution
This PR injects a conditional check inside the XML builder block within server.rb. If any attached volumes are configured to use a scsi bus, it programmatically forces libvirt to instantiate a modern virtio-scsi controller layout:
This ensures out-of-the-box compatibility for RHEL cloud images.
Development & Testing Notes
Disclaimer: I am not natively a Ruby developer! After troubleshooting and isolating the root cause in the hypervisor XML configurations, I consulted a Large Language Model (LLM) to assist me in mapping the logic safely into the native Nokogiri syntax used by the gem's codebase.
Validation: This fix was live-patched directly into server.rb on a production Red Hat Satellite 6.19.2 server running fog-libvirt-0.14.0. Post-patch testing verified that newly provisioned VMs successfully attached the virtual media controller using virtio-scsi. The guest kernels immediately mapped the volume to /dev/sda, allowing cloud-init to fetch the metadata source and run the commands in user-data.