Class: Vagrant::Environment
- Inherits:
-
Object
- Object
- Vagrant::Environment
- Defined in:
- lib/vagrant/environment.rb
Overview
Represents a single Vagrant environment. A "Vagrant environment" is defined as basically a folder with a "Vagrantfile." This class allows access to the VMs, CLI, etc. all in the scope of this environment.
Constant Summary collapse
- HOME_SUBDIRS =
["tmp", "boxes", "logs"]
- DEFAULT_VM =
:default
- DEFAULT_HOME =
"~/.vagrant.d"
Instance Attribute Summary collapse
-
#config_loader ⇒ Object
readonly
The Config object representing the Vagrantfile loader.
-
#cwd ⇒ Object
readonly
The
cwd
that this environment represents. -
#parent ⇒ Object
readonly
Parent environment (in the case of multi-VMs).
-
#ui ⇒ UI
Returns the UI for the environment, which is responsible for talking with the outside world.
-
#vagrantfile_name ⇒ Object
readonly
The valid name for a Vagrantfile for this environment.
-
#vm ⇒ Object
The single VM that this environment represents, in the case of multi-VM.
Class Method Summary collapse
-
.check_virtualbox! ⇒ Object
Verifies that VirtualBox is installed and that the version of VirtualBox installed is high enough.
Instance Method Summary collapse
-
#actions ⇒ Action
Returns the Action class for this environment which allows actions to be executed (middleware chains) in the context of this environment.
-
#box ⇒ Box
Returns the box that this environment represents.
-
#boxes ⇒ BoxCollection
Returns the collection of boxes for the environment.
-
#boxes_path ⇒ Pathname
The path to the Vagrant boxes directory.
-
#cli(*args) ⇒ Object
Makes a call to the CLI with the given arguments as if they came from the real command line (sometimes they do!).
-
#config ⇒ Config::Top
The configuration object represented by this environment.
-
#dotfile_path ⇒ Pathname
The path to the
dotfile
, which contains the persisted UUID of the VM if it exists. -
#global_data ⇒ DataStore
Loads on initial access and reads data from the global data store.
-
#home_path ⇒ Pathname
The path to the home directory and converted into a Pathname object.
-
#host ⇒ Hosts::Base
Returns the host object associated with this environment.
-
#initialize(opts = nil) ⇒ Environment
constructor
Initializes a new environment with the given options.
-
#load! ⇒ Object
Loads this entire environment, setting up the instance variables such as
vm
,config
, etc. -
#load_config! ⇒ Object
Loads this environment's configuration and stores it in the #config variable.
-
#load_home_directory! ⇒ Object
Loads the home directory path and creates the necessary subdirectories within the home directory if they're not already created.
-
#load_vms! ⇒ Object
Loads the persisted VM (if it exists) for this environment.
-
#loaded? ⇒ Bool
Returns a boolean representing if the environment has been loaded or not.
-
#local_data ⇒ DataStore
Loads (on initial access) and reads data from the local data store.
-
#lock ⇒ Object
This locks Vagrant for the duration of the block passed to this method.
-
#lock_path ⇒ Object
This returns the path which Vagrant uses to determine the location of the file lock.
-
#log_path ⇒ Pathname
Path to the Vagrant logs directory.
-
#logger ⇒ Logger
Accesses the logger for Vagrant.
-
#multivm? ⇒ Bool
Returns a boolean whether this environment represents a multi-VM environment or not.
-
#primary_vm ⇒ VM
Returns the primary VM associated with this environment.
-
#reload_config! ⇒ Object
Reloads the configuration of this environment.
-
#resource ⇒ String
Returns the name of the resource which this environment represents.
-
#root_path ⇒ String
The root path is the path where the top-most (loaded last) Vagrantfile resides.
-
#tmp_path ⇒ Pathname
The path to the Vagrant tmp directory.
-
#vms ⇒ Hash<Symbol,VM>
Returns the VMs associated with this environment.
-
#vms_ordered ⇒ Array<VM>
Returns the VMs associated with this environment, in the order that they were defined.
Constructor Details
#initialize(opts = nil) ⇒ Environment
Initializes a new environment with the given options. The options
is a hash where the main available key is cwd
, which defines where
the environment represents. There are other options available but
they shouldn't be used in general. If cwd
is nil, then it defaults
to the Dir.pwd
(which is the cwd of the executing process).
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/vagrant/environment.rb', line 59 def initialize(opts=nil) opts = { :parent => nil, :vm => nil, :cwd => nil, :vagrantfile_name => nil, :lock_path => nil }.merge(opts || {}) # Set the default working directory to look for the vagrantfile opts[:cwd] ||= Dir.pwd opts[:cwd] = Pathname.new(opts[:cwd]) # Set the default vagrantfile name, which can be either Vagrantfile # or vagrantfile (capital for backwards compatibility) opts[:vagrantfile_name] ||= ["Vagrantfile", "vagrantfile"] opts[:vagrantfile_name] = [opts[:vagrantfile_name]] if !opts[:vagrantfile_name].is_a?(Array) opts.each do |key, value| instance_variable_set("@#{key}".to_sym, opts[key]) end @loaded = false @lock_acquired = false logger.info("environment") { "Environment initialized (#{self})" } logger.info("environment") { " - cwd: #{cwd}" } logger.info("environment") { " - parent: #{parent}" } logger.info("environment") { " - vm: #{vm}" } end |
Instance Attribute Details
#config_loader ⇒ Object (readonly)
The Config object representing the Vagrantfile loader
31 32 33 |
# File 'lib/vagrant/environment.rb', line 31 def config_loader @config_loader end |
#cwd ⇒ Object (readonly)
The cwd
that this environment represents
18 19 20 |
# File 'lib/vagrant/environment.rb', line 18 def cwd @cwd end |
#parent ⇒ Object (readonly)
Parent environment (in the case of multi-VMs)
15 16 17 |
# File 'lib/vagrant/environment.rb', line 15 def parent @parent end |
#ui ⇒ UI
Returns the UI for the environment, which is responsible for talking with the outside world.
240 241 242 243 244 245 246 247 248 |
# File 'lib/vagrant/environment.rb', line 240 def ui @ui ||= if parent result = parent.ui.clone result.env = self result else UI.new(self) end end |
#vagrantfile_name ⇒ Object (readonly)
The valid name for a Vagrantfile for this environment.
21 22 23 |
# File 'lib/vagrant/environment.rb', line 21 def vagrantfile_name @vagrantfile_name end |
#vm ⇒ Object
The single VM that this environment represents, in the case of multi-VM.
25 26 27 |
# File 'lib/vagrant/environment.rb', line 25 def vm @vm end |
Class Method Details
.check_virtualbox! ⇒ Object
Verifies that VirtualBox is installed and that the version of VirtualBox installed is high enough.
39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/vagrant/environment.rb', line 39 def check_virtualbox! version = VirtualBox.version raise Errors::VirtualBoxNotDetected if version.nil? raise Errors::VirtualBoxInvalidVersion, :version => version.to_s if version.to_f < 4.1 || version.to_f >= 4.2 rescue Errors::VirtualBoxNotDetected # On 64-bit Windows, show a special error. This error is a subclass # of VirtualBoxNotDetected, so libraries which use Vagrant can just # rescue VirtualBoxNotDetected. raise Errors::VirtualBoxNotDetected_Win64 if Util::Platform.windows? && Util::Platform.bit64? # Otherwise, reraise the old error raise end |
Instance Method Details
#actions ⇒ Action
Returns the Action class for this environment which allows actions to be executed (middleware chains) in the context of this environment.
261 262 263 |
# File 'lib/vagrant/environment.rb', line 261 def actions @actions ||= Action.new(self) end |
#box ⇒ Box
Returns the box that this environment represents.
177 178 179 |
# File 'lib/vagrant/environment.rb', line 177 def box boxes.find(config.vm.box) end |
#boxes ⇒ BoxCollection
Returns the collection of boxes for the environment.
169 170 171 172 |
# File 'lib/vagrant/environment.rb', line 169 def boxes return parent.boxes if parent @_boxes ||= BoxCollection.new(self) end |
#boxes_path ⇒ Pathname
The path to the Vagrant boxes directory
145 146 147 |
# File 'lib/vagrant/environment.rb', line 145 def boxes_path home_path.join("boxes") end |
#cli(*args) ⇒ Object
Makes a call to the CLI with the given arguments as if they came from the real command line (sometimes they do!). An example:
env.cli("package", "--vagrantfile", "Vagrantfile")
232 233 234 |
# File 'lib/vagrant/environment.rb', line 232 def cli(*args) CLI.start(args.flatten, :env => self) end |
#config ⇒ Config::Top
The configuration object represented by this environment. This will trigger the environment to load if it hasn't loaded yet (see #load!).
383 384 385 386 |
# File 'lib/vagrant/environment.rb', line 383 def config load! if !loaded? @config end |
#dotfile_path ⇒ Pathname
The path to the dotfile
, which contains the persisted UUID of
the VM if it exists.
98 99 100 |
# File 'lib/vagrant/environment.rb', line 98 def dotfile_path root_path.join(config.vagrant.dotfile_name) rescue nil end |
#global_data ⇒ DataStore
Loads on initial access and reads data from the global data store. The global data store is global to Vagrant everywhere (in every environment), so it can be used to store system-wide information. Note that "system-wide" typically means "for this user" since the location of the global data store is in the home directory.
272 273 274 275 |
# File 'lib/vagrant/environment.rb', line 272 def global_data return parent.global_data if parent @global_data ||= DataStore.new(File.("global_data.json", home_path)) end |
#home_path ⇒ Pathname
The path to the home directory and converted into a Pathname object.
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/vagrant/environment.rb', line 105 def home_path return parent.home_path if parent return @_home_path if defined?(@_home_path) @_home_path ||= Pathname.new(File.(ENV["VAGRANT_HOME"] || DEFAULT_HOME)) logger.info("environment") { "Home path: #{@_home_path}" } # This is the old default that Vagrant used to be put things into # up until Vagrant 0.8.0. We keep around an automatic migration # script here in case any old users upgrade. old_home = File.("~/.vagrant") if File.exists?(old_home) && File.directory?(old_home) logger.info("environment") { "Found both an old and new Vagrantfile. Migration initiated." } # We can't migrate if the home directory already exists if File.exists?(@_home_path) ui.warn I18n.t("vagrant.general.home_dir_migration_failed", :old => old_home, :new => @_home_path.to_s) else # If the new home path doesn't exist, simply transition to it ui.info I18n.t("vagrant.general.moving_home_dir", :directory => @_home_path) FileUtils.mv(old_home, @_home_path) end end # Return the home path @_home_path end |
#host ⇒ Hosts::Base
Returns the host object associated with this environment.
253 254 255 |
# File 'lib/vagrant/environment.rb', line 253 def host @host ||= Hosts::Base.load(self, config.vagrant.host) end |
#load! ⇒ Object
Loads this entire environment, setting up the instance variables
such as vm
, config
, etc. on this environment. The order this
method calls its other methods is very particular.
403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 |
# File 'lib/vagrant/environment.rb', line 403 def load! if !loaded? @loaded = true if !parent # We only need to check the virtualbox version once, so do it on # the parent most environment and then forget about it logger.info("environment") { "Environment not loaded. Checking virtual box version..." } self.class.check_virtualbox! end logger.info("environment") { "Loading configuration..." } load_config! end self end |
#load_config! ⇒ Object
Loads this environment's configuration and stores it in the #config variable. The configuration loaded by this method is specified to this environment, meaning that it will use the given root directory to load the Vagrantfile into that context.
433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 |
# File 'lib/vagrant/environment.rb', line 433 def load_config! first_run = @config.nil? # First load the initial, non config-dependent Vagrantfiles @config_loader ||= Config.new(parent ? parent.config_loader : nil) @config_loader.load_order = [:default, :box, :home, :root, :sub_vm] @config_loader.set(:default, File.("config/default.rb", Vagrant.source_root)) vagrantfile_name.each do |rootfile| if !first_run && vm && box # We load the box Vagrantfile box_vagrantfile = box.directory.join(rootfile) @config_loader.set(:box, box_vagrantfile) if box_vagrantfile.exist? end if !first_run && home_path # Load the home Vagrantfile home_vagrantfile = home_path.join(rootfile) @config_loader.set(:home, home_vagrantfile) if home_vagrantfile.exist? end if root_path # Load the Vagrantfile in this directory root_vagrantfile = root_path.join(rootfile) @config_loader.set(:root, root_vagrantfile) if root_vagrantfile.exist? end end # If this environment is representing a sub-VM, then we push that # proc on as the last configuration. if vm subvm = parent.config.vm.defined_vms[vm.name] @config_loader.set(:sub_vm, subvm.proc_stack) if subvm end # Execute the configuration stack and store the result as the final # value in the config ivar. @config = @config_loader.load(self) if first_run # After the first run we want to load the configuration again since # it can change due to box Vagrantfiles and home directory Vagrantfiles load_home_directory! load_config! end end |
#load_home_directory! ⇒ Object
Loads the home directory path and creates the necessary subdirectories within the home directory if they're not already created.
482 483 484 485 486 487 488 489 490 491 492 493 494 |
# File 'lib/vagrant/environment.rb', line 482 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) ui.info I18n.t("vagrant.general.creating_home_dir", :directory => dir) FileUtils.mkdir_p(dir) end end |
#load_vms! ⇒ Object
Loads the persisted VM (if it exists) for this environment.
497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 |
# File 'lib/vagrant/environment.rb', line 497 def load_vms! result = {} # Load the VM UUIDs from the local data store (local_data[:active] || {}).each do |name, uuid| result[name.to_sym] = Vagrant::VM.find(uuid, self, name.to_sym) end # For any VMs which aren't created, create a blank VM instance for # them all_keys = config.vm.defined_vm_keys all_keys = [DEFAULT_VM] if all_keys.empty? all_keys.each do |name| result[name] = Vagrant::VM.new(:name => name, :env => self) if !result.has_key?(name) end result end |
#loaded? ⇒ Bool
Returns a boolean representing if the environment has been loaded or not.
396 397 398 |
# File 'lib/vagrant/environment.rb', line 396 def loaded? !!@loaded end |
#local_data ⇒ DataStore
Loads (on initial access) and reads data from the local data store. This file is always at the root path as the file "~/.vagrant" and contains a JSON dump of a hash. See DataStore for more information.
283 284 285 286 |
# File 'lib/vagrant/environment.rb', line 283 def local_data return parent.local_data if parent @local_data ||= DataStore.new(dotfile_path) end |
#lock ⇒ Object
This locks Vagrant for the duration of the block passed to this method. During this time, any other environment which attempts to lock which points to the same lock file will fail.
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 |
# File 'lib/vagrant/environment.rb', line 350 def lock # This allows multiple locks in the same process to be nested return yield if @lock_acquired File.open(lock_path, "w+") do |f| # The file locking fails only if it returns "false." If it # succeeds it returns a 0, so we must explicitly check for # the proper error case. raise Errors::EnvironmentLockedError if f.flock(File::LOCK_EX | File::LOCK_NB) === false begin # Mark that we have a lock @lock_acquired = true yield ensure # We need to make sure that no matter what this is always # reset to false so we don't think we have a lock when we # actually don't. @lock_acquired = false end end end |
#lock_path ⇒ Object
This returns the path which Vagrant uses to determine the location of the file lock. This is specific to each operating system.
343 344 345 |
# File 'lib/vagrant/environment.rb', line 343 def lock_path @lock_path || tmp_path.join("vagrant.lock") end |
#log_path ⇒ Pathname
Path to the Vagrant logs directory
152 153 154 |
# File 'lib/vagrant/environment.rb', line 152 def log_path home_path.join("logs") end |
#logger ⇒ Logger
Accesses the logger for Vagrant. This logger is a detailed logger which should be used to log internals only. For outward facing information, use #ui.
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 |
# File 'lib/vagrant/environment.rb', line 293 def logger return parent.logger if parent return @logger if @logger # Figure out where the output should go to. output = nil if ENV["VAGRANT_LOG"] == "STDOUT" output = STDOUT elsif ENV["VAGRANT_LOG"] == "NULL" output = nil elsif ENV["VAGRANT_LOG"] output = ENV["VAGRANT_LOG"] else output = nil #log_path.join("#{Time.now.to_i}.log") end # Create the logger and custom formatter @logger = Logger.new(output) @logger.formatter = Proc.new do |severity, datetime, progname, msg| "#{datetime} - #{progname} - [#{resource}] #{msg}\n" end @logger end |
#multivm? ⇒ Bool
Returns a boolean whether this environment represents a multi-VM environment or not. This will work even when called on child environments.
219 220 221 222 223 224 225 |
# File 'lib/vagrant/environment.rb', line 219 def multivm? if parent parent.multivm? else vms.length > 1 || vms.keys.first != DEFAULT_VM end end |
#primary_vm ⇒ VM
Returns the primary VM associated with this environment. This method is only applicable for multi-VM environments. This can potentially be nil if no primary VM is specified.
203 204 205 206 207 208 209 210 211 212 |
# File 'lib/vagrant/environment.rb', line 203 def primary_vm return vms.values.first if !multivm? return parent.primary_vm if parent config.vm.defined_vms.each do |name, subvm| return vms[name] if subvm.[:primary] end nil end |
#reload_config! ⇒ Object
Reloads the configuration of this environment.
422 423 424 425 426 427 |
# File 'lib/vagrant/environment.rb', line 422 def reload_config! @config = nil @config_loader = nil load_config! self end |
#resource ⇒ String
Returns the name of the resource which this environment represents. The resource is the VM name if there is a VM it represents, otherwise it defaults to "vagrant"
161 162 163 164 |
# File 'lib/vagrant/environment.rb', line 161 def resource result = vm.name rescue nil result || "vagrant" end |
#root_path ⇒ String
The root path is the path where the top-most (loaded last) Vagrantfile resides. It can be considered the project root for this environment.
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 |
# File 'lib/vagrant/environment.rb', line 323 def root_path return @root_path if defined?(@root_path) root_finder = lambda do |path| # Note: To remain compatible with Ruby 1.8, we have to use # a `find` here instead of an `each`. found = vagrantfile_name.find do |rootfile| File.exist?(File.join(path.to_s, rootfile)) end return path if found return nil if path.root? || !File.exist?(path) root_finder.call(path.parent) end @root_path = root_finder.call(cwd) end |
#tmp_path ⇒ Pathname
The path to the Vagrant tmp directory
138 139 140 |
# File 'lib/vagrant/environment.rb', line 138 def tmp_path home_path.join("tmp") end |
#vms ⇒ Hash<Symbol,VM>
Returns the VMs associated with this environment.
184 185 186 187 188 |
# File 'lib/vagrant/environment.rb', line 184 def vms return parent.vms if parent load! if !loaded? @vms ||= load_vms! end |
#vms_ordered ⇒ Array<VM>
Returns the VMs associated with this environment, in the order that they were defined.
194 195 196 |
# File 'lib/vagrant/environment.rb', line 194 def vms_ordered @vms_enum ||= config.vm.defined_vm_keys.map { |name| @vms[name] } end |