diff --git a/lib/vagrant/action/vm/network.rb b/lib/vagrant/action/vm/network.rb index 9abf4c727..67d67c377 100644 --- a/lib/vagrant/action/vm/network.rb +++ b/lib/vagrant/action/vm/network.rb @@ -227,12 +227,21 @@ module Vagrant end if config[:type] == :dhcp - # TODO: Check that there isn't another DHCP server on this network - # that is different. + # Check that if there is a DHCP server attached on our interface, + # then it is identical. Otherwise, we can't set it. + if interface[:dhcp] + valid = interface[:dhcp][:ip] == config[:dhcp_ip] && + interface[:dhcp][:lower] == config[:dhcp_lower] && + interface[:dhcp][:upper] == config[:dhcp_upper] - # Configure the DHCP server for the network. - @logger.debug("Creating a DHCP server...") - @env[:vm].driver.create_dhcp_server(interface[:name], config) + raise Errors::NetworkDHCPAlreadyAttached if !valid + + @logger.debug("DHCP server already properly configured") + else + # Configure the DHCP server for the network. + @logger.debug("Creating a DHCP server...") + @env[:vm].driver.create_dhcp_server(interface[:name], config) + end end return { diff --git a/lib/vagrant/driver/virtualbox_4_0.rb b/lib/vagrant/driver/virtualbox_4_0.rb index c7060dd86..b419aca3a 100644 --- a/lib/vagrant/driver/virtualbox_4_0.rb +++ b/lib/vagrant/driver/virtualbox_4_0.rb @@ -53,7 +53,8 @@ module Vagrant return { :name => name, :ip => options[:adapter_ip], - :netmask => options[:netmask] + :netmask => options[:netmask], + :dhcp => nil } end @@ -235,6 +236,26 @@ module Vagrant end def read_host_only_interfaces + dhcp = {} + execute("list", "dhcpservers").split("\n\n").each do |block| + info = {} + + block.split("\n").each do |line| + if line =~ /^NetworkName:\s+HostInterfaceNetworking-(.+?)$/ + info[:network] = $1.to_s + elsif line =~ /^IP:\s+(.+?)$/ + info[:ip] = $1.to_s + elsif line =~ /^lowerIPAddress:\s+(.+?)$/ + info[:lower] = $1.to_s + elsif line =~ /^upperIPAddress:\s+(.+?)$/ + info[:upper] = $1.to_s + end + end + + # Set the DHCP info + dhcp[info[:network]] = info + end + execute("list", "hostonlyifs").split("\n\n").collect do |block| info = {} @@ -248,6 +269,9 @@ module Vagrant end end + # Set the DHCP info if it exists + info[:dhcp] = dhcp[info[:name]] if dhcp[info[:name]] + info end end diff --git a/lib/vagrant/driver/virtualbox_4_1.rb b/lib/vagrant/driver/virtualbox_4_1.rb index 087667881..3b56f79d4 100644 --- a/lib/vagrant/driver/virtualbox_4_1.rb +++ b/lib/vagrant/driver/virtualbox_4_1.rb @@ -53,7 +53,8 @@ module Vagrant return { :name => name, :ip => options[:adapter_ip], - :netmask => options[:netmask] + :netmask => options[:netmask], + :dhcp => nil } end @@ -235,6 +236,26 @@ module Vagrant end def read_host_only_interfaces + dhcp = {} + execute("list", "dhcpservers").split("\n\n").each do |block| + info = {} + + block.split("\n").each do |line| + if line =~ /^NetworkName:\s+HostInterfaceNetworking-(.+?)$/ + info[:network] = $1.to_s + elsif line =~ /^IP:\s+(.+?)$/ + info[:ip] = $1.to_s + elsif line =~ /^lowerIPAddress:\s+(.+?)$/ + info[:lower] = $1.to_s + elsif line =~ /^upperIPAddress:\s+(.+?)$/ + info[:upper] = $1.to_s + end + end + + # Set the DHCP info + dhcp[info[:network]] = info + end + execute("list", "hostonlyifs").split("\n\n").collect do |block| info = {} @@ -248,6 +269,9 @@ module Vagrant end end + # Set the DHCP info if it exists + info[:dhcp] = dhcp[info[:name]] if dhcp[info[:name]] + info end end diff --git a/lib/vagrant/errors.rb b/lib/vagrant/errors.rb index 3043b01b0..116e3cb42 100644 --- a/lib/vagrant/errors.rb +++ b/lib/vagrant/errors.rb @@ -223,6 +223,11 @@ module Vagrant error_key(:no_adapters, "vagrant.actions.vm.network") end + class NetworkDHCPAlreadyAttached < VagrantError + status_code(68) + error_key(:dhcp_already_attached, "vagrant.actions.vm.network") + end + class NetworkNotFound < VagrantError status_code(30) error_key(:not_found, "vagrant.actions.vm.host_only_network") diff --git a/templates/locales/en.yml b/templates/locales/en.yml index 9131d8301..c9c9ccb15 100644 --- a/templates/locales/en.yml +++ b/templates/locales/en.yml @@ -422,6 +422,14 @@ en: overlap. configuring: |- Configuring and enabling network interfaces... + dhcp_already_attached: |- + A host only network interface you're attempting to configure via DHCP + already has a conflicting host only adapter with DHCP enabled. The + DHCP on this adapter is incompatible with the DHCP settings. Two + host only network interfaces are not allowed to overlap, and each + host only network interface can have only one DHCP server. Please + reconfigure your host only network or remove the virtual machine + using the other host only network. no_adapters: |- No available adapters on the virtual machine were found to accomodate for all configured networks. VirtualBox virtual machines have 8