Local data path introduced

The local data path is set to the `ROOT_DIR/.vagrant` by default and is
a directory where Vagrant can store environment-local state. This can be
overriden on a per-Environment basis using the `local_data_path`
option.
This commit is contained in:
Mitchell Hashimoto 2012-12-26 20:36:46 -08:00
parent 5cb2f3275a
commit cc18492c7a
4 changed files with 84 additions and 24 deletions

View File

@ -13,6 +13,7 @@ module Vagrant
# access to the VMs, CLI, etc. all in the scope of this environment. # access to the VMs, CLI, etc. all in the scope of this environment.
class Environment class Environment
DEFAULT_HOME = "~/.vagrant.d" DEFAULT_HOME = "~/.vagrant.d"
DEFAULT_LOCAL_DATA = ".vagrant"
DEFAULT_RC = "~/.vagrantrc" DEFAULT_RC = "~/.vagrantrc"
# This is the global config, comprised of loading configuration from # This is the global config, comprised of loading configuration from
@ -34,6 +35,10 @@ module Vagrant
# global state. # global state.
attr_reader :home_path attr_reader :home_path
# The directory to the directory where local, environment-specific
# data is stored.
attr_reader :local_data_path
# The directory where temporary files for Vagrant go. # The directory where temporary files for Vagrant go.
attr_reader :tmp_path attr_reader :tmp_path
@ -58,10 +63,11 @@ module Vagrant
def initialize(opts=nil) def initialize(opts=nil)
opts = { opts = {
:cwd => nil, :cwd => nil,
:vagrantfile_name => nil, :home_path => nil,
:local_data_path => nil,
:lock_path => nil, :lock_path => nil,
:ui_class => nil, :ui_class => nil,
:home_path => nil :vagrantfile_name => nil
}.merge(opts || {}) }.merge(opts || {})
# Set the default working directory to look for the vagrantfile # Set the default working directory to look for the vagrantfile
@ -70,6 +76,9 @@ module Vagrant
opts[:cwd] = Pathname.new(opts[:cwd]) opts[:cwd] = Pathname.new(opts[:cwd])
raise Errors::EnvironmentNonExistentCWD if !opts[:cwd].directory? raise Errors::EnvironmentNonExistentCWD if !opts[:cwd].directory?
# Set the default ui class
opts[:ui_class] ||= UI::Silent
# Set the Vagrantfile name up. We append "Vagrantfile" and "vagrantfile" so that # Set the Vagrantfile name up. We append "Vagrantfile" and "vagrantfile" so that
# those continue to work as well, but anything custom will take precedence. # those continue to work as well, but anything custom will take precedence.
opts[:vagrantfile_name] ||= [] opts[:vagrantfile_name] ||= []
@ -77,15 +86,12 @@ module Vagrant
opts[:vagrantfile_name] += ["Vagrantfile", "vagrantfile"] opts[:vagrantfile_name] += ["Vagrantfile", "vagrantfile"]
# Set instance variables for all the configuration parameters. # Set instance variables for all the configuration parameters.
@cwd = opts[:cwd] @cwd = opts[:cwd]
@home_path = opts[:home_path]
@lock_path = opts[:lock_path]
@vagrantfile_name = opts[:vagrantfile_name] @vagrantfile_name = opts[:vagrantfile_name]
@lock_path = opts[:lock_path] @ui = opts[:ui_class].new("vagrant")
@home_path = opts[:home_path]
ui_class = opts[:ui_class] || UI::Silent
@ui = ui_class.new("vagrant")
@loaded = false
@lock_acquired = false @lock_acquired = false
@logger = Log4r::Logger.new("vagrant::environment") @logger = Log4r::Logger.new("vagrant::environment")
@ -94,10 +100,22 @@ module Vagrant
# Setup the home directory # Setup the home directory
setup_home_path setup_home_path
@tmp_path = @home_path.join("tmp") @tmp_path = @home_path.join("tmp")
@boxes_path = @home_path.join("boxes") @boxes_path = @home_path.join("boxes")
@gems_path = @home_path.join("gems") @gems_path = @home_path.join("gems")
# Setup the local data directory. If a configuration path is given,
# then it is expanded relative to the working directory. Otherwise,
# we use the default which is expanded relative to the root path.
@local_data_path = nil
if opts[:local_data_path]
@local_data_path = Pathname.new(File.expand_path(opts[:local_data_path], @cwd))
elsif !root_path.nil?
@local_data_path = root_path.join(DEFAULT_LOCAL_DATA)
end
setup_local_data_path
# Setup the default private key # Setup the default private key
@default_private_key_path = @home_path.join("insecure_private_key") @default_private_key_path = @home_path.join("insecure_private_key")
copy_insecure_private_key copy_insecure_private_key
@ -131,15 +149,6 @@ module Vagrant
:virtualbox :virtualbox
end end
# The path to the `dotfile`, which contains the persisted UUID of
# the VM if it exists.
#
# @return [Pathname]
def dotfile_path
return nil if !root_path
root_path.join(config_global.vagrant.dotfile_name)
end
# Returns the collection of boxes for the environment. # Returns the collection of boxes for the environment.
# #
# @return [BoxCollection] # @return [BoxCollection]
@ -315,7 +324,7 @@ module Vagrant
# #
# @return [DataStore] # @return [DataStore]
def local_data def local_data
@local_data ||= DataStore.new(dotfile_path) @local_data ||= DataStore.new(@local_data_path.join("environment_data"))
end end
# The root path is the path where the top-most (loaded last) # The root path is the path where the top-most (loaded last)
@ -433,6 +442,25 @@ module Vagrant
end end
end end
# This creates the local data directory and show an error if it
# couldn't properly be created.
def setup_local_data_path
if @local_data_path.nil?
@logger.warn("No local data path is set. Local data cannot be stored.")
return
end
@logger.info("Local data path: #{@local_data_path}")
begin
@logger.debug("Creating: #{@local_data_path}")
FileUtils.mkdir_p(@local_data_path)
rescue Errno::EACCES
raise Errors::LocalDataDirectoryNotAccessible,
:local_data_path => @local_data_path.to_s
end
end
protected protected
# This method copies the private key into the home directory if it # This method copies the private key into the home directory if it

