Merge pull request #10092 from jmaness/patch-1

[#10098] Filter out empty strings and loopback interfaces when constructing the list of network interfaces
This commit is contained in:
Brian Cain 2018-08-31 10:03:49 -07:00 committed by GitHub
commit 11c619bff6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 2 deletions

View File

@ -19,6 +19,7 @@ module VagrantPlugins
machine.communicate.sudo("#{path} -o -0 addr | grep -v LOOPBACK | awk '{print $2}' | sed 's/://'") do |type, data| machine.communicate.sudo("#{path} -o -0 addr | grep -v LOOPBACK | awk '{print $2}' | sed 's/://'") do |type, data|
s << data if type == :stdout s << data if type == :stdout
end end
# In some cases net devices may be added to the guest and will not # In some cases net devices may be added to the guest and will not
# properly show up when using `ip`. This pulls any device information # properly show up when using `ip`. This pulls any device information
# that can be found in /proc and adds it to the list of interfaces # that can be found in /proc and adds it to the list of interfaces
@ -26,7 +27,17 @@ module VagrantPlugins
machine.communicate.sudo("cat /proc/net/dev | grep -E '^[a-z0-9 ]+:' | awk '{print $1}' | sed 's/://'", error_check: false) do |type, data| machine.communicate.sudo("cat /proc/net/dev | grep -E '^[a-z0-9 ]+:' | awk '{print $1}' | sed 's/://'", error_check: false) do |type, data|
s << data if type == :stdout s << data if type == :stdout
end end
ifaces = s.split("\n")
# Collect all loopback interfaces
los = ""
machine.communicate.sudo("#{path} -o -0 addr | grep LOOPBACK | awk '{print $2}' | sed 's/://'") do |type, data|
los << data if type == :stdout
end
loifaces = los.split("\n")
@@logger.debug("loopback interfaces: #{loifaces.inspect}")
ifaces = s.split("\n").reject { |x| x.empty? or loifaces.include?(x) }
@@logger.debug("Unsorted list: #{ifaces.inspect}") @@logger.debug("Unsorted list: #{ifaces.inspect}")
# Break out integers from strings and sort the arrays to provide # Break out integers from strings and sort the arrays to provide
# a natural sort for the interface names # a natural sort for the interface names
@ -34,7 +45,7 @@ module VagrantPlugins
# as expected. This is generally seen with veth* devices, and proper ordering # as expected. This is generally seen with veth* devices, and proper ordering
# is currently not required # is currently not required
ifaces = ifaces.map do |iface| ifaces = ifaces.map do |iface|
iface.scan(/(.+?)(\d+)/).flatten.map do |iface_part| iface.scan(/(.+?)(\d+)?/).flatten.map do |iface_part|
if iface_part.to_i.to_s == iface_part if iface_part.to_i.to_s == iface_part
iface_part.to_i iface_part.to_i
else else

View File

@ -23,60 +23,84 @@ describe "VagrantPlugins::GuestLinux::Cap::NetworkInterfaces" do
it "sorts discovered classic interfaces" do it "sorts discovered classic interfaces" do
expect(comm).to receive(:sudo).twice.and_yield(:stdout, "eth1\neth2\neth0") expect(comm).to receive(:sudo).twice.and_yield(:stdout, "eth1\neth2\neth0")
expect(comm).to receive(:sudo).and_yield(:stdout, "lo")
result = cap.network_interfaces(machine) result = cap.network_interfaces(machine)
expect(result).to eq(["eth0", "eth1", "eth2"]) expect(result).to eq(["eth0", "eth1", "eth2"])
end end
it "sorts discovered classic interfaces and handles trailing newline" do
expect(comm).to receive(:sudo).twice.and_yield(:stdout, "eth1\neth2\neth0\n")
expect(comm).to receive(:sudo).and_yield(:stdout, "lo")
result = cap.network_interfaces(machine)
expect(result).to eq(["eth0", "eth1", "eth2"])
end
it "filters out lo interface" do
expect(comm).to receive(:sudo).twice.and_yield(:stdout, "lo\neth0")
expect(comm).to receive(:sudo).and_yield(:stdout, "lo")
result = cap.network_interfaces(machine)
expect(result).to eq(["eth0"])
end
it "sorts discovered predictable network interfaces" do it "sorts discovered predictable network interfaces" do
expect(comm).to receive(:sudo).twice.and_yield(:stdout, "enp0s8\nenp0s3\nenp0s5") expect(comm).to receive(:sudo).twice.and_yield(:stdout, "enp0s8\nenp0s3\nenp0s5")
expect(comm).to receive(:sudo).and_yield(:stdout, "lo")
result = cap.network_interfaces(machine) result = cap.network_interfaces(machine)
expect(result).to eq(["enp0s3", "enp0s5", "enp0s8"]) expect(result).to eq(["enp0s3", "enp0s5", "enp0s8"])
end end
it "sorts discovered classic interfaces naturally" do it "sorts discovered classic interfaces naturally" do
expect(comm).to receive(:sudo).twice.and_yield(:stdout, "eth1\neth2\neth12\neth0\neth10") expect(comm).to receive(:sudo).twice.and_yield(:stdout, "eth1\neth2\neth12\neth0\neth10")
expect(comm).to receive(:sudo).and_yield(:stdout, "lo")
result = cap.network_interfaces(machine) result = cap.network_interfaces(machine)
expect(result).to eq(["eth0", "eth1", "eth2", "eth10", "eth12"]) expect(result).to eq(["eth0", "eth1", "eth2", "eth10", "eth12"])
end end
it "sorts discovered predictable network interfaces naturally" do it "sorts discovered predictable network interfaces naturally" do
expect(comm).to receive(:sudo).twice.and_yield(:stdout, "enp0s8\nenp0s3\nenp0s5\nenp0s10\nenp1s3") expect(comm).to receive(:sudo).twice.and_yield(:stdout, "enp0s8\nenp0s3\nenp0s5\nenp0s10\nenp1s3")
expect(comm).to receive(:sudo).and_yield(:stdout, "lo")
result = cap.network_interfaces(machine) result = cap.network_interfaces(machine)
expect(result).to eq(["enp0s3", "enp0s5", "enp0s8", "enp0s10", "enp1s3"]) expect(result).to eq(["enp0s3", "enp0s5", "enp0s8", "enp0s10", "enp1s3"])
end end
it "sorts ethernet devices discovered with classic naming first in list" do it "sorts ethernet devices discovered with classic naming first in list" do
expect(comm).to receive(:sudo).twice.and_yield(:stdout, "eth1\neth2\ndocker0\nbridge0\neth0") expect(comm).to receive(:sudo).twice.and_yield(:stdout, "eth1\neth2\ndocker0\nbridge0\neth0")
expect(comm).to receive(:sudo).and_yield(:stdout, "lo")
result = cap.network_interfaces(machine) result = cap.network_interfaces(machine)
expect(result).to eq(["eth0", "eth1", "eth2", "bridge0", "docker0"]) expect(result).to eq(["eth0", "eth1", "eth2", "bridge0", "docker0"])
end end
it "sorts ethernet devices discovered with predictable network interfaces naming first in list" do it "sorts ethernet devices discovered with predictable network interfaces naming first in list" do
expect(comm).to receive(:sudo).twice.and_yield(:stdout, "enp0s8\ndocker0\nenp0s3\nbridge0\nenp0s5") expect(comm).to receive(:sudo).twice.and_yield(:stdout, "enp0s8\ndocker0\nenp0s3\nbridge0\nenp0s5")
expect(comm).to receive(:sudo).and_yield(:stdout, "lo")
result = cap.network_interfaces(machine) result = cap.network_interfaces(machine)
expect(result).to eq(["enp0s3", "enp0s5", "enp0s8", "bridge0", "docker0"]) expect(result).to eq(["enp0s3", "enp0s5", "enp0s8", "bridge0", "docker0"])
end end
it "sorts ethernet devices discovered with predictable network interfaces naming first in list with less" do it "sorts ethernet devices discovered with predictable network interfaces naming first in list with less" do
expect(comm).to receive(:sudo).twice.and_yield(:stdout, "enp0s3\nenp0s8\ndocker0") expect(comm).to receive(:sudo).twice.and_yield(:stdout, "enp0s3\nenp0s8\ndocker0")
expect(comm).to receive(:sudo).and_yield(:stdout, "lo")
result = cap.network_interfaces(machine) result = cap.network_interfaces(machine)
expect(result).to eq(["enp0s3", "enp0s8", "docker0"]) expect(result).to eq(["enp0s3", "enp0s8", "docker0"])
end end
it "does not include ethernet devices aliases within prefix device listing" do it "does not include ethernet devices aliases within prefix device listing" do
expect(comm).to receive(:sudo).twice.and_yield(:stdout, "eth1\neth2\ndocker0\nbridge0\neth0\ndocker1\neth0:0") expect(comm).to receive(:sudo).twice.and_yield(:stdout, "eth1\neth2\ndocker0\nbridge0\neth0\ndocker1\neth0:0")
expect(comm).to receive(:sudo).and_yield(:stdout, "lo")
result = cap.network_interfaces(machine) result = cap.network_interfaces(machine)
expect(result).to eq(["eth0", "eth1", "eth2", "bridge0", "docker0", "docker1", "eth0:0"]) expect(result).to eq(["eth0", "eth1", "eth2", "bridge0", "docker0", "docker1", "eth0:0"])
end end
it "does not include ethernet devices aliases within prefix device listing with dot separators" do it "does not include ethernet devices aliases within prefix device listing with dot separators" do
expect(comm).to receive(:sudo).twice.and_yield(:stdout, "eth1\neth2\ndocker0\nbridge0\neth0\ndocker1\neth0.1@eth0") expect(comm).to receive(:sudo).twice.and_yield(:stdout, "eth1\neth2\ndocker0\nbridge0\neth0\ndocker1\neth0.1@eth0")
expect(comm).to receive(:sudo).and_yield(:stdout, "lo")
result = cap.network_interfaces(machine) result = cap.network_interfaces(machine)
expect(result).to eq(["eth0", "eth1", "eth2", "bridge0", "docker0", "docker1", "eth0.1@eth0"]) expect(result).to eq(["eth0", "eth1", "eth2", "bridge0", "docker0", "docker1", "eth0.1@eth0"])
end end
it "properly sorts non-consistent device name formats" do it "properly sorts non-consistent device name formats" do
expect(comm).to receive(:sudo).twice.and_yield(:stdout, "eth0\neth1\ndocker0\nveth437f7f9\nveth06b3e44\nveth8bb7081") expect(comm).to receive(:sudo).twice.and_yield(:stdout, "eth0\neth1\ndocker0\nveth437f7f9\nveth06b3e44\nveth8bb7081")
expect(comm).to receive(:sudo).and_yield(:stdout, "lo")
result = cap.network_interfaces(machine) result = cap.network_interfaces(machine)
expect(result).to eq(["eth0", "eth1", "docker0", "veth8bb7081", "veth437f7f9", "veth06b3e44"]) expect(result).to eq(["eth0", "eth1", "docker0", "veth8bb7081", "veth437f7f9", "veth06b3e44"])
end end