vagrant 0.5.4 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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