From 49c4581a8ca3c8f9798ce5c6a44a0927307512f5 Mon Sep 17 00:00:00 2001
From: Dan Williams <dcbw@redhat.com>
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.
---
plugins/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 2f67099..323519c 100644
--- a/plugins/guests/fedora/cap/configure_networks.rb
+++ b/plugins/guests/fedora/cap/configure_networks.rb
@@ -16,6 +16,7 @@ def self.configure_networks(machine, networks)
virtual = false
interface_names = Array.new
+ interface_names_by_slot = Array.new
machine.communicate.sudo("/usr/sbin/biosdevname; echo $?") do |_, result|
virtual = true if ['4', '127'].include? result.chomp
end
@@ -25,7 +26,7 @@ def self.configure_networks(machine, networks)
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 @@ def self.configure_networks(machine, networks)
"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