vagrant 0.5.4 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (234) hide show
  1. data/.gitignore +1 -0
  2. data/.yardopts +1 -0
  3. data/CHANGELOG.md +56 -0
  4. data/Gemfile +14 -3
  5. data/Gemfile.lock +38 -11
  6. data/README.md +1 -1
  7. data/bin/vagrant +20 -5
  8. data/config/default.rb +6 -8
  9. data/lib/vagrant.rb +40 -13
  10. data/lib/vagrant/action.rb +56 -16
  11. data/lib/vagrant/action/box/destroy.rb +3 -1
  12. data/lib/vagrant/action/box/download.rb +8 -13
  13. data/lib/vagrant/action/box/unpackage.rb +8 -11
  14. data/lib/vagrant/action/box/verify.rb +3 -3
  15. data/lib/vagrant/action/builder.rb +3 -30
  16. data/lib/vagrant/action/builtin.rb +6 -1
  17. data/lib/vagrant/action/environment.rb +14 -62
  18. data/lib/vagrant/action/general/package.rb +29 -22
  19. data/lib/vagrant/action/vm/boot.rb +5 -12
  20. data/lib/vagrant/action/vm/check_box.rb +4 -4
  21. data/lib/vagrant/action/vm/check_guest_additions.rb +4 -6
  22. data/lib/vagrant/action/vm/clear_forwarded_ports.rb +2 -2
  23. data/lib/vagrant/action/vm/clear_nfs_exports.rb +1 -1
  24. data/lib/vagrant/action/vm/clear_shared_folders.rb +1 -1
  25. data/lib/vagrant/action/vm/customize.rb +1 -1
  26. data/lib/vagrant/action/vm/destroy.rb +1 -2
  27. data/lib/vagrant/action/vm/destroy_unused_network_interfaces.rb +1 -1
  28. data/lib/vagrant/action/vm/disable_networks.rb +11 -9
  29. data/lib/vagrant/action/vm/discard_state.rb +2 -2
  30. data/lib/vagrant/action/vm/export.rb +10 -11
  31. data/lib/vagrant/action/vm/forward_ports.rb +21 -9
  32. data/lib/vagrant/action/vm/halt.rb +3 -8
  33. data/lib/vagrant/action/vm/import.rb +16 -14
  34. data/lib/vagrant/action/vm/match_mac_address.rb +1 -1
  35. data/lib/vagrant/action/vm/network.rb +9 -16
  36. data/lib/vagrant/action/vm/nfs.rb +14 -18
  37. data/lib/vagrant/action/vm/provision.rb +5 -5
  38. data/lib/vagrant/action/vm/resume.rb +1 -1
  39. data/lib/vagrant/action/vm/share_folders.rb +6 -44
  40. data/lib/vagrant/action/vm/suspend.rb +1 -1
  41. data/lib/vagrant/action/warden.rb +74 -0
  42. data/lib/vagrant/box.rb +18 -82
  43. data/lib/vagrant/box_collection.rb +47 -0
  44. data/lib/vagrant/cli.rb +55 -0
  45. data/lib/vagrant/command/base.rb +106 -0
  46. data/lib/vagrant/command/box.rb +33 -0
  47. data/lib/vagrant/command/destroy.rb +17 -0
  48. data/lib/vagrant/command/group_base.rb +99 -0
  49. data/lib/vagrant/command/halt.rb +18 -0
  50. data/lib/vagrant/command/helpers.rb +33 -0
  51. data/lib/vagrant/command/init.rb +14 -0
  52. data/lib/vagrant/command/named_base.rb +14 -0
  53. data/lib/vagrant/command/package.rb +41 -0
  54. data/lib/vagrant/command/provision.rb +17 -0
  55. data/lib/vagrant/command/reload.rb +17 -0
  56. data/lib/vagrant/command/resume.rb +17 -0
  57. data/lib/vagrant/command/ssh.rb +41 -0
  58. data/lib/vagrant/command/ssh_config.rb +21 -0
  59. data/lib/vagrant/command/status.rb +23 -0
  60. data/lib/vagrant/command/suspend.rb +17 -0
  61. data/lib/vagrant/command/up.rb +20 -0
  62. data/lib/vagrant/command/upgrade_to_060.rb +45 -0
  63. data/lib/vagrant/command/version.rb +13 -0
  64. data/lib/vagrant/config.rb +107 -189
  65. data/lib/vagrant/config/base.rb +67 -0
  66. data/lib/vagrant/config/error_recorder.rb +19 -0
  67. data/lib/vagrant/config/nfs.rb +10 -0
  68. data/lib/vagrant/config/package.rb +9 -0
  69. data/lib/vagrant/config/ssh.rb +28 -0
  70. data/lib/vagrant/config/vagrant.rb +21 -0
  71. data/lib/vagrant/config/vm.rb +111 -0
  72. data/lib/vagrant/data_store.rb +68 -0
  73. data/lib/vagrant/downloaders/file.rb +3 -3
  74. data/lib/vagrant/downloaders/http.rb +5 -5
  75. data/lib/vagrant/environment.rb +246 -243
  76. data/lib/vagrant/errors.rb +306 -0
  77. data/lib/vagrant/hosts/base.rb +1 -1
  78. data/lib/vagrant/hosts/bsd.rb +3 -9
  79. data/lib/vagrant/hosts/linux.rb +3 -9
  80. data/lib/vagrant/plugin.rb +50 -0
  81. data/lib/vagrant/provisioners/base.rb +0 -6
  82. data/lib/vagrant/provisioners/chef.rb +63 -58
  83. data/lib/vagrant/provisioners/chef_server.rb +9 -11
  84. data/lib/vagrant/provisioners/chef_solo.rb +2 -2
  85. data/lib/vagrant/ssh.rb +34 -37
  86. data/lib/vagrant/systems/base.rb +0 -13
  87. data/lib/vagrant/systems/linux.rb +10 -33
  88. data/lib/vagrant/systems/solaris.rb +59 -0
  89. data/lib/vagrant/test_helpers.rb +109 -0
  90. data/lib/vagrant/ui.rb +65 -0
  91. data/lib/vagrant/util.rb +9 -19
  92. data/lib/vagrant/util/glob_loader.rb +19 -17
  93. data/lib/vagrant/util/hash_with_indifferent_access.rb +63 -0
  94. data/lib/vagrant/util/plain_logger.rb +2 -0
  95. data/lib/vagrant/util/platform.rb +2 -0
  96. data/lib/vagrant/util/resource_logger.rb +5 -70
  97. data/lib/vagrant/util/retryable.rb +25 -0
  98. data/lib/vagrant/util/template_renderer.rb +1 -1
  99. data/lib/vagrant/version.rb +1 -1
  100. data/lib/vagrant/vm.rb +27 -13
  101. data/templates/commands/init/Vagrantfile.erb +13 -0
  102. data/templates/config/validation_failed.erb +7 -0
  103. data/templates/locales/en.yml +402 -0
  104. data/templates/package_Vagrantfile.erb +1 -1
  105. data/test/locales/en.yml +8 -0
  106. data/test/test_helper.rb +19 -103
  107. data/test/vagrant/action/box/destroy_test.rb +7 -19
  108. data/test/vagrant/action/box/download_test.rb +9 -25
  109. data/test/vagrant/action/box/package_test.rb +2 -2
  110. data/test/vagrant/action/box/unpackage_test.rb +8 -34
  111. data/test/vagrant/action/box/verify_test.rb +10 -19
  112. data/test/vagrant/action/builder_test.rb +0 -15
  113. data/test/vagrant/action/env/set_test.rb +1 -1
  114. data/test/vagrant/action/environment_test.rb +8 -26
  115. data/test/vagrant/action/general/package_test.rb +53 -53
  116. data/test/vagrant/action/vm/boot_test.rb +5 -22
  117. data/test/vagrant/action/vm/check_box_test.rb +35 -25
  118. data/test/vagrant/action/vm/clean_machine_folder_test.rb +1 -1
  119. data/test/vagrant/action/vm/clear_forwarded_ports_test.rb +1 -1
  120. data/test/vagrant/action/vm/clear_nfs_exports_test.rb +1 -1
  121. data/test/vagrant/action/vm/clear_shared_folders_test.rb +1 -1
  122. data/test/vagrant/action/vm/customize_test.rb +2 -1
  123. data/test/vagrant/action/vm/destroy_test.rb +1 -2
  124. data/test/vagrant/action/vm/destroy_unused_network_interfaces_test.rb +1 -1
  125. data/test/vagrant/action/vm/disable_networks_test.rb +10 -1
  126. data/test/vagrant/action/vm/discard_state_test.rb +10 -1
  127. data/test/vagrant/action/vm/export_test.rb +9 -37
  128. data/test/vagrant/action/vm/forward_ports_helpers_test.rb +2 -2
  129. data/test/vagrant/action/vm/forward_ports_test.rb +19 -16
  130. data/test/vagrant/action/vm/halt_test.rb +11 -1
  131. data/test/vagrant/action/vm/import_test.rb +37 -21
  132. data/test/vagrant/action/vm/match_mac_address_test.rb +1 -1
  133. data/test/vagrant/action/vm/network_test.rb +8 -7
  134. data/test/vagrant/action/vm/nfs_helpers_test.rb +6 -3
  135. data/test/vagrant/action/vm/nfs_test.rb +20 -45
  136. data/test/vagrant/action/vm/package_test.rb +1 -1
  137. data/test/vagrant/action/vm/package_vagrantfile_test.rb +1 -1
  138. data/test/vagrant/action/vm/provision_test.rb +10 -17
  139. data/test/vagrant/action/vm/resume_test.rb +1 -1
  140. data/test/vagrant/action/vm/share_folders_test.rb +25 -106
  141. data/test/vagrant/action/vm/suspend_test.rb +1 -1
  142. data/test/vagrant/action/warden_test.rb +105 -0
  143. data/test/vagrant/action_test.rb +5 -27
  144. data/test/vagrant/box_collection_test.rb +44 -0
  145. data/test/vagrant/box_test.rb +5 -105
  146. data/test/vagrant/cli_test.rb +35 -0
  147. data/test/vagrant/command/base_test.rb +23 -0
  148. data/test/vagrant/command/group_base_test.rb +15 -0
  149. data/test/vagrant/command/helpers_test.rb +88 -0
  150. data/test/vagrant/config/base_test.rb +52 -0
  151. data/test/vagrant/config/error_recorder_test.rb +18 -0
  152. data/test/vagrant/config/ssh_test.rb +12 -0
  153. data/test/vagrant/config/vagrant_test.rb +11 -0
  154. data/test/vagrant/config/vm_test.rb +70 -0
  155. data/test/vagrant/config_test.rb +113 -206
  156. data/test/vagrant/data_store_test.rb +68 -0
  157. data/test/vagrant/downloaders/base_test.rb +1 -1
  158. data/test/vagrant/downloaders/file_test.rb +4 -3
  159. data/test/vagrant/downloaders/http_test.rb +14 -4
  160. data/test/vagrant/environment_test.rb +290 -590
  161. data/test/vagrant/errors_test.rb +42 -0
  162. data/test/vagrant/hosts/base_test.rb +1 -1
  163. data/test/vagrant/hosts/bsd_test.rb +3 -6
  164. data/test/vagrant/hosts/linux_test.rb +3 -5
  165. data/test/vagrant/plugin_test.rb +9 -0
  166. data/test/vagrant/provisioners/base_test.rb +1 -1
  167. data/test/vagrant/provisioners/chef_server_test.rb +31 -35
  168. data/test/vagrant/provisioners/chef_solo_test.rb +1 -1
  169. data/test/vagrant/provisioners/chef_test.rb +7 -7
  170. data/test/vagrant/ssh_session_test.rb +3 -10
  171. data/test/vagrant/ssh_test.rb +25 -33
  172. data/test/vagrant/systems/linux_test.rb +6 -71
  173. data/test/vagrant/ui_test.rb +29 -0
  174. data/test/vagrant/util/hash_with_indifferent_access_test.rb +39 -0
  175. data/test/vagrant/util/resource_logger_test.rb +14 -81
  176. data/test/vagrant/util/retryable_test.rb +38 -0
  177. data/test/vagrant/util/template_renderer_test.rb +4 -4
  178. data/test/vagrant/vm_test.rb +47 -26
  179. data/vagrant.gemspec +14 -12
  180. metadata +142 -108
  181. data/bin/.gitignore +0 -0
  182. data/lib/vagrant/action/action_exception.rb +0 -16
  183. data/lib/vagrant/action/env/error_halt.rb +0 -16
  184. data/lib/vagrant/action/exception_catcher.rb +0 -14
  185. data/lib/vagrant/action/vm/persist.rb +0 -22
  186. data/lib/vagrant/active_list.rb +0 -83
  187. data/lib/vagrant/command.rb +0 -27
  188. data/lib/vagrant/commands/base.rb +0 -181
  189. data/lib/vagrant/commands/box.rb +0 -16
  190. data/lib/vagrant/commands/box/add.rb +0 -30
  191. data/lib/vagrant/commands/box/list.rb +0 -30
  192. data/lib/vagrant/commands/box/remove.rb +0 -30
  193. data/lib/vagrant/commands/box/repackage.rb +0 -35
  194. data/lib/vagrant/commands/destroy.rb +0 -37
  195. data/lib/vagrant/commands/halt.rb +0 -43
  196. data/lib/vagrant/commands/init.rb +0 -36
  197. data/lib/vagrant/commands/package.rb +0 -81
  198. data/lib/vagrant/commands/provision.rb +0 -31
  199. data/lib/vagrant/commands/reload.rb +0 -36
  200. data/lib/vagrant/commands/resume.rb +0 -35
  201. data/lib/vagrant/commands/ssh.rb +0 -78
  202. data/lib/vagrant/commands/ssh_config.rb +0 -45
  203. data/lib/vagrant/commands/status.rb +0 -125
  204. data/lib/vagrant/commands/suspend.rb +0 -36
  205. data/lib/vagrant/commands/up.rb +0 -44
  206. data/lib/vagrant/exceptions/uncallable_action.rb +0 -17
  207. data/lib/vagrant/util/translator.rb +0 -35
  208. data/templates/strings.yml +0 -341
  209. data/templates/unison/crontab_entry.erb +0 -1
  210. data/templates/unison/script.erb +0 -71
  211. data/test/vagrant/action/env/error_halt_test.rb +0 -21
  212. data/test/vagrant/action/exception_catcher_test.rb +0 -30
  213. data/test/vagrant/action/vm/persist_test.rb +0 -50
  214. data/test/vagrant/active_list_test.rb +0 -173
  215. data/test/vagrant/command_test.rb +0 -53
  216. data/test/vagrant/commands/base_test.rb +0 -139
  217. data/test/vagrant/commands/box/add_test.rb +0 -34
  218. data/test/vagrant/commands/box/list_test.rb +0 -32
  219. data/test/vagrant/commands/box/remove_test.rb +0 -41
  220. data/test/vagrant/commands/box/repackage_test.rb +0 -52
  221. data/test/vagrant/commands/destroy_test.rb +0 -44
  222. data/test/vagrant/commands/halt_test.rb +0 -50
  223. data/test/vagrant/commands/init_test.rb +0 -71
  224. data/test/vagrant/commands/package_test.rb +0 -97
  225. data/test/vagrant/commands/provision_test.rb +0 -60
  226. data/test/vagrant/commands/reload_test.rb +0 -47
  227. data/test/vagrant/commands/resume_test.rb +0 -44
  228. data/test/vagrant/commands/ssh_config_test.rb +0 -77
  229. data/test/vagrant/commands/ssh_test.rb +0 -129
  230. data/test/vagrant/commands/status_test.rb +0 -40
  231. data/test/vagrant/commands/suspend_test.rb +0 -44
  232. data/test/vagrant/commands/up_test.rb +0 -49
  233. data/test/vagrant/util/translator_test.rb +0 -61
  234. data/test/vagrant/util_test.rb +0 -27
