diff --git a/lib/vagrant/actions/vm/network.rb b/lib/vagrant/actions/vm/network.rb index 252998f59..484b56272 100644 --- a/lib/vagrant/actions/vm/network.rb +++ b/lib/vagrant/actions/vm/network.rb @@ -19,40 +19,46 @@ module Vagrant def assign_network logger.info "Enabling host only network..." - options = runner.env.config.vm.network_options - adapter = runner.vm.network_adapters[options[:adapter]] + network_options = runner.env.config.vm.network_options + adapter = runner.vm.network_adapters[network_options[:adapter]] adapter.enabled = true adapter.attachment_type = :host_only - adapter.host_interface = network_name(options) + adapter.host_interface = network_name(network_options) adapter.save end # Returns the name of the proper host only network, or creates # it if it does not exist. Vagrant determines if the host only # network exists by comparing the netmask and the IP. - def network_name(options) + def network_name(net_options) # First try to find a matching network interfaces = VirtualBox::Global.global.host.network_interfaces interfaces.each do |ni| - return ni.name if matching_network?(ni, options) + if net_options[:name] + return ni.name if net_options[:name] == ni.name + else + return ni.name if matching_network?(ni, net_options) + end end + raise ActionException.new(:network_not_found, :name => net_options[:name]) if net_options[:name] + # One doesn't exist, create it. logger.info "Creating new host only network for environment..." ni = interfaces.create - ni.enable_static(network_ip(options[:ip], options[:netmask]), - options[:netmask]) + ni.enable_static(network_ip(net_options[:ip], net_options[:netmask]), + net_options[:netmask]) ni.name end # Tests if a network matches the given options by applying the # netmask to the IP of the network and also to the IP of the # virtual machine and see if they match. - def matching_network?(interface, options) - interface.network_mask == options[:netmask] && + def matching_network?(interface, net_options) + interface.network_mask == net_options[:netmask] && apply_netmask(interface.ip_address, interface.network_mask) == - apply_netmask(options[:ip], options[:netmask]) + apply_netmask(net_options[:ip], net_options[:netmask]) end # Applies a netmask to an IP and returns the corresponding diff --git a/lib/vagrant/config.rb b/lib/vagrant/config.rb index 30702839d..df3a45e67 100644 --- a/lib/vagrant/config.rb +++ b/lib/vagrant/config.rb @@ -136,6 +136,7 @@ module Vagrant options = { :ip => ip, :netmask => "255.255.255.0", + :adapter => 1, :name => nil }.merge(options || {}) diff --git a/templates/strings.yml b/templates/strings.yml index b35629278..9bb3fdf89 100644 --- a/templates/strings.yml +++ b/templates/strings.yml @@ -111,6 +111,11 @@ already be created, but unfortunately this vagrant still appears to have no box! You can setup the environment by setting up your <%= Vagrant::Environment::ROOTFILE_NAME %> and running `vagrant up` +:network_not_found: |- + The specified host network could not be found: <%= name %>. + If the name specification is removed, Vagrant will create a new + host only network for you. Alternatively, please create the + specified network manually. :package_include_file_doesnt_exist: |- File specified to include: '<%= filename %>' does not exist! :package_multivm: |- diff --git a/test/vagrant/actions/vm/network_test.rb b/test/vagrant/actions/vm/network_test.rb index 2e3a5d622..0b1125fb8 100644 --- a/test/vagrant/actions/vm/network_test.rb +++ b/test/vagrant/actions/vm/network_test.rb @@ -70,7 +70,7 @@ class NetworkTest < Test::Unit::TestCase @action.stubs(:matching_network?).returns(false) - @options = { :ip => :foo, :netmask => :bar } + @options = { :ip => :foo, :netmask => :bar, :name => nil } end should "return the network which matches" do @@ -83,6 +83,26 @@ class NetworkTest < Test::Unit::TestCase assert_equal result, @action.network_name(@options) end + should "return the network which matches the name if given" do + @options[:name] = "foo" + + interface = mock("interface") + interface.stubs(:name).returns(@options[:name]) + @interfaces << interface + + assert_equal @options[:name], @action.network_name(@options) + end + + should "error and exit if the given network name is not found" do + @options[:name] = "foo" + + @interfaces.expects(:create).never + + assert_raises(Vagrant::Actions::ActionException) { + @action.network_name(@options) + } + end + should "create a network for the IP and netmask" do result = mock("result") interface = mock("interface") diff --git a/vagrant.gemspec b/vagrant.gemspec index 1c9b8bb7f..887ba4054 100644 --- a/vagrant.gemspec +++ b/vagrant.gemspec @@ -9,7 +9,7 @@ Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version= s.authors = ["Mitchell Hashimoto", "John Bender"] - s.date = %q{2010-05-30} + s.date = %q{2010-06-03} s.default_executable = %q{vagrant} s.description = %q{Vagrant is a tool for building and distributing virtualized development environments.} s.email = ["mitchell.hashimoto@gmail.com", "john.m.bender@gmail.com"] @@ -50,6 +50,7 @@ Gem::Specification.new do |s| "lib/vagrant/actions/vm/halt.rb", "lib/vagrant/actions/vm/import.rb", "lib/vagrant/actions/vm/move_hard_drive.rb", + "lib/vagrant/actions/vm/network.rb", "lib/vagrant/actions/vm/package.rb", "lib/vagrant/actions/vm/provision.rb", "lib/vagrant/actions/vm/reload.rb", @@ -128,6 +129,7 @@ Gem::Specification.new do |s| "test/vagrant/actions/vm/halt_test.rb", "test/vagrant/actions/vm/import_test.rb", "test/vagrant/actions/vm/move_hard_drive_test.rb", + "test/vagrant/actions/vm/network_test.rb", "test/vagrant/actions/vm/package_test.rb", "test/vagrant/actions/vm/provision_test.rb", "test/vagrant/actions/vm/reload_test.rb", @@ -218,6 +220,7 @@ Gem::Specification.new do |s| "test/vagrant/actions/vm/import_test.rb", "test/vagrant/actions/vm/customize_test.rb", "test/vagrant/actions/vm/start_test.rb", + "test/vagrant/actions/vm/network_test.rb", "test/vagrant/actions/vm/move_hard_drive_test.rb", "test/vagrant/actions/vm/up_test.rb", "test/vagrant/actions/vm/export_test.rb",