Fix network device creation logic.

Network device creation logic did not properly handle forwarded_ports;
instead it created connections to the management network for each one.
We depended on this in order to have at least one connection to the
management network. This commit explicitly handles the management
network and ignores forwarded ports.
This commit is contained in:
Brian Pitts 2014-01-30 11:44:24 -06:00
parent 8fefca0f64
commit 8a8ec7bcdb
5 changed files with 130 additions and 135 deletions

View File

@ -10,7 +10,7 @@ module VagrantPlugins
# Networks for connecting those interfaces should be already prepared.
class CreateNetworkInterfaces
include VagrantPlugins::ProviderLibvirt::Util::ErbTemplate
include VagrantPlugins::ProviderLibvirt::Util::LibvirtUtil
include VagrantPlugins::ProviderLibvirt::Util::NetworkUtil
include Vagrant::Util::NetworkIP
include Vagrant::Util::ScopedHashOverride
@ -36,14 +36,10 @@ module VagrantPlugins
# Vagrant gives you adapter 0 by default
# Assign interfaces to slots.
env[:machine].config.vm.networks.each do |type, options|
@logger.debug "In config found network type #{type} options #{options}"
configured_networks(env, @logger).each do |options|
# Get options for this interface. Options can be specified in
# Vagrantfile in short format (:ip => ...), or provider format
# (:libvirt__network_name => ...).
options = scoped_hash_override(options, :libvirt)
options = { :netmask => '255.255.255.0', :iface_type => type }.merge(options)
# dont need to create interface for this type
next if options[:iface_type] == :forwarded_port
# TODO fill first ifaces with adapter option specified.
if options[:adapter]
@ -103,9 +99,9 @@ module VagrantPlugins
networks_to_configure = []
adapters.each_with_index do |options, slot_number|
# Skip configuring first interface. It's used for provisioning and
# it has to be available during provisioning - ifdown command is
# not acceptable here.
# Skip configuring the management network, which is on the first interface.
# It's used for provisioning and it has to be available during provisioning,
# ifdown command is not acceptable here.
next if slot_number == 0
@logger.debug "Configuring interface slot_number #{slot_number} options #{options}"
@ -161,13 +157,7 @@ module VagrantPlugins
end
end
# the management network always gets attached to slot 0
# because the first network is of type forwarded_port.
# this is confusing.
# TODO only iterate over networks of type private_network
# and prepend the management network to that list
@logger.debug "Did not find network so using default of #{@management_network_name}"
@management_network_name
raise NetworkNotAvailableError, network_name: options[:ip]
end
end
end

View File

@ -12,7 +12,7 @@ module VagrantPlugins
include Vagrant::Util::NetworkIP
include Vagrant::Util::ScopedHashOverride
include VagrantPlugins::ProviderLibvirt::Util::ErbTemplate
include VagrantPlugins::ProviderLibvirt::Util::LibvirtUtil
include VagrantPlugins::ProviderLibvirt::Util::NetworkUtil
@@lock = Mutex.new
@ -27,63 +27,15 @@ module VagrantPlugins
end
def call(env)
management_network_name = env[:machine].provider_config.management_network_name
management_network_address = env[:machine].provider_config.management_network_address
@logger.info "Using #{management_network_name} at #{management_network_address} as the management network"
begin
management_network_ip = IPAddr.new(management_network_address)
rescue ArgumentError
raise Errors::ManagementNetworkError,
error_message: "#{management_network_address} is not a valid IP address"
end
# capture address into $1 and mask into $2
management_network_ip.inspect =~ /IPv4:(.*)\/(.*)>/
if $2 == '255.255.255.255'
raise Errors::ManagementNetworkError,
error_message: "#{management_network_address} does not include both an address and subnet mask"
end
management_network_options = {
network_name: management_network_name,
ip: $1,
netmask: $2,
dhcp_enabled: true,
forward_mode: 'nat',
}
# add management network to list of networks to check
networks = [ management_network_options ]
env[:machine].config.vm.networks.each do |type, original_options|
# There are two other types public network and port forwarding,
# but there are problems with creating them via libvirt API,
# so this provider doesn't implement them.
next if type != :private_network
# Options can be specified in Vagrantfile in short format (:ip => ...),
# or provider format # (:libvirt__network_name => ...).
# https://github.com/mitchellh/vagrant/blob/master/lib/vagrant/util/scoped_hash_override.rb
options = scoped_hash_override(original_options, :libvirt)
# use default values if not already set
options = {
netmask: '255.255.255.0',
dhcp_enabled: true,
forward_mode: 'nat',
}.merge(options)
# add to list of networks to check
networks.push(options)
end
# only one vm at a time should try to set up networks
# otherwise they'll have inconsitent views of current state
# and conduct redundant operations that cause errors
@@lock.synchronize do
# Iterate over networks If some network is not
# available, create it if possible. Otherwise raise an error.
networks.each do |options|
configured_networks(env, @logger).each do |options|
# Only need to create private networks
next if options[:iface_type] != :private_network
@logger.debug "Searching for network with options #{options}"
# should fix other methods so this doesn't have to be instance var

View File