@@ -0,0 +1,67 @@
1
+ module Vagrant
2
+ class Config
3
+ # The base class for all configuration classes. This implements
4
+ # basic things such as the environment instance variable which all
5
+ # config classes need as well as a basic `to_json` implementation.
6
+ class Base
7
+ attr_accessor :env
8
+
9
+ # Registers a subclass with the Vagrant configuration system so
10
+ # that it can then be used in Vagrantfiles.
11
+ #
12
+ # @param [Symbol] accessor The accessor on the main config object
13
+ # that is used to access the configuration class.
14
+ #
15
+ def self.configures(accessor, klass=self)
16
+ Top.configures(accessor, klass)
17
+ end
18
+
19
+ # Loads configuration values from JSON back into the proper
20
+ # configuration classes. By default, this is done by simply
21
+ # iterating over all values in the JSON hash and assigning them
22
+ # to instance variables on the class.
23
+ def self.json_create(data)
24
+ data.inject(new) do |result, data|
25
+ key, value = data
26
+ result.instance_variable_set("@#{key}".to_sym, value) if key != "json_class"
27
+ result
28
+ end
29
+ end
30
+
31
+ # Called by {Top} after the configuration is loaded to validate
32
+ # the configuaration objects. Subclasses should implement this
33
+ # method and add any errors to the `errors` object given.
34
+ #
35
+ # @param [ErrorRecorder] errors
36
+ def validate(errors); end
37
+
38
+ # Converts the configuration to a raw hash by calling `#to_hash`
39
+ # on all instance variables (if it can) and putting them into
40
+ # a hash.
41
+ def to_hash
42
+ instance_variables_hash.inject({}) do |acc, data|
43
+ k,v = data
44
+ v = v.to_hash if v.respond_to?(:to_hash)
45
+ acc[k] = v
46
+ acc
47
+ end
48
+ end
49
+
50
+ # Converts to JSON, with the `json_class` field set so that when
51
+ # the JSON is parsed back, it can be loaded back into the proper class.
52
+ # See {json_create}.
53
+ def to_json(*a)
54
+ result = { 'json_class' => self.class.name }
55
+ result.merge(instance_variables_hash).to_json(*a)
56
+ end
57
+
58
+ # Returns the instance variables as a hash of key-value pairs.
59
+ def instance_variables_hash
60
+ instance_variables.inject({}) do |acc, iv|
61
+ acc[iv.to_s[1..-1]] = instance_variable_get(iv) unless iv.to_sym == :@env
62
+ acc
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,19 @@
1
+ module Vagrant
2
+ class Config
3
+ # A class which is passed into the various {Base#validate} methods and
4
+ # can be used as a helper to add error messages about a single config
5
+ # class.
6
+ class ErrorRecorder
7
+ attr_reader :errors
8
+
9
+ def initialize
10
+ @errors = []
11
+ end
12
+
13
+ # Adds an error to the list of errors.
14
+ def add(message)
15
+ @errors << message
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,10 @@
1
+ module Vagrant
2
+ class Config
3
+ class NFSConfig < Base
4
+ configures :nfs
5
+
6
+ attr_accessor :map_uid
7
+ attr_accessor :map_gid
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ module Vagrant
2
+ class Config
3
+ class PackageConfig < Base
4
+ configures :package
5
+
6
+ attr_accessor :name
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,28 @@
1
+ module Vagrant
2
+ class Config
3
+ class SSHConfig < Base
4
+ configures :ssh
5
+
6
+ attr_accessor :username
7
+ attr_accessor :host
8
+ attr_accessor :port
9
+ attr_accessor :forwarded_port_key
10
+ attr_accessor :max_tries
11
+ attr_accessor :timeout
12
+ attr_writer :private_key_path
13
+ attr_accessor :forward_agent
14
+
15
+ def private_key_path
16
+ File.expand_path(@private_key_path, env.root_path)
17
+ end
18
+
19
+ def validate(errors)
20
+ [:username, :host, :port, :forwarded_port_key, :max_tries, :timeout, :private_key_path].each do |field|
21
+ errors.add(I18n.t("vagrant.config.common.error_empty", :field => field)) if !instance_variable_get("@#{field}".to_sym)
22
+ end
23
+
24
+ errors.add(I18n.t("vagrant.config.ssh.private_key_missing", :path => private_key_path)) if !File.file?(private_key_path)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,21 @@
1
+ module Vagrant
2
+ class Config
3
+ class VagrantConfig < Base
4
+ configures :vagrant
5
+
6
+ attr_accessor :dotfile_name
7
+ attr_accessor :home
8
+ attr_accessor :host
9
+
10
+ def initialize
11
+ @home = nil
12
+ end
13
+
14
+ def validate(errors)
15
+ [:dotfile_name, :home, :host].each do |field|
16
+ errors.add(I18n.t("vagrant.config.common.error_empty", :field => field)) if !instance_variable_get("@#{field}".to_sym)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,111 @@
1
+ module Vagrant
2
+ class Config
3
+ class VMConfig < Base
4
+ configures :vm
5
+
6
+ include Util::StackedProcRunner
7
+
8
+ attr_accessor :auto_port_range
9
+ attr_accessor :box
10
+ attr_accessor :box_url
11
+ attr_accessor :box_ovf
12
+ attr_accessor :base_mac
13
+ attr_accessor :boot_mode
14
+ attr_reader :forwarded_ports
15
+ attr_reader :shared_folders
16
+ attr_reader :network_options
17
+ attr_reader :hd_location
18
+ attr_accessor :disk_image_format
19
+ attr_accessor :provisioner
20
+ attr_writer :shared_folder_uid
21
+ attr_writer :shared_folder_gid
22
+ attr_accessor :system
23
+
24
+ # Represents a SubVM. This class is only used here in the VMs
25
+ # hash.
26
+ class SubVM
27
+ include Util::StackedProcRunner
28
+
29
+ def options
30
+ @options ||= {}
31
+ end
32
+ end
33
+
34
+ def initialize
35
+ @forwarded_ports = {}
36
+ @shared_folders = {}
37
+ @provisioner = nil
38
+ @network_options = []
39
+ end
40
+
41
+ def forward_port(name, guestport, hostport, options=nil)
42
+ options = {
43
+ :guestport => guestport,
44
+ :hostport => hostport,
45
+ :protocol => "TCP",
46
+ :adapter => 0,
47
+ :auto => false
48
+ }.merge(options || {})
49
+
50
+ forwarded_ports[name] = options
51
+ end
52
+
53
+ def share_folder(name, guestpath, hostpath, opts=nil)
54
+ @shared_folders[name] = {
55
+ :guestpath => guestpath,
56
+ :hostpath => hostpath
57
+ }.merge(opts || {})
58
+ end
59
+
60
+ def network(ip, options=nil)
61
+ options = {
62
+ :ip => ip,
63
+ :netmask => "255.255.255.0",
64
+ :adapter => 1,
65
+ :name => nil
66
+ }.merge(options || {})
67
+
68
+ @network_options[options[:adapter]] = options
69
+ end
70
+
71
+ def shared_folder_uid
72
+ @shared_folder_uid || env.config.ssh.username
73
+ end
74
+
75
+ def shared_folder_gid
76
+ @shared_folder_gid || env.config.ssh.username
77
+ end
78
+
79
+ def customize(&block)
80
+ push_proc(&block)
81
+ end
82
+
83
+ def has_multi_vms?
84
+ !defined_vms.empty?
85
+ end
86
+
87
+ def defined_vms
88
+ @defined_vms ||= {}
89
+ end
90
+
91
+ def define(name, options=nil, &block)
92
+ options ||= {}
93
+ defined_vms[name.to_sym] ||= SubVM.new
94
+ defined_vms[name.to_sym].options.merge!(options)
95
+ defined_vms[name.to_sym].push_proc(&block)
96
+ end
97
+
98
+ def validate(errors)
99
+ shared_folders.each do |name, options|
100
+ if !File.directory?(File.expand_path(options[:hostpath].to_s, env.root_path))
101
+ errors.add(I18n.t("vagrant.config.vm.shared_folder_hostpath_missing",
102
+ :name => name,
103
+ :path => options[:hostpath]))
104
+ end
105
+ end
106
+
107
+ errors.add(I18n.t("vagrant.config.vm.boot_mode_invalid")) if ![:vrdp, :gui].include?(boot_mode.to_sym)
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,68 @@
1
+ module Vagrant
2
+ # The Vagrant data store is a key-value store which is persisted
3
+ # as JSON in a local file which is specified in the initializer.
4
+ # The data store itself is accessed via typical hash accessors: `[]`
5
+ # and `[]=`. If a key is set to `nil`, then it is removed from the
6
+ # datastore. The data store is only updated on disk when {#commit}
7
+ # is called on the data store itself.
8
+ #
9
+ # The data store is a hash with indifferent access, meaning that
10
+ # while all keys are persisted as strings in the JSON, you can access
11
+ # them back as either symbols or strings. Note that this is only true
12
+ # for the top-level data store. As soon as you set a hash inside the
13
+ # data store, unless you explicitly use a {Util::HashWithIndifferentAccess},
14
+ # it will be a regular hash.
15
+ class DataStore < Util::HashWithIndifferentAccess
16
+ attr_reader :file_path
17
+
18
+ def initialize(file_path)
19
+ @file_path = file_path
20
+ return if !file_path
21
+
22
+ File.open(file_path, "r") do |f|
23
+ merge!(JSON.parse(f.read))
24
+ end
25
+ rescue Errno::ENOENT
26
+ clear
27
+ end
28
+
29
+ # Commits any changes to the data to disk. Even if the data
30
+ # hasn't changed, it will be reserialized and written to disk.
31
+ def commit
32
+ return if !file_path
33
+
34
+ clean_nil_and_empties
35
+
36
+ if empty?
37
+ # Delete the file since an empty data store is not useful
38
+ File.delete(file_path) if File.file?(file_path)
39
+ else
40
+ File.open(file_path, "w") { |f| f.write(to_json) }
41
+ end
42
+ end
43
+
44
+ protected
45
+
46
+ # Removes the "nil" and "empty?" values from the hash (children
47
+ # included) so that the final output JSON is cleaner.
48
+ def clean_nil_and_empties(hash=self)
49
+ # Clean depth first
50
+ hash.each do |k, v|
51
+ clean_nil_and_empties(v) if v.is_a?(Hash)
52
+ end
53
+
54
+ # Clean ourselves, knowing that any children have already been
55
+ # cleaned up
56
+ bad_keys = hash.inject([]) do |acc, data|
57
+ k,v = data
58
+ acc.push(k) if v.nil?
59
+ acc.push(k) if v.respond_to?(:empty?) && v.empty?
60
+ acc
61
+ end
62
+
63
+ bad_keys.each do |key|
64
+ hash.delete(key)
65
+ end
66
+ end
67
+ end
68
+ end
@@ -1,3 +1,5 @@
1
+ require 'fileutils'
2
+
1
3
  module Vagrant
