vagrant-libvirt/vagrant-libvirt-match-interface-by-mac.patch

69 lines
2.8 KiB
Diff

From ee7afab369dc7e80128ff35a2ff11f6eab23d368 Mon Sep 17 00:00:00 2001
From: Dan Williams <dcbw@redhat.com>
Date: Tue, 30 Jun 2015 16:24:30 -0500
Subject: [PATCH] Read MAC address from libvirt and pass up to Vagrant
Configuring networks based solely on slot numbers doesn't work very
well, since there's no way to guarantee that the interface Vagrant
finds is the same one that vagrant-libvirt created at that index.
For example, Vagrant's Fedora configure_networks action does this:
machine.communicate.sudo("ls /sys/class/net | grep -v lo") do |_, result|
interface_names = result.split("\n")
end
interface_names = networks.map do |network|
"#{interface_names[network[:interface]]}"
end
which means that if your image has 'docker' pre-installed, then
interface_names[0] = "docker0" and hilarity ensues, with the first
non-management network being assigned to the vagrant-libvirt
management interface.
Since interface names are very unreliable (they can be renamed by
udev at will or when hardware changes) the only way to ensure that
the interface vagrant-libvirt attaches to the domain maps to the
correct one inside the VM is by MAC address. Pull the MAC address
out of the libvirt config once the interface has been attached and
pass that up to Vagrant so we have a chance of doing the right thing.
---
lib/vagrant-libvirt/action/create_network_interfaces.rb | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/lib/vagrant-libvirt/action/create_network_interfaces.rb b/lib/vagrant-libvirt/action/create_network_interfaces.rb
index 35886ad..cbe7562 100644
--- a/lib/vagrant-libvirt/action/create_network_interfaces.rb
+++ b/lib/vagrant-libvirt/action/create_network_interfaces.rb
@@ -96,6 +96,21 @@ def call(env)
raise Errors::AttachDeviceError,
:error_message => e.message
end
+
+ # Re-read the network configuration and grab the MAC address
+ if !@mac
+ xml = Nokogiri::XML(domain.xml_desc)
+ if iface_configuration[:iface_type] == :public_network
+ if @type == 'direct'
+ @mac = xml.xpath("/domain/devices/interface[source[@dev='#{@device}']]/mac/@address")
+ else
+ @mac = xml.xpath("/domain/devices/interface[source[@bridge='#{@device}']]/mac/@address")
+ end
+ else
+ @mac = xml.xpath("/domain/devices/interface[source[@network='#{@network_name}']]/mac/@address")
+ end
+ iface_configuration[:mac] = @mac.to_s
+ end
end
# Continue the middleware chain.
@@ -116,7 +131,7 @@ def call(env)
network = {
:interface => slot_number,
- #:mac => ...,
+ :mac_address => options[:mac],
}
if options[:ip]