From 49c4581a8ca3c8f9798ce5c6a44a0927307512f5 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 30 Jun 2015 16:43:36 -0500 Subject: [PATCH] [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. --- .../guests/fedora/cap/configure_networks.rb | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/plugins/guests/fedora/cap/configure_networks.rb b/plugins/guests/fedora/cap/configure_networks.rb index 2f67099cd..323519cac 100644 --- a/plugins/guests/fedora/cap/configure_networks.rb +++ b/plugins/guests/fedora/cap/configure_networks.rb @@ -16,6 +16,7 @@ module VagrantPlugins virtual = false interface_names = Array.new + interface_names_by_slot = Array.new machine.communicate.sudo("/usr/sbin/biosdevname; echo $?") do |_, result| virtual = true if result.chomp == '4' end @@ -25,7 +26,7 @@ module VagrantPlugins interface_names = result.split("\n") end - interface_names = networks.map do |network| + interface_names_by_slot = networks.map do |network| "#{interface_names[network[:interface]]}" end else @@ -44,18 +45,39 @@ module VagrantPlugins "eth#{network[:interface]}" end + interface_names_by_slot = interface_names.dup interface_name_pairs.each do |interface_name, previous_interface_name| if setting_interface_names.index(previous_interface_name) == nil - interface_names.delete(interface_name) + interface_names_by_slot.delete(interface_name) 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 # as what interfaces we're actually configuring since we use that later. interfaces = Set.new 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) network[:device] = interface