2
4
  module Downloaders
3
5
  # "Downloads" a file to a temporary file. Basically, this downloader
@@ -8,9 +10,7 @@ module Vagrant
8
10
  end
9
11
 
10
12
  def prepare(source_url)
11
- if !::File.file?(source_url)
12
- return env.error!(:downloader_file_doesnt_exist, :source_url => source_url)
13
- end
13
+ raise Errors::DownloaderFileDoesntExist.new if !::File.file?(source_url)
14
14
  end
15
15
 
16
16
  def download!(source_url, destination_file)
@@ -15,8 +15,10 @@ module Vagrant
15
15
  end
16
16
 
17
17
  def download!(source_url, destination_file)
18
+ proxy_uri = URI.parse(ENV["http_proxy"] || "")
18
19
  uri = URI.parse(source_url)
19
- http = Net::HTTP.new(uri.host, uri.port)
20
+ http = Net::HTTP.new(uri.host, uri.port, proxy_uri.host, proxy_uri.port, proxy_uri.user, proxy_uri.password)
21
+
20
22
  if uri.scheme == "https"
21
23
  http.use_ssl = true
22
24
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
@@ -36,7 +38,7 @@ module Vagrant
36
38
  # Progress reporting is limited to every 25 segments just so
37
39
  # we're not constantly updating
