diff --git a/bin/vagrant b/bin/vagrant index 25125e38d..a86d6581e 100755 --- a/bin/vagrant +++ b/bin/vagrant @@ -22,12 +22,13 @@ else opts[:ui_class] = Vagrant::UI::Colored end -# Create the environment, which is the cwd of wherever the -# `vagrant` command was invoked from -logger.debug("Creating Vagrant environment") -env = Vagrant::Environment.new(opts) - +env = nil begin + # Create the environment, which is the cwd of wherever the + # `vagrant` command was invoked from + logger.debug("Creating Vagrant environment") + env = Vagrant::Environment.new(opts) + # Load the environment logger.debug("Loading environment") env.load! @@ -40,8 +41,14 @@ rescue Vagrant::Errors::VagrantError => e logger.error(e.message) logger.error(e.backtrace.join("\n")) - opts = { :prefix => false } - env.ui.error e.message, opts if e.message + if env + opts = { :prefix => false } + env.ui.error e.message, opts if e.message + else + $stderr.puts "Vagrant failed to initialize at a very early stage:\n\n" + $stderr.puts e.message + end + exit e.status_code if e.respond_to?(:status_code) exit 999 # An error occurred with no status code defined end diff --git a/lib/vagrant/environment.rb b/lib/vagrant/environment.rb index c9fe69a3a..fd7dfef6c 100644 --- a/lib/vagrant/environment.rb +++ b/lib/vagrant/environment.rb @@ -21,6 +21,10 @@ module Vagrant # The {UI} object to communicate with the outside world. attr_reader :ui + # The directory to the "home" folder that Vagrant will use to store + # global state. + attr_reader :home_path + #--------------------------------------------------------------- # Class Methods #--------------------------------------------------------------- @@ -80,6 +84,9 @@ module Vagrant @logger = Log4r::Logger.new("vagrant::environment") @logger.info("Environment initialized (#{self})") @logger.info(" - cwd: #{cwd}") + + # Setup the home directory + setup_home_path end #--------------------------------------------------------------- @@ -95,23 +102,6 @@ module Vagrant root_path.join(config.global.vagrant.dotfile_name) end - # The path to the home directory and converted into a Pathname object. - # - # @return [Pathname] - def home_path - return @_home_path if defined?(@_home_path) - - @_home_path ||= Pathname.new(File.expand_path(@home_path || - ENV["VAGRANT_HOME"] || - DEFAULT_HOME)) - @logger.info("Home path: #{@_home_path}") - - # Make sure the home directory is properly setup - load_home_directory! - - @_home_path - end - # The path to the Vagrant tmp directory # # @return [Pathname] @@ -446,22 +436,6 @@ module Vagrant @config = Config::Container.new(global, vm_configs) end - # Loads the home directory path and creates the necessary subdirectories - # within the home directory if they're not already created. - def load_home_directory! - # Setup the array of necessary home directories - dirs = [home_path] - dirs += HOME_SUBDIRS.collect { |subdir| home_path.join(subdir) } - - # Go through each required directory, creating it if it doesn't exist - dirs.each do |dir| - next if File.directory?(dir) - - @logger.info("Creating: #{dir}") - FileUtils.mkdir_p(dir) - end - end - # Loads the persisted VM (if it exists) for this environment. def load_vms! result = {} @@ -484,5 +458,33 @@ module Vagrant result end + + # This sets the `@home_path` variable properly. + # + # @return [Pathname] + def setup_home_path + @home_path = Pathname.new(File.expand_path(@home_path || + ENV["VAGRANT_HOME"] || + DEFAULT_HOME)) + @logger.info("Home path: #{@home_path}") + + if !@home_path.readable? || !@home_path.writable? + @logger.error("Home directory not accessible") + raise Errors::HomeDirectoryNotAccessible, :home_path => @home_path.to_s + end + + # Setup the array of necessary home directories + dirs = [@home_path] + dirs += HOME_SUBDIRS.collect { |subdir| @home_path.join(subdir) } + + # Go through each required directory, creating it if it doesn't exist + dirs.each do |dir| + next if File.directory?(dir) + + @logger.info("Creating: #{dir}") + FileUtils.mkdir_p(dir) + end + end + end end diff --git a/lib/vagrant/errors.rb b/lib/vagrant/errors.rb index 7b4f0e7cc..a29d9dbe6 100644 --- a/lib/vagrant/errors.rb +++ b/lib/vagrant/errors.rb @@ -163,6 +163,11 @@ module Vagrant error_key(:home_dir_migration_failed) end + class HomeDirectoryNotAccessible < VagrantError + status_code(55) + error_key(:home_dir_not_accessible) + end + class ForwardPortAutolistEmpty < VagrantError status_code(27) error_key(:auto_empty, "vagrant.actions.vm.forward_ports") diff --git a/templates/locales/en.yml b/templates/locales/en.yml index 7f5f6168d..3f5cabe39 100644 --- a/templates/locales/en.yml +++ b/templates/locales/en.yml @@ -43,6 +43,11 @@ en: may run at any given time to avoid problems with VirtualBox inconsistencies occurring. Please wait for the other instance of Vagrant to end and then try again. + home_dir_not_accessible: |- + The home directory you specified is not accessible. The home + directory that Vagrant uses must be both readable and writable. + + You specified: %{home_path} interrupted: "Vagrant exited after cleanup due to external interrupt." multi_vm_required: "A multi-vm environment is required for name specification to this command." multi_vm_target_required: "`vagrant %{command}` requires a specific VM name to target in a multi-VM environment." diff --git a/test/unit/vagrant/environment_test.rb b/test/unit/vagrant/environment_test.rb index 2dd2dc7a0..c4a6b2cff 100644 --- a/test/unit/vagrant/environment_test.rb +++ b/test/unit/vagrant/environment_test.rb @@ -36,6 +36,12 @@ describe Vagrant::Environment do expected = Pathname.new(File.expand_path(described_class::DEFAULT_HOME)) described_class.new.home_path.should == expected end + + it "throws an exception if inaccessible" do + expect { + described_class.new(:home_path => "/") + }.to raise_error(Vagrant::Errors::HomeDirectoryNotAccessible) + end end it "has a box collection pointed to the proper directory" do