[fedora] honor MAC address when configuring networks

Configuring by :interface doesn't work very well because Vagrant has
no idea about what interfaces are present in the VM, for example if
the image has 'docker' installed but not biosdevname, then
interface_names[0] = "docker0" which is usually not what you want
mapped to the first network from the Vagrantfile.

So if the plugins (like vagrant-libvirt) or the Vagrantfile has
given us a network with a MAC address, use that to find the interface
name for the network.  Otherwise use slot numbers as before.
This commit is contained in:
Dan Williams 2015-06-30 16:43:36 -05:00
parent 261ef836e0
commit 49c4581a8c
1 changed files with 25 additions and 3 deletions

View File

@ -16,6 +16,7 @@ module VagrantPlugins
virtual = false virtual = false
interface_names = Array.new interface_names = Array.new
interface_names_by_slot = Array.new
machine.communicate.sudo("/usr/sbin/biosdevname; echo $?") do |_, result| machine.communicate.sudo("/usr/sbin/biosdevname; echo $?") do |_, result|
virtual = true if result.chomp == '4' virtual = true if result.chomp == '4'
end end
@ -25,7 +26,7 @@ module VagrantPlugins
interface_names = result.split("\n") interface_names = result.split("\n")
end end
interface_names = networks.map do |network| interface_names_by_slot = networks.map do |network|
"#{interface_names[network[:interface]]}" "#{interface_names[network[:interface]]}"
end end
else else
@ -44,18 +45,39 @@ module VagrantPlugins
"eth#{network[:interface]}" "eth#{network[:interface]}"
end end
interface_names_by_slot = interface_names.dup
interface_name_pairs.each do |interface_name, previous_interface_name| interface_name_pairs.each do |interface_name, previous_interface_name|
if setting_interface_names.index(previous_interface_name) == nil if setting_interface_names.index(previous_interface_name) == nil
interface_names.delete(interface_name) interface_names_by_slot.delete(interface_name)
end end
end end
end end
# Read interface MAC addresses for later matching
mac_addresses = Array.new(interface_names.length)
interface_names.each_with_index do |ifname, index|
machine.communicate.sudo("cat /sys/class/net/#{ifname}/address") do |_, result|
mac_addresses[index] = result.strip
end
end
# Accumulate the configurations to add to the interfaces file as well # Accumulate the configurations to add to the interfaces file as well
# as what interfaces we're actually configuring since we use that later. # as what interfaces we're actually configuring since we use that later.
interfaces = Set.new interfaces = Set.new
networks.each do |network| networks.each do |network|
interface = interface_names[network[:interface]-1] interface = nil
if network[:mac_address]
found_idx = mac_addresses.find_index(network[:mac_address])
# Ignore network if requested MAC address could not be found
next if found_idx.nil?
interface = interface_names[found_idx]
else
ifname_by_slot = interface_names_by_slot[network[:interface]-1]
# Don't overwrite if interface was already matched via MAC address
next if interfaces.include?(ifname_by_slot)
interface = ifname_by_slot
end
interfaces.add(interface) interfaces.add(interface)
network[:device] = interface network[:device] = interface