38
40
  if segment_count % 25 == 0
39
- env.logger.report_progress(progress, total)
41
+ env.ui.report_progress(progress, total)
40
42
  segment_count = 0
41
43
  end
42
44
 
@@ -45,10 +47,8 @@ module Vagrant
45
47
  end
46
48
  end
47
49
  end
48
-
49
- env.logger.clear_progress
50
50
  rescue SocketError
51
- env.error!(:box_download_http_socket_error, :box_url => source_url)
51
+ raise Errors::DownloaderHTTPSocketError.new
52
52
  end
53
53
  end
54
54
  end
@@ -1,109 +1,143 @@
1
+ require 'pathname'
2
+ require 'fileutils'
3
+
1
4
  module Vagrant
2
- # Represents a single Vagrant environment. This class is responsible
3
- # for loading all of the Vagrantfile's for the given environment and
4
- # storing references to the various instances.
5
+ # Represents a single Vagrant environment. A "Vagrant environment" is
6
+ # defined as basically a folder with a "Vagrantfile." This class allows
7
+ # access to the VMs, CLI, etc. all in the scope of this environment.
5
8
  class Environment
6
9
  ROOTFILE_NAME = "Vagrantfile"
7
- HOME_SUBDIRS = ["tmp", "boxes"]
10
+ HOME_SUBDIRS = ["tmp", "boxes", "logs"]
8
11
  DEFAULT_VM = :default
