def call(env)
begin
domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(
env[:machine].id.to_s
)
rescue => e
raise Errors::NoDomainError,
error_message: e.message
end
adapters = []
configured_networks(env, @logger).each do |options|
next if options[:iface_type] == :forwarded_port
if options[:adapter]
if adapters[options[:adapter]]
raise Errors::InterfaceSlotNotAvailable
end
free_slot = options[:adapter].to_i
@logger.debug "Using specified adapter slot #{free_slot}"
else
free_slot = find_empty(adapters)
@logger.debug "Adapter not specified so found slot #{free_slot}"
raise Errors::InterfaceSlotExhausted if free_slot.nil?
end
adapters[free_slot] = options
adapters[free_slot][:network_name] = interface_network(
env[:machine].provider.driver.connection.client, adapters[free_slot]
)
end
@macs_per_network = Hash.new(0)
adapters.each_with_index do |iface_configuration, slot_number|
@iface_number = slot_number
@network_name = iface_configuration[:network_name]
@source_options = {
network: @network_name
}
@mac = iface_configuration.fetch(:mac, false)
@model_type = iface_configuration.fetch(:model_type, @nic_model_type)
@driver_name = iface_configuration.fetch(:driver_name, false)
@driver_queues = iface_configuration.fetch(:driver_queues, false)
@device_name = iface_configuration.fetch(:iface_name, false)
@mtu = iface_configuration.fetch(:mtu, nil)
@pci_bus = iface_configuration.fetch(:bus, nil)
@pci_slot = iface_configuration.fetch(:slot, nil)
template_name = 'interface'
@type = nil
@udp_tunnel = nil
if iface_configuration[:iface_type] == :public_network
@device = iface_configuration.fetch(:dev, 'eth0')
@mode = iface_configuration.fetch(:mode, 'bridge')
@type = iface_configuration.fetch(:type, 'direct')
@model_type = iface_configuration.fetch(:model_type, @nic_model_type)
@driver_name = iface_configuration.fetch(:driver_name, false)
@driver_queues = iface_configuration.fetch(:driver_queues, false)
@portgroup = iface_configuration.fetch(:portgroup, nil)
@network_name = iface_configuration.fetch(:network_name, @network_name)
template_name = 'public_interface'
@logger.info("Setting up public interface using device #{@device} in mode #{@mode}")
@ovs = iface_configuration.fetch(:ovs, false)
@trust_guest_rx_filters = iface_configuration.fetch(:trust_guest_rx_filters, false)
elsif iface_configuration.fetch(:tunnel_type, nil)
@type = iface_configuration.fetch(:tunnel_type)
@tunnel_port = iface_configuration.fetch(:tunnel_port, nil)
raise Errors::TunnelPortNotDefined if @tunnel_port.nil?
if @type == 'udp'
@udp_tunnel={
address: iface_configuration.fetch(:tunnel_local_ip,'127.0.0.1'),
port: iface_configuration.fetch(:tunnel_local_port)
}
end
default_ip = if @type == 'mcast'
'239.255.1.1'
else
'127.0.0.1'
end
@source_options = {
address: iface_configuration.fetch(:tunnel_ip, default_ip),
port: @tunnel_port
}
@tunnel_type = iface_configuration.fetch(:model_type, @nic_model_type)
@driver_name = iface_configuration.fetch(:driver_name, false)
@driver_queues = iface_configuration.fetch(:driver_queues, false)
template_name = 'tunnel_interface'
@logger.info("Setting up #{@type} tunnel interface using #{@tunnel_ip} port #{@tunnel_port}")
end
message = "Creating network interface eth#{@iface_number}"
message << " connected to network #{@network_name}."
if @mac
@mac = @mac.scan(/(\h{2})/).join(':')
message << " Using MAC address: #{@mac}"
end
@logger.info(message)
begin
driver_options = {}
driver_options[:name] = @driver_name if @driver_name
driver_options[:queues] = @driver_queues if @driver_queues
@udp_tunnel ||= {}
xml = if template_name == 'interface' or
template_name == 'tunnel_interface'
interface_xml(@type,
@source_options,
@mac,
@device_name,
@iface_number,
@model_type,
@mtu,
driver_options,
@udp_tunnel,
@pci_bus,
@pci_slot)
else
to_xml(template_name)
end
domain.attach_device(xml)
rescue => e
raise Errors::AttachDeviceError,
error_message: e.message
end
if iface_configuration[:iface_type] == :public_network
xml = Nokogiri::XML(domain.xml_desc)
source = "@network='#{@network_name}'"
if @type == 'direct'
source = "@dev='#{@device}'"
elsif @portgroup.nil?
source = "@bridge='#{@device}'"
end
if not @mac
macs = xml.xpath("/domain/devices/interface[source[#{source}]]/mac/@address")
@mac = macs[@macs_per_network[source]]
iface_configuration[:mac] = @mac.to_s
end
@macs_per_network[source] += 1
end
end
@app.call(env)
if env[:machine].config.vm.box
networks_to_configure = []
adapters.each_with_index do |options, slot_number|
next if slot_number.zero?
next if options[:auto_config] === false
@logger.debug "Configuring interface slot_number #{slot_number} options #{options}"
network = {
interface: slot_number,
use_dhcp_assigned_default_route: options[:use_dhcp_assigned_default_route],
mac_address: options[:mac]
}
if options[:ip]
network = {
type: :static,
ip: options[:ip],
netmask: options[:netmask],
gateway: options[:gateway]
}.merge(network)
else
network[:type] = :dhcp
end
next if options.fetch(:tunnel_type, nil)
networks_to_configure << network
end
env[:ui].info I18n.t('vagrant.actions.vm.network.configuring')
env[:machine].guest.capability(
:configure_networks, networks_to_configure
)
end
end