Create default network if needed. Relates to #102.

This commit

* renames the option default_network to default_network_name
* introduces the option default_network_address, since we need an
address in order to create a network
* handles creation of the default network similarly to other private
networks if needed
This commit is contained in:
Brian Pitts 2014-01-12 18:36:53 -06:00
parent 01d3f28d0d
commit de553d0ea7
6 changed files with 82 additions and 34 deletions

View File

@ -99,7 +99,8 @@ This provider exposes quite a few provider-specific configuration options:
* `password` - Password to access Libvirt.
* `id_ssh_key_file` - The id ssh key file name to access Libvirt (eg: id_dsa or id_rsa or ... in the user .ssh directory)
* `storage_pool_name` - Libvirt storage pool name, where box image and instance snapshots will be stored.
* `default_network` - Libvirt default network name. If not specified default network name is 'default'.
* `default_network_name` - Libvirt default network name. If not specified the default network name is 'default'.
* `default_network_address` - Libvirt default network address. Must include the address and subnet mask. If not specified the default is '192.168.122.0/24'.
### Domain Specific Options

View File

@ -16,7 +16,7 @@ module VagrantPlugins
def initialize(app, env)
@logger = Log4r::Logger.new('vagrant_libvirt::action::create_network_interfaces')
@default_network = env[:machine].provider_config.default_network;
@default_network_name = env[:machine].provider_config.default_network_name
@app = app
end
@ -159,9 +159,13 @@ module VagrantPlugins
end
end
# TODO Network default can be missing
@logger.debug "Did not find network so using default #{@default_network}"
return @default_network;
# the default 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 default network to that list
@logger.debug "Did not find network so using default of #{@default_network_name}"
return @default_network_name
end
end
end

View File

@ -25,32 +25,68 @@ module VagrantPlugins
def call(env)
# Iterate over networks requested from config. If some network is not
default_network_name = env[:machine].provider_config.default_network_name
default_network_address = env[:machine].provider_config.default_network_address
@logger.info "Using #{default_network_name} at #{default_network_address} as the default network"
begin
default_network_ip = IPAddr.new(default_network_address)
rescue ArgumentError
raise Errors::DefaultNetworkError,
error_message: "#{default_network_address} is not a valid IP address"
end
# capture address into $1 and mask into $2
default_network_ip.inspect =~ /IPv4:(.*)\/(.*)>/
if $2 == '255.255.255.255'
raise Errors::DefaultNetworkError,
error_message: "#{default_network_address} does not include both an address and subnet mask"
end
default_network_options = {
network_name: default_network_name,
ip: $1,
netmask: $2,
dhcp_enabled: true,
forward_mode: 'nat',
}
# add default network to list of networks to check
networks = [ default_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
# Iterate over networks If some network is not
# available, create it if possible. Otherwise raise an error.
env[:machine].config.vm.networks.each do |type, options|
@logger.debug "In config found network type #{type} options #{options}"
networks.each do |options|
@logger.debug "Searching for network with options #{options}"
# should fix other methods so this doesn't have to be instance var
@options = options
# Get a list of all (active and inactive) libvirt networks. This
# list is used throughout this class and should be easier to
# process than libvirt API calls.
@available_networks = libvirt_networks(env[:libvirt_compute].client)
# Now, we support private networks only. 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
# Get options for this interface network. 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',
dhcp_enabled: true,
forward_mode: 'nat',
}.merge(@options)
# Prepare a hash describing network for this specific interface.
@interface_network = {
name: nil,
@ -65,13 +101,11 @@ module VagrantPlugins
}
if @options[:ip]
@logger.debug "handle by ip"
handle_ip_option(env)
# in vagrant 1.2.3 and later it is not possible to take this branch
# bcasue cannot have name without ip
# because cannot have name without ip
# https://github.com/mitchellh/vagrant/commit/cf2f6da4dbcb4f57c9cdb3b94dcd0bba62c5f5fd
elsif @options[:network_name]
@logger.debug "handle by name"
handle_network_name_option
end

View File

@ -26,7 +26,8 @@ module VagrantPlugins
attr_accessor :storage_pool_name
# Libvirt default network
attr_accessor :default_network
attr_accessor :default_network_name
attr_accessor :default_network_address
# Domain specific settings used while creating new domain.
attr_accessor :memory
@ -44,7 +45,8 @@ module VagrantPlugins
@password = UNSET_VALUE
@id_ssh_key_file = UNSET_VALUE
@storage_pool_name = UNSET_VALUE
@default_network = UNSET_VALUE
@default_network_name = UNSET_VALUE
@default_network_address = UNSET_VALUE
# Domain specific settings.
@memory = UNSET_VALUE
@ -63,7 +65,8 @@ module VagrantPlugins
@password = nil if @password == UNSET_VALUE
@id_ssh_key_file = 'id_rsa' if @id_ssh_key_file == UNSET_VALUE
@storage_pool_name = 'default' if @storage_pool_name == UNSET_VALUE
@default_network = 'default' if @default_network == UNSET_VALUE
@default_network_name = 'default' if @default_network_name == UNSET_VALUE
@default_network_address = '192.168.122.0/24' if @default_network_address == UNSET_VALUE
# Domain specific settings.
@memory = 512 if @memory == UNSET_VALUE

View File

@ -68,10 +68,9 @@ module VagrantPlugins
error_key(:fog_create_server_error)
end
# Other exceptions
class InterfaceSlotNotAvailable < VagrantLibvirtError
error_key(:interface_slot_not_available)
# Network exceptions
class DefaultNetworkError < VagrantLibvirtError
error_key(:default_network_error)
end
class NetworkNameAndAddressMismatch < VagrantLibvirtError
@ -98,6 +97,11 @@ module VagrantPlugins
error_key(:activate_network_error)
end
# Other exceptions
class InterfaceSlotNotAvailable < VagrantLibvirtError
error_key(:interface_slot_not_available)
end
class RsyncError < VagrantLibvirtError
error_key(:rsync_error)
end

View File

@ -101,6 +101,8 @@ en:
Error while attaching new device to domain. %{error_message}
no_ip_address_error: |-
No IP address found.
default_network_error: |-
Error in specification of default network: %{error_message}.
network_name_and_address_mismatch: |-
Address %{ip_address} does not match with network name %{network_name}.
Please fix your configuration and run vagrant again.