9
12
 
10
- include Util
13
+ # Parent environment (in the case of multi-VMs)
14
+ attr_reader :parent
11
15
 
12
- attr_reader :parent # Parent environment (in the case of multi-VMs)
13
- attr_reader :vm_name # The name of the VM (internal name) which this environment represents
16
+ # The `cwd` that this environment represents
17
+ attr_reader :cwd
14
18
 
15
- attr_accessor :cwd
16
- attr_reader :root_path
17
- attr_reader :config
18
- attr_reader :host
19
- attr_reader :box
19
+ # The single VM that this environment represents, in the case of
20
+ # multi-VM.
20
21
  attr_accessor :vm
21
- attr_reader :vms
22
- attr_reader :active_list
23
- attr_reader :commands
24
- attr_reader :logger
25
- attr_reader :actions
22
+
23
+ # The {UI} object to communicate with the outside world.
24
+ attr_writer :ui
26
25
 
27
26
  #---------------------------------------------------------------
28
27
  # Class Methods
29
28
  #---------------------------------------------------------------
30
29
  class << self
31
- # Loads and returns an environment given a specific working
32
- # directory. If a working directory is not given, it will default
33
- # to the pwd.
34
- def load!(cwd=nil)
35
- Environment.new(:cwd => cwd).load!
36
- end
37
-
38
30
  # Verifies that VirtualBox is installed and that the version of
39
- # VirtualBox installed is high enough. Also verifies that the
40
- # configuration path is properly set.
31
+ # VirtualBox installed is high enough.
41
32
  def check_virtualbox!
42
33
  version = VirtualBox.version
