fix: handle nil network name for bridge/direct interfaces#189
Conversation
ekohl
left a comment
There was a problem hiding this comment.
Please address the RuboCop issue too
|
Feedback addressed @ekohl |
ekohl
left a comment
There was a problem hiding this comment.
fog-libvirt'saddresses()passesnic.network(nil) tolist_networks, which callslookup_network_by_name(nil), raising:
I'm rereading this now and this is:
fog-libvirt/lib/fog/libvirt/models/compute/server.rb
Lines 475 to 489 in eb3ca30
In particular:
Isn't the better fix to try and find the first nic with a network? So:
if (nic = self.nics&.filter { |nic| nic.network }&.first)That gives a better chance of finding a network that actually has an ip address.
|
Good call, that's the better fix. Switched to selecting the first nic that has a network in if (nic = self.nics&.find { |n| n.network })Used |
|
Since you took the effort to write commit messages I don't want to squash for you. Would you mind squashing your commits? |
When a VM has a bridge or macvtap interface (e.g. a Vagrant public_network with :dev), libvirt represents it without a source network, so the nic's network name is nil. #addresses took nics.first unconditionally and passed that nil into lookup_network_by_name(nil), raising "TypeError: no implicit conversion of nil into String" and crashing vagrant-libvirt state checks. Select the first nic that actually has a network instead. Bridge/direct interfaces have no network name and never carry a libvirt-managed lease, so skipping them avoids the nil lookup and gives multi-nic VMs a better chance of resolving a real address. As defense in depth, get_network_by_filter returns nil early for a nil name filter and list_networks compacts the result, so lookup_network_by_name(nil) can't raise from any other caller. Add minitest coverage for the bridge-only (no address, no raise) and mixed-nic (resolves the networked nic) cases.
f51f3f1 to
9a9a9c9
Compare
|
Squashed, thanks for checking! |
Problem
When a VM has a bridge or macvtap interface (e.g. from a Vagrant
public_networkwith:dev), libvirt represents it without a source network attribute, so the nic's network name isnil.addresses()tooknics.firstunconditionally and passed thatnilname down tolookup_network_by_name(nil), raising:This crashed
vagrant-libvirtstate checks on any VM with a bridge NIC.Fix
Primary fix is in
addresses(): select the first nic that actually has a network instead of blindly taking the first nic. Bridge/direct interfaces have no network name and never carry a libvirt-managed lease, so skipping them both avoids the nil lookup and gives multi-nic VMs a better chance of resolving a real address.As defense in depth,
get_network_by_filterstill returnsnilearly when the name filter isnil, andlist_networkscompacts the result soFog::Collection#loadnever receives a nil entry. This keepslookup_network_by_name(nil)from raising for any other caller. Happy to drop this layer if you'd rather keep the surface minimal.Tests
Added minitest coverage for
addresses():Fixes
vagrant-libvirtstate checks crashing on VMs with bridge NICs.