Basic :dhcp configuration works.

This commit is contained in:
Mitchell Hashimoto 2012-01-08 19:51:29 -08:00
parent 2efa076142
commit 4e426249ed
6 changed files with 92 additions and 16 deletions

View File

@ -155,7 +155,14 @@ module Vagrant
ip = args[0] ip = args[0]
options = args[1] || {} options = args[1] || {}
# Determine if we're dealing with a static IP or a DHCP-served IP.
type = ip == :dhcp ? :dhcp : :static
# Default IP is in the 20-bit private network block for DHCP based networks
ip = "172.28.128.1" if type == :dhcp
options = { options = {
:type => type,
:ip => ip, :ip => ip,
:netmask => "255.255.255.0", :netmask => "255.255.255.0",
:adapter => nil, :adapter => nil,
@ -167,6 +174,34 @@ module Vagrant
# bridged interfaces # bridged interfaces
verify_no_bridge_collision(options) verify_no_bridge_collision(options)
# Get the network address and IP parts which are used for many
# default calculations
netaddr = network_address(options[:ip], options[:netmask])
ip_parts = netaddr.split(".").map { |i| i.to_i }
# Calculate the adapter IP, which we assume is the IP ".1" at the
# end usually.
adapter_ip = ip_parts.dup
adapter_ip[3] += 1
options[:adapter_ip] ||= adapter_ip.join(".")
if type == :dhcp
# Calculate the DHCP server IP, which is the network address
# with the final octet + 2. So "172.28.0.0" turns into "172.28.0.2"
dhcp_ip = ip_parts.dup
dhcp_ip[3] += 2
options[:dhcp_ip] ||= dhcp_ip.join(".")
# Calculate the lower and upper bound for the DHCP server
dhcp_lower = ip_parts.dup
dhcp_lower[3] += 3
options[:dhcp_lower] ||= dhcp_lower.join(".")
dhcp_upper = ip_parts.dup
dhcp_upper[3] = 254
options[:dhcp_upper] ||= dhcp_upper.join(".")
end
# Return the hostonly network configuration # Return the hostonly network configuration
return options return options
end end
@ -191,6 +226,15 @@ module Vagrant
@logger.debug("Created network: #{interface[:name]}") @logger.debug("Created network: #{interface[:name]}")
end end
if config[:type] == :dhcp
# TODO: Check that there isn't another DHCP server on this network
# that is different.
# Configure the DHCP server for the network.
@logger.debug("Creating a DHCP server...")
@env[:vm].driver.create_dhcp_server(interface[:name], config)
end
return { return {
:adapter => config[:adapter], :adapter => config[:adapter],
:type => :hostonly, :type => :hostonly,
@ -201,7 +245,7 @@ module Vagrant
def hostonly_network_config(config) def hostonly_network_config(config)
return { return {
:type => :static, :type => config[:type],
:ip => config[:ip], :ip => config[:ip],
:netmask => config[:netmask] :netmask => config[:netmask]
} }
@ -210,18 +254,10 @@ module Vagrant
# Creates a new hostonly network that matches the network requested # Creates a new hostonly network that matches the network requested
# by the given host-only network configuration. # by the given host-only network configuration.
def create_hostonly_network(config) def create_hostonly_network(config)
# First we need to determine a good IP for the host machine
# of this interface. We choose to use the network address
# plus 1, which is usually what is expected.
netaddr = network_address(config[:ip], config[:netmask])
parts = netaddr.split(".").map { |i| i.to_i }
parts[3] += 1
ip = parts.join(".")
# Create the options that are going to be used to create our # Create the options that are going to be used to create our
# new network. # new network.
options = config.dup options = config.dup
options[:ip] = ip options[:ip] = options[:adapter_ip]
@env[:vm].driver.create_host_only_network(options) @env[:vm].driver.create_host_only_network(options)
end end

View File

@ -157,7 +157,9 @@ do before is certainly still possible with `VBoxManage` as well.
# providers other than VirtualBox will not be able to satisfy # providers other than VirtualBox will not be able to satisfy
# all types of networks. # all types of networks.
networks.each do |type, args| networks.each do |type, args|
if type == :hostonly if type == :hostonly && args[0] == :dhcp
# Valid. There is no real way this can be invalid at the moment.
elsif type == :hostonly
# Validate the host-only network # Validate the host-only network
ip = args[0] ip = args[0]
options = args[1] || {} options = args[1] || {}

View File

@ -72,6 +72,7 @@ module Vagrant
def_delegators :@driver, :clear_forwarded_ports, def_delegators :@driver, :clear_forwarded_ports,
:clear_shared_folders, :clear_shared_folders,
:create_dhcp_server,
:create_host_only_network, :create_host_only_network,
:delete, :delete,
:delete_unused_host_only_networks, :delete_unused_host_only_networks,

View File

@ -9,7 +9,7 @@ module Vagrant
def initialize(uuid) def initialize(uuid)
super() super()
@logger = Log4r::Logger.new("vagrant::driver::virtualbox_4_0") @logger = Log4r::Logger.new("vagrant::driver::virtualbox_4_1")
@uuid = uuid @uuid = uuid
end end
@ -30,6 +30,15 @@ module Vagrant
end end
end end
def create_dhcp_server(network, options)
execute("dhcpserver", "add", "--ifname", network,
"--ip", options[:dhcp_ip],
"--netmask", options[:netmask],
"--lowerip", options[:dhcp_lower],
"--upperip", options[:dhcp_upper],
"--enable")
end
def create_host_only_network(options) def create_host_only_network(options)
# Create the interface # Create the interface
execute("hostonlyif", "create") =~ /^Interface '(.+?)' was successfully created$/ execute("hostonlyif", "create") =~ /^Interface '(.+?)' was successfully created$/
@ -37,13 +46,13 @@ module Vagrant
# Configure it # Configure it
execute("hostonlyif", "ipconfig", name, execute("hostonlyif", "ipconfig", name,
"--ip", options[:ip], "--ip", options[:adapter_ip],
"--netmask", options[:netmask]) "--netmask", options[:netmask])
# Return the details # Return the details
return { return {
:name => name, :name => name,
:ip => options[:ip], :ip => options[:adapter_ip],
:netmask => options[:netmask] :netmask => options[:netmask]
} }
end end
@ -69,6 +78,12 @@ module Vagrant
end end
networks.each do |name| networks.each do |name|
# First try to remove any DHCP servers attached. We use `raw` because
# it is okay if this fails. It usually means that a DHCP server was
# never attached.
raw("dhcpserver", "remove", "--ifname", name)
# Delete the actual host only network interface.
execute("hostonlyif", "remove", name) execute("hostonlyif", "remove", name)
end end
end end

View File

@ -30,6 +30,15 @@ module Vagrant
end end
end end
def create_dhcp_server(network, options)
execute("dhcpserver", "add", "--ifname", network,
"--ip", options[:dhcp_ip],
"--netmask", options[:netmask],
"--lowerip", options[:dhcp_lower],
"--upperip", options[:dhcp_upper],
"--enable")
end
def create_host_only_network(options) def create_host_only_network(options)
# Create the interface # Create the interface
execute("hostonlyif", "create") =~ /^Interface '(.+?)' was successfully created$/ execute("hostonlyif", "create") =~ /^Interface '(.+?)' was successfully created$/
@ -37,13 +46,13 @@ module Vagrant
# Configure it # Configure it
execute("hostonlyif", "ipconfig", name, execute("hostonlyif", "ipconfig", name,
"--ip", options[:ip], "--ip", options[:adapter_ip],
"--netmask", options[:netmask]) "--netmask", options[:netmask])
# Return the details # Return the details
return { return {
:name => name, :name => name,
:ip => options[:ip], :ip => options[:adapter_ip],
:netmask => options[:netmask] :netmask => options[:netmask]
} }
end end
@ -69,6 +78,12 @@ module Vagrant
end end
networks.each do |name| networks.each do |name|
# First try to remove any DHCP servers attached. We use `raw` because
# it is okay if this fails. It usually means that a DHCP server was
# never attached.
raw("dhcpserver", "remove", "--ifname", name)
# Delete the actual host only network interface.
execute("hostonlyif", "remove", name) execute("hostonlyif", "remove", name)
end end
end end

View File

@ -47,6 +47,13 @@ module Vagrant
def clear_shared_folders def clear_shared_folders
end end
# Creates a DHCP server for a host only network.
#
# @param [String] network Name of the host-only network.
# @param [Hash] options Options for the DHCP server.
def create_dhcp_server(network, options)
end
# Creates a host only network with the given options. # Creates a host only network with the given options.
# #
# @param [Hash] options Options to create the host only network. # @param [Hash] options Options to create the host only network.