@ -4,7 +4,7 @@ module VagrantPlugins
autoload :ErbTemplate, 'vagrant-libvirt/util/erb_template'
autoload :Collection, 'vagrant-libvirt/util/collection'
autoload :Timer, 'vagrant-libvirt/util/timer'
autoload :LibvirtUtil, 'vagrant-libvirt/util/libvirt_util'
autoload :NetworkUtil, 'vagrant-libvirt/util/network_util'
end
end
end

View File

@ -1,64 +0,0 @@
require 'nokogiri'
require 'vagrant/util/network_ip'
module VagrantPlugins
module ProviderLibvirt
module Util
module LibvirtUtil
include Vagrant::Util::NetworkIP
# Return a list of all (active and inactive) libvirt networks as a list
# of hashes with their name, network address and status (active or not)
def libvirt_networks(libvirt_client)
libvirt_networks = []
active = libvirt_client.list_networks
inactive = libvirt_client.list_defined_networks
# Iterate over all (active and inactive) networks.
active.concat(inactive).each do |network_name|
libvirt_network = libvirt_client.lookup_network_by_name(
network_name)
# Parse ip address and netmask from the network xml description.
xml = Nokogiri::XML(libvirt_network.xml_desc)
ip = xml.xpath('/network/ip/@address').first
ip = ip.value if ip
netmask = xml.xpath('/network/ip/@netmask').first
netmask = netmask.value if netmask
if xml.at_xpath('//network/ip/dhcp')
dhcp_enabled = true
else
dhcp_enabled = false
end
# Calculate network address of network from ip address and
# netmask.
if ip && netmask
network_address = network_address(ip, netmask)
else
network_address = nil
end
libvirt_networks << {
name: network_name,
ip_address: ip,
netmask: netmask,
network_address: network_address,
dhcp_enabled: dhcp_enabled,
bridge_name: libvirt_network.bridge_name,
created: true,
active: libvirt_network.active?,
autostart: libvirt_network.autostart?,
libvirt_network: libvirt_network
}
end
libvirt_networks
end
end
end
end
end

View File

@ -0,0 +1,117 @@
require 'nokogiri'
require 'vagrant/util/network_ip'
module VagrantPlugins
module ProviderLibvirt
module Util
module NetworkUtil
include Vagrant::Util::NetworkIP
def configured_networks(env, logger)
management_network_name = env[:machine].provider_config.management_network_name
management_network_address = env[:machine].provider_config.management_network_address
logger.info "Using #{management_network_name} at #{management_network_address} as the management network"
begin
management_network_ip = IPAddr.new(management_network_address)
rescue ArgumentError
raise Errors::ManagementNetworkError,
error_message: "#{management_network_address} is not a valid IP address"
end
# capture address into $1 and mask into $2
management_network_ip.inspect =~ /IPv4:(.*)\/(.*)>/
if $2 == '255.255.255.255'
raise Errors::ManagementNetworkError,
error_message: "#{management_network_address} does not include both an address and subnet mask"
end
management_network_options = {
iface_type: :private_network,
network_name: management_network_name,
ip: $1,
netmask: $2,
dhcp_enabled: true,
forward_mode: 'nat',
}
# add management network to list of networks to check
networks = [ management_network_options ]
env[:machine].config.vm.networks.each do |type, original_options|
logger.debug "In config found network type #{type} options #{original_options}"
# Options can be specified in Vagrantfile in short format (:ip => ...),
# or provider format # (:libvirt__network_name => ...).
# https://github.com/mitchellh/vagrant/blob/master/lib/vagrant/util/scoped_hash_override.rb
options = scoped_hash_override(original_options, :libvirt)
# store type in options
# use default values if not already set
options = {
iface_type: type,
netmask: '255.255.255.0',
dhcp_enabled: true,
forward_mode: 'nat',
}.merge(options)
# add to list of networks to check
networks.push(options)
end
return networks
end
# Return a list of all (active and inactive) libvirt networks as a list
# of hashes with their name, network address and status (active or not)
def libvirt_networks(libvirt_client)
libvirt_networks = []
active = libvirt_client.list_networks
inactive = libvirt_client.list_defined_networks
# Iterate over all (active and inactive) networks.
active.concat(inactive).each do |network_name|
libvirt_network = libvirt_client.lookup_network_by_name(
network_name)
# Parse ip address and netmask from the network xml description.
xml = Nokogiri::XML(libvirt_network.xml_desc)
ip = xml.xpath('/network/ip/@address').first
ip = ip.value if ip
netmask = xml.xpath('/network/ip/@netmask').first
netmask = netmask.value if netmask
if xml.at_xpath('//network/ip/dhcp')
dhcp_enabled = true
else
dhcp_enabled = false
end
# Calculate network address of network from ip address and
# netmask.
if ip && netmask
network_address = network_address(ip, netmask)
else
network_address = nil
end
libvirt_networks << {
name: network_name,
ip_address: ip,
netmask: netmask,
network_address: network_address,
dhcp_enabled: dhcp_enabled,
bridge_name: libvirt_network.bridge_name,
created: true,
active: libvirt_network.active?,
autostart: libvirt_network.autostart?,
libvirt_network: libvirt_network
}
end
libvirt_networks
end
end
end
end
end