View File

@ -230,6 +230,10 @@ module Vagrant
error_key(:port_collision_resume) error_key(:port_collision_resume)
end end
class LocalDataDirectoryNotAccessible < VagrantError
error_key(:local_data_dir_not_accessible)
end
class MachineGuestNotReady < VagrantError class MachineGuestNotReady < VagrantError
error_key(:machine_guest_not_ready) error_key(:machine_guest_not_ready)
end end

View File

@ -85,6 +85,13 @@ en:
You specified: %{home_path} You specified: %{home_path}
interrupted: |- interrupted: |-
Vagrant exited after cleanup due to external interrupt. Vagrant exited after cleanup due to external interrupt.
local_data_dir_not_accessible: |-
The directory Vagrant will use to store local environment-specific
state is not accessible. The directory specified as the local data
directory must be both readable and writable for the user that is
running Vagrant.
Local data directory: %{local_data_path}
machine_guest_not_ready: |- machine_guest_not_ready: |-
Guest-specific operations were attempted on a machine that is not Guest-specific operations were attempted on a machine that is not
ready for guest communication. This should not happen and a bug ready for guest communication. This should not happen and a bug

View File

@ -23,19 +23,22 @@ describe Vagrant::Environment do
describe "current working directory" do describe "current working directory" do
it "is the cwd by default" do it "is the cwd by default" do
with_temp_env("VAGRANT_CWD" => nil) do temp_dir = Tempdir.new.path
described_class.new.cwd.should == Pathname.new(Dir.pwd) Dir.chdir(temp_dir) do
with_temp_env("VAGRANT_CWD" => nil) do
described_class.new.cwd.should == Pathname.new(Dir.pwd)
end
end end
end end
it "is set to the cwd given" do it "is set to the cwd given" do
directory = File.dirname(__FILE__) directory = Tempdir.new.path
instance = described_class.new(:cwd => directory) instance = described_class.new(:cwd => directory)
instance.cwd.should == Pathname.new(directory) instance.cwd.should == Pathname.new(directory)
end end
it "is set to the environmental variable VAGRANT_CWD" do it "is set to the environmental variable VAGRANT_CWD" do
directory = File.dirname(__FILE__) directory = Tempdir.new.path
instance = with_temp_env("VAGRANT_CWD" => directory) do instance = with_temp_env("VAGRANT_CWD" => directory) do
described_class.new described_class.new
end end
@ -72,6 +75,24 @@ describe Vagrant::Environment do
end end
end end
describe "local data path" do
it "is set to the proper default" do
default = instance.root_path.join(described_class::DEFAULT_LOCAL_DATA)
instance.local_data_path.should == default
end
it "is expanded relative to the cwd" do
instance = described_class.new(:local_data_path => "foo")
instance.local_data_path.should == instance.cwd.join("foo")
end
it "is set to the given value" do
dir = Tempdir.new.path
instance = described_class.new(:local_data_path => dir)
instance.local_data_path.to_s.should == dir
end
end
describe "default provider" do describe "default provider" do
it "should return virtualbox" do it "should return virtualbox" do
instance.default_provider.should == :virtualbox instance.default_provider.should == :virtualbox