From 8aa4e58ea83547e2bc5330470e86258e6a6d652b Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 8 Jan 2012 20:28:47 -0800 Subject: [PATCH] Check for conflicting DHCP servers --- lib/vagrant/action/vm/network.rb | 21 +++++++++++++++------ lib/vagrant/driver/virtualbox_4_0.rb | 26 +++++++++++++++++++++++++- lib/vagrant/driver/virtualbox_4_1.rb | 26 +++++++++++++++++++++++++- lib/vagrant/errors.rb | 5 +++++ templates/locales/en.yml | 8 ++++++++ 5 files changed, 78 insertions(+), 8 deletions(-) diff --git a/lib/vagrant/action/vm/network.rb b/lib/vagrant/action/vm/network.rb index 9abf4c72754..67d67c37740 100644 --- a/lib/vagrant/action/vm/network.rb +++ b/lib/vagrant/action/vm/network.rb @@ -227,12 +227,21 @@ def hostonly_adapter(config) 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) + # 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] + + 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 c7060dd86b4..b419aca3a90 100644 --- a/lib/vagrant/driver/virtualbox_4_0.rb +++ b/lib/vagrant/driver/virtualbox_4_0.rb @@ -53,7 +53,8 @@ def create_host_only_network(options) return { :name => name, :ip => options[:adapter_ip], - :netmask => options[:netmask] + :netmask => options[:netmask], + :dhcp => nil } end @@ -235,6 +236,26 @@ def read_guest_additions_version 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 @@ def read_host_only_interfaces 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 087667881e1..3b56f79d4d4 100644 --- a/lib/vagrant/driver/virtualbox_4_1.rb +++ b/lib/vagrant/driver/virtualbox_4_1.rb @@ -53,7 +53,8 @@ def create_host_only_network(options) return { :name => name, :ip => options[:adapter_ip], - :netmask => options[:netmask] + :netmask => options[:netmask], + :dhcp => nil } end @@ -235,6 +236,26 @@ def read_guest_additions_version 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 @@ def read_host_only_interfaces 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 3043b01b066..116e3cb42b4 100644 --- a/lib/vagrant/errors.rb +++ b/lib/vagrant/errors.rb @@ -223,6 +223,11 @@ class NetworkNoAdapters < VagrantError 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 9131d830112..c9c9ccb1585 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