43
- if version.nil?
44
- error_and_exit(:virtualbox_not_detected)
45
- elsif version.to_f < 3.2
46
- error_and_exit(:virtualbox_invalid_version, :version => version.to_s)
47
- elsif version.to_s.downcase.include?("ose")
48
- error_and_exit(:virtualbox_invalid_ose, :version => version.to_s)
49
- end
34
+ raise Errors::VirtualBoxNotDetected.new if version.nil?
35
+ raise Errors::VirtualBoxInvalidVersion.new(:version => version.to_s) if version.to_f < 3.2
36
+ raise Errors::VirtualBoxInvalidOSE.new(:version => version.to_s) if version.to_s.downcase.include?("ose")
50
37
  end
51
38
  end
52
39
 
40
+ # Initializes a new environment with the given options. The options
41
+ # is a hash where the main available key is `cwd`, which defines where
42
+ # the environment represents. There are other options available but
43
+ # they shouldn't be used in general. If `cwd` is nil, then it defaults
44
+ # to the `Dir.pwd` (which is the cwd of the executing process).
53
45
  def initialize(opts=nil)
54
- defaults = {
46
+ opts = {
55
47
  :parent => nil,
56
- :vm_name => nil,
57
48
  :vm => nil,
58
- :cwd => nil
59
- }
49
+ :cwd => nil,
50
+ }.merge(opts || {})
60
51
 
61
- opts = defaults.merge(opts || {})
52
+ opts[:cwd] ||= Dir.pwd
53
+ opts[:cwd] = Pathname.new(opts[:cwd])
62
54
 
63
- defaults.each do |key, value|
55
+ opts.each do |key, value|
64
56
  instance_variable_set("@#{key}".to_sym, opts[key])
65
57
  end
58
+
59
+ @loaded = false
66
60
  end
67
61
 
68
62
  #---------------------------------------------------------------
69
63
  # Helpers
70
64
  #---------------------------------------------------------------
71
65
 
72
- # Specifies the "current working directory" for this environment.
73
- # This is vital in determining the root path and therefore the
74
- # dotfile, rootpath vagrantfile, etc. This defaults to the
75
- # actual cwd (`Dir.pwd`).
76
- def cwd
77
- @cwd || Dir.pwd
78
- end
79
-
80
66
  # The path to the `dotfile`, which contains the persisted UUID of
81
67
  # the VM if it exists.
68
+ #
69
+ # @return [Pathname]
82
70
  def dotfile_path
83
- root_path ? File.join(root_path, config.vagrant.dotfile_name) : nil
71
+ root_path.join(config.vagrant.dotfile_name) rescue nil
84
72
  end
85
73
 
86
- # The path to the home directory, which is usually in `~/.vagrant/~
74
+ # The path to the home directory, expanded relative to the root path,
75
+ # and converted into a Pathname object.
76
+ #
77
+ # @return [Pathname]
87
78
  def home_path
88
- config ? config.vagrant.home : nil
79
+ @_home_path ||= Pathname.new(File.expand_path(config.vagrant.home, root_path))
89
80
  end
90
81
 
91
82
  # The path to the Vagrant tmp directory
83
+ #
84
+ # @return [Pathname]
92
85
  def tmp_path
93
- File.join(home_path, "tmp")
86
+ home_path.join("tmp")
94
87
  end
95
88
 
96
89
  # The path to the Vagrant boxes directory
90
+ #
91
+ # @return [Pathname]
97
92
  def boxes_path
98
- File.join(home_path, "boxes")
93
+ home_path.join("boxes")
94
+ end
95
+
96
+ # Path to the Vagrant logs directory
97
+ #
98
+ # @return [Pathname]
99
+ def log_path
100
+ home_path.join("logs")
101
+ end
102
+
103
+ # Returns the name of the resource which this environment represents.
104
+ # The resource is the VM name if there is a VM it represents, otherwise
105
+ # it defaults to "vagrant"
106
+ #
107
+ # @return [String]
108
+ def resource
109
+ vm.name rescue "vagrant"
110
+ end
111
+
112
+ # Returns the collection of boxes for the environment.
113
+ #
114
+ # @return [BoxCollection]
115
+ def boxes
116
+ return parent.boxes if parent
117
+ @_boxes ||= BoxCollection.new(self)
118
+ end
119
+
120
+ # Returns the box that this environment represents.
121
+ #
122
+ # @return [Box]
123
+ def box
124
+ boxes.find(config.vm.box)
99
125
  end
100
126
 
101
127
  # Returns the VMs associated with this environment.
128
+ #
129
+ # @return [Array<VM>]
102
130
  def vms
103
- @vms ||= {}
131
+ return parent.vms if parent
132
+ load! if !loaded?
133
+ @vms ||= load_vms!
104
134
  end
105
135
 
106
- # Returns the primray VM associated with this environment
136
+ # Returns the primary VM associated with this environment. This
137
+ # method is only applicable for multi-VM environments. This can
138
+ # potentially be nil if no primary VM is specified.
139
+ #
140
+ # @return [VM]
107
141
  def primary_vm
108
142
  return vms.values.first if !multivm?
109
143
  return parent.primary_vm if parent
@@ -118,6 +152,8 @@ module Vagrant
118
152
  # Returns a boolean whether this environment represents a multi-VM
119
153
  # environment or not. This will work even when called on child
120
154
  # environments.
155
+ #
156
+ # @return [Bool]
121
157
  def multivm?
122
158
  if parent
123
159
  parent.multivm?
@@ -126,237 +162,204 @@ module Vagrant
126
162
  end
127
163
  end
128
164
 
