Use libvirt to query host physical devices (#1550)

Request the list of physical devices from libvirt when performing
config validation. This ensures remote instances using bridges will get
the correct list of devices as well as be alerted when the device needed
does not exist.

Fixes issue introduced with #1499
This commit is contained in:
Darragh Bailey
2022-08-17 15:14:25 +01:00
committed by GitHub
parent 06fd99fcef
commit 591e151b13
2 changed files with 10 additions and 9 deletions

View File

@@ -1067,8 +1067,9 @@ module VagrantPlugins
# only interested in public networks where portgroup is nil, as then source will be a host device
if type == :public_network && opts[:portgroup] == nil
if !host_devices.include?(opts[:dev])
errors << "network configuration #{index} for machine #{machine.name} is a public_network referencing host device '#{opts[:dev]}' which does not exist, consider adding ':dev => ....' referencing one of #{host_devices.join(", ")}"
devices = host_devices(machine)
if !devices.include?(opts[:dev])
errors << "network configuration #{index} for machine #{machine.name} is a public_network referencing host device '#{opts[:dev]}' which does not exist, consider adding ':dev => ....' referencing one of #{devices.join(", ")}"
end
end
end
@@ -1210,11 +1211,9 @@ module VagrantPlugins
end
end
def host_devices
def host_devices(machine)
@host_devices ||= begin
require 'socket'
Socket.getifaddrs.map { |iface| iface.name }.uniq.select do |dev|
machine.provider.driver.connection.client.list_all_interfaces().map { |iface| iface.name }.uniq.select do |dev|
dev != "lo" && !@host_device_exclude_prefixes.any? { |exclude| dev.start_with?(exclude) }
end
end

View File

@@ -635,13 +635,15 @@ describe VagrantPlugins::ProviderLibvirt::Config do
end
context 'with public_network defined' do
let(:libvirt_client) { instance_double(::Libvirt::Connect) }
let(:host_devices) { [
instance_double(Socket::Ifaddr),
instance_double(Socket::Ifaddr),
instance_double(Libvirt::Interface),
instance_double(Libvirt::Interface),
] }
before do
machine.config.vm.network :public_network, dev: 'eth0', ip: "192.168.2.157"
expect(Socket).to receive(:getifaddrs).and_return(host_devices)
expect(machine).to receive_message_chain('provider.driver.connection.client').and_return(libvirt_client)
expect(libvirt_client).to receive(:list_all_interfaces).and_return(host_devices)
expect(host_devices[0]).to receive(:name).and_return('eth0')
expect(host_devices[1]).to receive(:name).and_return('virbr0')
end