165
+ # Makes a call to the CLI with the given arguments as if they
166
+ # came from the real command line (sometimes they do!). An example:
167
+ #
168
+ # env.cli("package", "--vagrantfile", "Vagrantfile")
169
+ #
170
+ def cli(*args)
171
+ CLI.start(args.flatten, :env => self)
172
+ end
173
+
174
+ # Returns the {UI} for the environment, which is responsible
175
+ # for talking with the outside world.
176
+ #
177
+ # @return [UI]
178
+ def ui
179
+ @ui ||= if parent
180
+ result = parent.ui.clone
181
+ result.env = self
182
+ result
183
+ else
184
+ UI.new(self)
185
+ end
186
+ end
187
+
188
+ # Returns the host object associated with this environment.
189
+ #
190
+ # @return [Hosts::Base]
191
+ def host
192
+ @host ||= Hosts::Base.load(self, config.vagrant.host)
193
+ end
194
+
195
+ # Returns the {Action} class for this environment which allows actions
196
+ # to be executed (middleware chains) in the context of this environment.
197
+ #
198
+ # @return [Action]
199
+ def actions
200
+ @actions ||= Action.new(self)
201
+ end
202
+
203
+ # Loads on initial access and reads data from the global data store.
204
+ # The global data store is global to Vagrant everywhere (in every environment),
205
+ # so it can be used to store system-wide information. Note that "system-wide"
206
+ # typically means "for this user" since the location of the global data
207
+ # store is in the home directory.
208
+ #
209
+ # @return [DataStore]
210
+ def global_data
211
+ return parent.global_data if parent
212
+ @global_data ||= DataStore.new(File.expand_path("global_data.json", home_path))
213
+ end
214
+
215
+ # Loads (on initial access) and reads data from the local data
216
+ # store. This file is always at the root path as the file "~/.vagrant"
217
+ # and contains a JSON dump of a hash. See {DataStore} for more
218
+ # information.
219
+ #
220
+ # @return [DataStore]
221
+ def local_data
222
+ return parent.local_data if parent
223
+ @local_data ||= DataStore.new(dotfile_path)
224
+ end
225
+
226
+ # Accesses the logger for Vagrant. This logger is a _detailed_
227
+ # logger which should be used to log internals only. For outward
228
+ # facing information, use {#ui}.
229
+ #
230
+ # @return [Logger]
231
+ def logger
232
+ return parent.logger if parent
233
+ @logger ||= Util::ResourceLogger.new(resource, self)
234
+ end
235
+
236
+ # The root path is the path where the top-most (loaded last)
237
+ # Vagrantfile resides. It can be considered the project root for
238
+ # this environment.
239
+ #
240
+ # @return [String]
241
+ def root_path
242
+ return @root_path if defined?(@root_path)
243
+
244
+ root_finder = lambda do |path|
245
+ return path if File.exist?(File.join(path.to_s, ROOTFILE_NAME))
246
+ return nil if path.root?
247
+ root_finder.call(path.parent)
248
+ end
249
+
250
+ @root_path = root_finder.call(cwd)
251
+ end
252
+
253
+ #---------------------------------------------------------------
254
+ # Config Methods
255
+ #---------------------------------------------------------------
256
+
257
+ # The configuration object represented by this environment. This
258
+ # will trigger the environment to load if it hasn't loaded yet (see
259
+ # {#load!}).
260
+ #
261
+ # @return [Config::Top]
262
+ def config
263
+ load! if !loaded?
264
+ @config
265
+ end
266
+
129
267
  #---------------------------------------------------------------
130
268
  # Load Methods
131
269
  #---------------------------------------------------------------
132
270
 
271
+ # Returns a boolean representing if the environment has been
272
+ # loaded or not.
273
+ #
274
+ # @return [Bool]
275
+ def loaded?
276
+ !!@loaded
277
+ end
278
+
133
279
  # Loads this entire environment, setting up the instance variables
134
280
  # such as `vm`, `config`, etc. on this environment. The order this
135
281
  # method calls its other methods is very particular.
136
282
  def load!
137
- load_logger!
138
- load_root_path!
139
- load_config!
140
- load_home_directory!
141
- load_host!
142
- load_box!
143
- load_config!
144
- self.class.check_virtualbox!
145
- load_vm!
146
- load_active_list!
147
- load_commands!
148
- load_actions!
149
- self
150
- end
151
-
152
- # Loads the root path of this environment, given the starting
153
- # directory (the "cwd" of this environment for lack of better words).
154
- # This method allows an environment in `/foo` to be detected from
155
- # `/foo/bar` (similar to how git works in subdirectories)
156
- def load_root_path!(path=nil)
157
- path = Pathname.new(File.expand_path(path || cwd))
158
-
159
- # Stop if we're at the root.
160
- return false if path.root?
161
-
162
- file = "#{path}/#{ROOTFILE_NAME}"
163
- if File.exist?(file)
164
- @root_path = path.to_s
165
- return true
283
+ if !loaded?
284
+ @loaded = true
285
+ self.class.check_virtualbox!
286
+ load_config!
287
+ actions.run(:environment_load)
166
288
  end
167
289
 
168
- load_root_path!(path.parent)
290
+ self
169
291
  end
170
292
 
171
- # Loads this environment's configuration and stores it in the {config}
293
+ # Loads this environment's configuration and stores it in the {#config}
172
294
  # variable. The configuration loaded by this method is specified to
173
295
  # this environment, meaning that it will use the given root directory
174
296
  # to load the Vagrantfile into that context.
175
297
  def load_config!
176
- # Prepare load paths for config files and append to config queue
177
- config_queue = [File.join(PROJECT_ROOT, "config", "default.rb")]
178
- config_queue << File.join(box.directory, ROOTFILE_NAME) if box
179
- config_queue << File.join(home_path, ROOTFILE_NAME) if home_path
180
- config_queue << File.join(root_path, ROOTFILE_NAME) if root_path
181
-
182
- # If this environment represents some VM in a multi-VM environment,
183
- # we push that VM's configuration onto the config_queue.
184
- if vm_name
185
- subvm = parent.config.vm.defined_vms[vm_name]
186
- config_queue << subvm.proc_stack if subvm
298
+ first_run = @config.nil?
299
+
300
+ # First load the initial, non config-dependent Vagrantfiles
301
+ loader = Config.new(self)
302
+ loader.queue << File.expand_path("config/default.rb", Vagrant.source_root)
303
+ loader.queue << File.join(box.directory, ROOTFILE_NAME) if !first_run && box
304
+ loader.queue << File.join(home_path, ROOTFILE_NAME) if !first_run && home_path
305
+ loader.queue << File.join(root_path, ROOTFILE_NAME) if root_path
306
+
307
+ # If this environment is representing a sub-VM, then we push that
308
+ # proc on as the last configuration.
309
+ if !first_run && vm
310
+ subvm = parent.config.vm.defined_vms[vm.name]
311
+ loader.queue << subvm.proc_stack if subvm
187
312
  end
188
313
 
189
- # Flatten the config queue so any nested procs are flattened
190
- config_queue.flatten!
191
-
192
- # Clear out the old data
193
- Config.reset!(self)
194
-
195
- # Load each of the config files in order
196
- config_queue.each do |item|
197
- if item.is_a?(String) && File.exist?(item)
198
- load item
199
- next
200
- end
201
-
202
- if item.is_a?(Proc)
203
- # Just push the proc straight onto the config runnable stack
204
- Config.run(&item)
205
- end
206
- end
207
-
208
- # Execute the configuration stack and store the result
209
- @config = Config.execute!
314
+ # Execute the configuration stack and store the result as the final
315
+ # value in the config ivar.
316
+ @config = loader.load!
210
317
 
211
318
  # (re)load the logger
212
- load_logger!
213
- end
319
+ @logger = nil
214
320
 
215
- # Loads the logger for this environment. This is called by
216
- # {#load_config!} so that the logger is only loaded after
217
- # configuration information is available. The logger is also
218
- # loaded early on in the load chain process so that the various
219
- # references to logger won't throw nil exceptions, but by default
220
- # the logger will just send the log data to a black hole.
221
- def load_logger!
222
- resource = vm_name || "vagrant"
223
- @logger = Util::ResourceLogger.new(resource, self)
321
+ if first_run
322
+ # After the first run we want to load the configuration again since
323
+ # it can change due to box Vagrantfiles and home directory Vagrantfiles
324
+ load_home_directory!
325
+ load_config!
326
+ end
224
327
  end
225
328
 
226
329
  # Loads the home directory path and creates the necessary subdirectories
227
330
  # within the home directory if they're not already created.
228
331
  def load_home_directory!
229
332
  # Setup the array of necessary home directories
230
- dirs = HOME_SUBDIRS.collect { |subdir| File.join(home_path, subdir) }
231
- dirs.unshift(home_path)
333
+ dirs = [home_path]
334
+ dirs += HOME_SUBDIRS.collect { |subdir| home_path.join(subdir) }
232
335
 
233
336
  # Go through each required directory, creating it if it doesn't exist
234
337
  dirs.each do |dir|
235
338
  next if File.directory?(dir)
236
339
 
237
- logger.info "Creating home directory since it doesn't exist: #{dir}"
340
+ ui.info I18n.t("vagrant.general.creating_home_dir", :directory => dir)
238
341
  FileUtils.mkdir_p(dir)
239
342
  end
240
343
  end
241
344
 
242
- # Loads the host class for this environment.
243
- def load_host!
244
- @host = Hosts::Base.load(self, config.vagrant.host)
245
- end
246
-
247
- # Loads the specified box for this environment.
248
- def load_box!
249
- return unless root_path
250
-
251
- @box = Box.find(self, config.vm.box) if config.vm.box
252
- end
253
-
254
345
  # Loads the persisted VM (if it exists) for this environment.
255
- def load_vm!
256
- # This environment represents a single sub VM. The VM is then
257
- # probably (read: should be) set on the VM attribute, so we do
258
- # nothing.
259
- return if vm_name
260
-
261
- # First load the defaults (blank, noncreated VMs)
262
- load_blank_vms!
263
-
264
- # If we have no dotfile, then return
265
- return if !dotfile_path || !File.file?(dotfile_path)
266
-
267
- # Open and parse the dotfile
268
- File.open(dotfile_path) do |f|
269
- data = { DEFAULT_VM => f.read }
270
-
271
- begin
272
- data = JSON.parse(data[DEFAULT_VM])
273
- rescue JSON::ParserError
274
- # Most likely an older (<= 0.3.x) dotfile. Try to load it
275
- # as the :__vagrant VM.
276
- end
277
-
278
- data.each do |key, value|
279
- key = key.to_sym
280
- vms[key] = Vagrant::VM.find(value, self, key)
281
- end
282
- end
283
- rescue Errno::ENOENT
284
- # Just rescue it.
285
- end
286
-
287
- # Loads blank VMs into the `vms` attribute.
288
- def load_blank_vms!
289
- # Clear existing vms
290
- vms.clear
291
-
292
- # Load up the blank VMs
293
- defined_vms = config.vm.defined_vms.keys
294
- defined_vms = [DEFAULT_VM] if defined_vms.empty?
295
-
296
- defined_vms.each do |name|
297
- vms[name] = Vagrant::VM.new(:vm_name => name, :env => self)
298
- end
299
- end
300
-
301
- # Loads the activelist for this environment
302
- def load_active_list!
303
- @active_list = ActiveList.new(self)
304
- end
305
-
306
- # Loads the instance of {Command} for this environment. This allows
307
- # users of the instance to run commands such as "up" "down" etc. in
308
- # the context of this environment.
309
- def load_commands!
310
- @commands = Command.new(self)
311
- end
312
-
313
- # Loads the instance of {Action} for this environment. This allows
314
- # users of the instance to run action sequences in the context of
315
- # this environment.
316
- def load_actions!
317
- @actions = Action.new(self)
318
- end
319
-
320
- #---------------------------------------------------------------
321
- # Methods to manage VM
322
- #---------------------------------------------------------------
323
-
324
- # Persists this environment's VM to the dotfile so it can be
325
- # re-loaded at a later time.
326
- def update_dotfile
327
- return parent.update_dotfile if parent
346
+ def load_vms!
347
+ result = {}
328
348
 
329
- # Generate and save the persisted VM info
330
- data = vms.inject({}) do |acc, data|
331
- key, value = data
332
- acc[key] = value.uuid if value.created?
333
- acc
349
+ # Load the VM UUIDs from the local data store
350
+ (local_data[:active] || {}).each do |name, uuid|
351
+ result[name.to_sym] = Vagrant::VM.find(uuid, self, name.to_sym)
334
352
  end
335
353
 
336
- if data.empty?
337
- File.delete(dotfile_path) if File.exist?(dotfile_path)
338
- else
339
- File.open(dotfile_path, 'w+') do |f|
340
- f.write(data.to_json)
341
- end
354
+ # For any VMs which aren't created, create a blank VM instance for
355
+ # them
356
+ all_keys = config.vm.defined_vms.keys
357
+ all_keys = [DEFAULT_VM] if all_keys.empty?
358
+ all_keys.each do |name|
359
+ result[name] = Vagrant::VM.new(:name => name, :env => self) if !result.has_key?(name)
342
360
  end
343
361
 
344
- # Also add to the global store
345
- # active_list.add(vm)
346
- end
347
-
348
- #---------------------------------------------------------------
349
- # Methods to check for properties and error
350
- #---------------------------------------------------------------
351
-
352
- def require_root_path
353
- error_and_exit(:rootfile_not_found) if !root_path
354
- end
355
-
356
- def require_persisted_vm
357
- require_root_path
358
-
359
- error_and_exit(:environment_not_created) if !vm
362
+ result
360
363
  end
361
364
  end
362
365
  end