vagrant 0.8.10 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (324) hide show
  1. data/CHANGELOG.md +77 -1
  2. data/Gemfile +0 -14
  3. data/LICENSE +1 -1
  4. data/bin/vagrant +47 -20
  5. data/config/default.rb +6 -14
  6. data/lib/vagrant.rb +132 -5
  7. data/lib/vagrant/action.rb +45 -123
  8. data/lib/vagrant/action/box/destroy.rb +7 -3
  9. data/lib/vagrant/action/box/download.rb +8 -8
  10. data/lib/vagrant/action/box/package.rb +2 -2
  11. data/lib/vagrant/action/box/unpackage.rb +13 -7
  12. data/lib/vagrant/action/box/verify.rb +5 -5
  13. data/lib/vagrant/action/builder.rb +23 -19
  14. data/lib/vagrant/action/builtin.rb +117 -79
  15. data/lib/vagrant/action/env/set.rb +7 -4
  16. data/lib/vagrant/action/environment.rb +3 -41
  17. data/lib/vagrant/action/general/package.rb +14 -29
  18. data/lib/vagrant/action/general/validate.rb +2 -2
  19. data/lib/vagrant/action/runner.rb +53 -0
  20. data/lib/vagrant/action/vm/boot.rb +9 -9
  21. data/lib/vagrant/action/vm/check_accessible.rb +2 -2
  22. data/lib/vagrant/action/vm/check_box.rb +10 -12
  23. data/lib/vagrant/action/vm/check_guest_additions.rb +8 -8
  24. data/lib/vagrant/action/vm/check_port_collisions.rb +85 -0
  25. data/lib/vagrant/action/vm/clean_machine_folder.rb +4 -4
  26. data/lib/vagrant/action/vm/clear_forwarded_ports.rb +3 -11
  27. data/lib/vagrant/action/vm/clear_network_interfaces.rb +31 -0
  28. data/lib/vagrant/action/vm/clear_shared_folders.rb +2 -11
  29. data/lib/vagrant/action/vm/customize.rb +19 -9
  30. data/lib/vagrant/action/vm/destroy.rb +4 -4
  31. data/lib/vagrant/action/vm/destroy_unused_network_interfaces.rb +2 -12
  32. data/lib/vagrant/action/vm/discard_state.rb +4 -4
  33. data/lib/vagrant/action/vm/export.rb +13 -8
  34. data/lib/vagrant/action/vm/forward_ports.rb +55 -102
  35. data/lib/vagrant/action/vm/halt.rb +9 -6
  36. data/lib/vagrant/action/vm/host_name.rb +4 -4
  37. data/lib/vagrant/action/vm/import.rb +19 -10
  38. data/lib/vagrant/action/vm/match_mac_address.rb +4 -9
  39. data/lib/vagrant/action/vm/network.rb +300 -94
  40. data/lib/vagrant/action/vm/nfs.rb +41 -26
  41. data/lib/vagrant/action/vm/package.rb +1 -1
  42. data/lib/vagrant/action/vm/package_vagrantfile.rb +5 -2
  43. data/lib/vagrant/action/vm/provision.rb +42 -13
  44. data/lib/vagrant/action/vm/provisioner_cleanup.rb +2 -2
  45. data/lib/vagrant/action/vm/{clear_nfs_exports.rb → prune_nfs_exports.rb} +7 -7
  46. data/lib/vagrant/action/vm/resume.rb +4 -4
  47. data/lib/vagrant/action/vm/setup_package_files.rb +54 -0
  48. data/lib/vagrant/action/vm/share_folders.rb +63 -39
  49. data/lib/vagrant/action/vm/suspend.rb +4 -4
  50. data/lib/vagrant/action/warden.rb +13 -6
  51. data/lib/vagrant/box.rb +9 -55
  52. data/lib/vagrant/box_collection.rb +22 -17
  53. data/lib/vagrant/cli.rb +62 -47
  54. data/lib/vagrant/command.rb +18 -20
  55. data/lib/vagrant/command/base.rb +135 -90
  56. data/lib/vagrant/command/box.rb +46 -21
  57. data/lib/vagrant/command/box_add.rb +33 -0
  58. data/lib/vagrant/command/box_list.rb +25 -0
  59. data/lib/vagrant/command/box_remove.rb +23 -0
  60. data/lib/vagrant/command/box_repackage.rb +23 -0
  61. data/lib/vagrant/command/destroy.rb +16 -5
  62. data/lib/vagrant/command/halt.rb +25 -7
  63. data/lib/vagrant/command/init.rb +30 -7
  64. data/lib/vagrant/command/package.rb +49 -18
  65. data/lib/vagrant/command/provision.rb +22 -9
  66. data/lib/vagrant/command/reload.rb +18 -5
  67. data/lib/vagrant/command/resume.rb +18 -5
  68. data/lib/vagrant/command/ssh.rb +69 -31
  69. data/lib/vagrant/command/ssh_config.rb +37 -22
  70. data/lib/vagrant/command/status.rb +22 -20
  71. data/lib/vagrant/command/suspend.rb +18 -5
  72. data/lib/vagrant/command/up.rb +41 -8
  73. data/lib/vagrant/communication.rb +7 -0
  74. data/lib/vagrant/communication/base.rb +56 -0
  75. data/lib/vagrant/communication/ssh.rb +200 -0
  76. data/lib/vagrant/config.rb +29 -103
  77. data/lib/vagrant/config/base.rb +18 -26
  78. data/lib/vagrant/config/container.rb +37 -0
  79. data/lib/vagrant/config/error_recorder.rb +1 -1
  80. data/lib/vagrant/config/loader.rb +125 -0
  81. data/lib/vagrant/config/nfs.rb +1 -3
  82. data/lib/vagrant/config/package.rb +1 -3
  83. data/lib/vagrant/config/ssh.rb +31 -16
  84. data/lib/vagrant/config/top.rb +36 -25
  85. data/lib/vagrant/config/vagrant.rb +2 -5
  86. data/lib/vagrant/config/vm.rb +115 -56
  87. data/lib/vagrant/config/vm/provisioner.rb +16 -20
  88. data/lib/vagrant/config/vm/sub_vm.rb +1 -1
  89. data/lib/vagrant/data_store.rb +23 -15
  90. data/lib/vagrant/downloaders/base.rb +7 -5
  91. data/lib/vagrant/downloaders/file.rb +4 -4
  92. data/lib/vagrant/downloaders/http.rb +4 -5
  93. data/lib/vagrant/driver.rb +7 -0
  94. data/lib/vagrant/driver/virtualbox.rb +121 -0
  95. data/lib/vagrant/driver/virtualbox_4_0.rb +411 -0
  96. data/lib/vagrant/driver/virtualbox_4_1.rb +411 -0
  97. data/lib/vagrant/driver/virtualbox_base.rb +284 -0
  98. data/lib/vagrant/environment.rb +221 -240
  99. data/lib/vagrant/errors.rb +74 -25
  100. data/lib/vagrant/guest.rb +16 -0
  101. data/lib/vagrant/guest/arch.rb +48 -0
  102. data/lib/vagrant/{systems → guest}/base.rb +30 -18
  103. data/lib/vagrant/guest/debian.rb +61 -0
  104. data/lib/vagrant/{systems → guest}/freebsd.rb +11 -18
  105. data/lib/vagrant/guest/gentoo.rb +32 -0
  106. data/lib/vagrant/guest/linux.rb +78 -0
  107. data/lib/vagrant/{systems → guest}/linux/config.rb +2 -4
  108. data/lib/vagrant/guest/linux/error.rb +9 -0
  109. data/lib/vagrant/guest/redhat.rb +66 -0
  110. data/lib/vagrant/guest/solaris.rb +114 -0
  111. data/lib/vagrant/{systems → guest}/suse.rb +2 -2
  112. data/lib/vagrant/guest/ubuntu.rb +23 -0
  113. data/lib/vagrant/hosts.rb +23 -6
  114. data/lib/vagrant/hosts/arch.rb +7 -3
  115. data/lib/vagrant/hosts/base.rb +36 -46
  116. data/lib/vagrant/hosts/bsd.rb +53 -16
  117. data/lib/vagrant/hosts/fedora.rb +14 -0
  118. data/lib/vagrant/hosts/freebsd.rb +6 -36
  119. data/lib/vagrant/hosts/linux.rb +45 -20
  120. data/lib/vagrant/hosts/windows.rb +16 -0
  121. data/lib/vagrant/provisioners.rb +10 -7
  122. data/lib/vagrant/provisioners/base.rb +11 -34
  123. data/lib/vagrant/provisioners/chef.rb +30 -26
  124. data/lib/vagrant/provisioners/chef_client.rb +37 -23
  125. data/lib/vagrant/provisioners/chef_solo.rb +61 -16
  126. data/lib/vagrant/provisioners/puppet.rb +70 -38
  127. data/lib/vagrant/provisioners/puppet_server.rb +12 -13
  128. data/lib/vagrant/provisioners/shell.rb +24 -24
  129. data/lib/vagrant/registry.rb +49 -0
  130. data/lib/vagrant/ssh.rb +82 -153
  131. data/lib/vagrant/ui.rb +118 -50
  132. data/lib/vagrant/util/busy.rb +1 -1
  133. data/lib/vagrant/util/file_mode.rb +12 -0
  134. data/lib/vagrant/util/network_ip.rb +28 -0
  135. data/lib/vagrant/util/platform.rb +1 -0
  136. data/lib/vagrant/util/subprocess.rb +227 -0
  137. data/lib/vagrant/version.rb +1 -1
  138. data/lib/vagrant/vm.rb +111 -97
  139. data/tasks/acceptance.rake +3 -3
  140. data/tasks/test.rake +7 -2
  141. data/templates/commands/init/Vagrantfile.erb +11 -4
  142. data/templates/{ssh_config.erb → commands/ssh_config/config.erb} +0 -0
  143. data/templates/guests/arch/network_dhcp.erb +7 -0
  144. data/templates/guests/arch/network_static.erb +7 -0
  145. data/templates/guests/debian/network_dhcp.erb +6 -0
  146. data/templates/guests/debian/network_static.erb +7 -0
  147. data/templates/guests/gentoo/network_dhcp.erb +4 -0
  148. data/templates/guests/gentoo/network_static.erb +4 -0
  149. data/templates/guests/redhat/network_dhcp.erb +6 -0
  150. data/templates/guests/redhat/network_static.erb +7 -0
  151. data/templates/locales/en.yml +241 -122
  152. data/templates/{chef_server_client.erb → provisioners/chef_client/client.erb} +0 -0
  153. data/templates/{chef_solo_solo.erb → provisioners/chef_solo/solo.erb} +0 -0
  154. data/test/acceptance/base.rb +10 -10
  155. data/test/acceptance/box_test.rb +28 -6
  156. data/test/acceptance/destroy_test.rb +1 -1
  157. data/test/acceptance/halt_test.rb +4 -4
  158. data/test/acceptance/init_test.rb +3 -3
  159. data/test/acceptance/networking/host_only_test.rb +37 -0
  160. data/test/acceptance/networking/port_forward_test.rb +125 -0
  161. data/test/acceptance/package_test.rb +46 -0
  162. data/test/acceptance/provisioning/basic_test.rb +61 -0
  163. data/test/acceptance/provisioning/chef_solo_test.rb +37 -0
  164. data/test/acceptance/provisioning/shell_test.rb +53 -0
  165. data/test/acceptance/resume_test.rb +1 -1
  166. data/test/acceptance/skeletons/chef_solo_basic/README.md +3 -0
  167. data/test/acceptance/skeletons/chef_solo_basic/cookbooks/basic/recipes/default.rb +5 -0
  168. data/test/acceptance/skeletons/chef_solo_json/README.md +3 -0
  169. data/test/acceptance/skeletons/chef_solo_json/cookbooks/basic/recipes/default.rb +6 -0
  170. data/test/acceptance/skeletons/provisioner_multi/README.md +3 -0
  171. data/test/acceptance/skeletons/provisioner_multi/cookbooks/basic/recipes/default.rb +5 -0
  172. data/test/acceptance/ssh_test.rb +7 -2
  173. data/test/acceptance/support/config.rb +1 -1
  174. data/test/acceptance/support/isolated_environment.rb +41 -150
  175. data/test/acceptance/support/matchers/match_output.rb +1 -1
  176. data/test/acceptance/support/matchers/succeed.rb +14 -0
  177. data/test/acceptance/support/network_tests.rb +29 -0
  178. data/test/acceptance/support/output.rb +9 -1
  179. data/test/acceptance/support/shared/base_context.rb +16 -9
  180. data/test/acceptance/support/shared/command_examples.rb +4 -4
  181. data/test/acceptance/suspend_test.rb +1 -1
  182. data/test/acceptance/up_basic_test.rb +26 -7
  183. data/test/acceptance/up_with_box_url.rb +1 -1
  184. data/test/acceptance/vagrant_test.rb +1 -1
  185. data/test/acceptance/version_test.rb +0 -5
  186. data/test/support/isolated_environment.rb +46 -0
  187. data/test/{acceptance/support → support}/tempdir.rb +0 -0
  188. data/test/unit/base.rb +21 -0
  189. data/test/unit/support/isolated_environment.rb +39 -0
  190. data/test/unit/support/shared/base_context.rb +30 -0
  191. data/test/unit/vagrant/action/builder_test.rb +126 -177
  192. data/test/unit/vagrant/action/environment_test.rb +10 -21
  193. data/test/unit/vagrant/action/runner_test.rb +65 -0
  194. data/test/unit/vagrant/action/warden_test.rb +64 -97
  195. data/test/unit/vagrant/box_collection_test.rb +44 -33
  196. data/test/unit/vagrant/box_test.rb +25 -65
  197. data/test/unit/vagrant/command/base_test.rb +141 -14
  198. data/test/unit/vagrant/config/base_test.rb +16 -43
  199. data/test/unit/vagrant/config/loader_test.rb +79 -0
  200. data/test/unit/vagrant/config/top_test.rb +69 -0
  201. data/test/unit/vagrant/config/vm_test.rb +62 -47
  202. data/test/unit/vagrant/config_test.rb +16 -151
  203. data/test/unit/vagrant/data_store_test.rb +43 -61
  204. data/test/unit/vagrant/downloaders/base_test.rb +12 -22
  205. data/test/unit/vagrant/downloaders/file_test.rb +58 -31
  206. data/test/unit/vagrant/downloaders/http_test.rb +12 -86
  207. data/test/unit/vagrant/environment_test.rb +107 -536
  208. data/test/unit/vagrant/hosts_test.rb +36 -0
  209. data/test/unit/vagrant/registry_test.rb +56 -0
  210. data/test/unit/vagrant/util/file_checksum_test.rb +23 -0
  211. data/test/unit/vagrant/util/hash_with_indifferent_access_test.rb +23 -24
  212. data/test/unit/vagrant/util/network_ip_test.rb +17 -0
  213. data/test/unit/vagrant/util/retryable_test.rb +90 -34
  214. data/test/unit/vagrant_test.rb +27 -0
  215. data/test/{unit → unit_legacy}/locales/en.yml +0 -0
  216. data/test/{unit → unit_legacy}/test_helper.rb +0 -0
  217. data/test/{unit → unit_legacy}/vagrant/action/box/destroy_test.rb +0 -0
  218. data/test/{unit → unit_legacy}/vagrant/action/box/download_test.rb +0 -0
  219. data/test/{unit → unit_legacy}/vagrant/action/box/package_test.rb +0 -0
  220. data/test/{unit → unit_legacy}/vagrant/action/box/unpackage_test.rb +0 -0
  221. data/test/{unit → unit_legacy}/vagrant/action/box/verify_test.rb +0 -0
  222. data/test/{unit → unit_legacy}/vagrant/action/env/set_test.rb +0 -0
  223. data/test/{unit → unit_legacy}/vagrant/action/general/package_test.rb +0 -0
  224. data/test/{unit → unit_legacy}/vagrant/action/general/validate_test.rb +0 -0
  225. data/test/{unit → unit_legacy}/vagrant/action/vm/boot_test.rb +0 -0
  226. data/test/{unit → unit_legacy}/vagrant/action/vm/check_accessible_test.rb +0 -0
  227. data/test/{unit → unit_legacy}/vagrant/action/vm/check_box_test.rb +0 -0
  228. data/test/{unit → unit_legacy}/vagrant/action/vm/check_guest_additions_test.rb +0 -0
  229. data/test/{unit → unit_legacy}/vagrant/action/vm/clean_machine_folder_test.rb +0 -0
  230. data/test/{unit → unit_legacy}/vagrant/action/vm/clear_forwarded_ports_test.rb +0 -0
  231. data/test/{unit → unit_legacy}/vagrant/action/vm/clear_nfs_exports_test.rb +0 -0
  232. data/test/{unit → unit_legacy}/vagrant/action/vm/clear_shared_folders_test.rb +0 -0
  233. data/test/{unit → unit_legacy}/vagrant/action/vm/customize_test.rb +0 -0
  234. data/test/{unit → unit_legacy}/vagrant/action/vm/destroy_test.rb +0 -0
  235. data/test/{unit → unit_legacy}/vagrant/action/vm/destroy_unused_network_interfaces_test.rb +0 -0
  236. data/test/{unit → unit_legacy}/vagrant/action/vm/discard_state_test.rb +0 -0
  237. data/test/{unit → unit_legacy}/vagrant/action/vm/export_test.rb +0 -0
  238. data/test/{unit → unit_legacy}/vagrant/action/vm/forward_ports_helpers_test.rb +0 -0
  239. data/test/{unit → unit_legacy}/vagrant/action/vm/forward_ports_test.rb +0 -0
  240. data/test/{unit → unit_legacy}/vagrant/action/vm/halt_test.rb +0 -0
  241. data/test/{unit → unit_legacy}/vagrant/action/vm/host_name_test.rb +0 -0
  242. data/test/{unit → unit_legacy}/vagrant/action/vm/import_test.rb +0 -0
  243. data/test/{unit → unit_legacy}/vagrant/action/vm/match_mac_address_test.rb +0 -0
  244. data/test/{unit → unit_legacy}/vagrant/action/vm/modify_test.rb +0 -0
  245. data/test/{unit → unit_legacy}/vagrant/action/vm/network_test.rb +0 -0
  246. data/test/{unit → unit_legacy}/vagrant/action/vm/nfs_helpers_test.rb +0 -0
  247. data/test/{unit → unit_legacy}/vagrant/action/vm/nfs_test.rb +0 -0
  248. data/test/{unit → unit_legacy}/vagrant/action/vm/package_test.rb +0 -0
  249. data/test/{unit → unit_legacy}/vagrant/action/vm/package_vagrantfile_test.rb +0 -0
  250. data/test/{unit → unit_legacy}/vagrant/action/vm/provision_test.rb +0 -0
  251. data/test/{unit → unit_legacy}/vagrant/action/vm/provisioner_cleanup_test.rb +0 -0
  252. data/test/{unit → unit_legacy}/vagrant/action/vm/resume_test.rb +0 -0
  253. data/test/{unit → unit_legacy}/vagrant/action/vm/share_folders_test.rb +0 -0
  254. data/test/{unit → unit_legacy}/vagrant/action/vm/suspend_test.rb +0 -0
  255. data/test/{unit → unit_legacy}/vagrant/action_test.rb +0 -0
  256. data/test/unit_legacy/vagrant/box_collection_test.rb +45 -0
  257. data/test/unit_legacy/vagrant/box_test.rb +74 -0
  258. data/test/{unit → unit_legacy}/vagrant/cli_test.rb +0 -0
  259. data/test/unit_legacy/vagrant/command/base_test.rb +23 -0
  260. data/test/{unit → unit_legacy}/vagrant/command/group_base_test.rb +0 -0
  261. data/test/{unit → unit_legacy}/vagrant/command/helpers_test.rb +0 -0
  262. data/test/{unit → unit_legacy}/vagrant/command/init_test.rb +0 -0
  263. data/test/{unit → unit_legacy}/vagrant/command/package_test.rb +0 -0
  264. data/test/unit_legacy/vagrant/config/base_test.rb +52 -0
  265. data/test/{unit → unit_legacy}/vagrant/config/error_recorder_test.rb +0 -0
  266. data/test/{unit → unit_legacy}/vagrant/config/ssh_test.rb +0 -0
  267. data/test/{unit → unit_legacy}/vagrant/config/vagrant_test.rb +0 -0
  268. data/test/{unit → unit_legacy}/vagrant/config/vm/provisioner_test.rb +0 -0
  269. data/test/unit_legacy/vagrant/config/vm_test.rb +47 -0
  270. data/test/unit_legacy/vagrant/config_test.rb +148 -0
  271. data/test/unit_legacy/vagrant/downloaders/http_test.rb +93 -0
  272. data/test/unit_legacy/vagrant/environment_test.rb +539 -0
  273. data/test/{unit → unit_legacy}/vagrant/errors_test.rb +0 -0
  274. data/test/{unit → unit_legacy}/vagrant/hosts/base_test.rb +0 -0
  275. data/test/{unit → unit_legacy}/vagrant/hosts/bsd_test.rb +0 -0
  276. data/test/{unit → unit_legacy}/vagrant/hosts/linux_test.rb +0 -0
  277. data/test/{unit → unit_legacy}/vagrant/plugin_test.rb +0 -0
  278. data/test/{unit → unit_legacy}/vagrant/provisioners/base_test.rb +0 -0
  279. data/test/{unit → unit_legacy}/vagrant/provisioners/chef_client_test.rb +0 -0
  280. data/test/{unit → unit_legacy}/vagrant/provisioners/chef_solo_test.rb +0 -0
  281. data/test/{unit → unit_legacy}/vagrant/provisioners/chef_test.rb +0 -0
  282. data/test/{unit → unit_legacy}/vagrant/provisioners/puppet_server_test.rb +0 -0
  283. data/test/{unit → unit_legacy}/vagrant/provisioners/puppet_test.rb +0 -0
  284. data/test/{unit → unit_legacy}/vagrant/provisioners/shell_test.rb +0 -0
  285. data/test/{unit → unit_legacy}/vagrant/ssh/session_test.rb +0 -0
  286. data/test/{unit → unit_legacy}/vagrant/ssh_test.rb +0 -0
  287. data/test/{unit → unit_legacy}/vagrant/systems/base_test.rb +0 -0
  288. data/test/{unit → unit_legacy}/vagrant/systems/linux_test.rb +0 -0
  289. data/test/{unit → unit_legacy}/vagrant/util/busy_test.rb +0 -0
  290. data/test/{unit → unit_legacy}/vagrant/util/counter_test.rb +0 -0
  291. data/test/{unit → unit_legacy}/vagrant/util/platform_test.rb +0 -0
  292. data/test/{unit → unit_legacy}/vagrant/util/stacked_proc_runner_test.rb +0 -0
  293. data/test/{unit → unit_legacy}/vagrant/util/template_renderer_test.rb +0 -0
  294. data/test/{unit → unit_legacy}/vagrant/vm_test.rb +0 -0
  295. data/vagrant.gemspec +7 -9
  296. metadata +214 -216
  297. data/keys/vagrant.ppk +0 -26
  298. data/lib/vagrant/action/box.rb +0 -11
  299. data/lib/vagrant/action/env.rb +0 -7
  300. data/lib/vagrant/action/general.rb +0 -8
  301. data/lib/vagrant/action/vm.rb +0 -34
  302. data/lib/vagrant/action/vm/forward_ports_helpers.rb +0 -28
  303. data/lib/vagrant/action/vm/modify.rb +0 -37
  304. data/lib/vagrant/action/vm/nfs_helpers.rb +0 -11
  305. data/lib/vagrant/command/group_base.rb +0 -107
  306. data/lib/vagrant/command/helpers.rb +0 -33
  307. data/lib/vagrant/command/named_base.rb +0 -14
  308. data/lib/vagrant/command/upgrade_to_060.rb +0 -45
  309. data/lib/vagrant/command/version.rb +0 -13
  310. data/lib/vagrant/ssh/session.rb +0 -136
  311. data/lib/vagrant/systems.rb +0 -13
  312. data/lib/vagrant/systems/arch.rb +0 -34
  313. data/lib/vagrant/systems/debian.rb +0 -36
  314. data/lib/vagrant/systems/gentoo.rb +0 -27
  315. data/lib/vagrant/systems/linux.rb +0 -82
  316. data/lib/vagrant/systems/linux/error.rb +0 -9
  317. data/lib/vagrant/systems/redhat.rb +0 -48
  318. data/lib/vagrant/systems/solaris.rb +0 -113
  319. data/lib/vagrant/systems/ubuntu.rb +0 -17
  320. data/templates/network_entry_arch.erb +0 -9
  321. data/templates/network_entry_debian.erb +0 -8
  322. data/templates/network_entry_gentoo.erb +0 -5
  323. data/templates/network_entry_redhat.erb +0 -9
  324. data/test/unit/vagrant/ui_test.rb +0 -29
@@ -1,55 +1,41 @@
1
1
  require 'pathname'
2
2
  require 'fileutils'
3
- require 'logger'
3
+
4
+ require 'log4r'
5
+
6
+ require 'vagrant/util/file_mode'
7
+ require 'vagrant/util/platform'
4
8
 
5
9
  module Vagrant
6
10
  # Represents a single Vagrant environment. A "Vagrant environment" is
7
11
  # defined as basically a folder with a "Vagrantfile." This class allows
8
12
  # access to the VMs, CLI, etc. all in the scope of this environment.
9
13
  class Environment
10
- HOME_SUBDIRS = ["tmp", "boxes", "logs"]
14
+ HOME_SUBDIRS = ["tmp", "boxes"]
11
15
  DEFAULT_VM = :default
12
16
  DEFAULT_HOME = "~/.vagrant.d"
13
17
 
14
- # Parent environment (in the case of multi-VMs)
15
- attr_reader :parent
16
-
17
18
  # The `cwd` that this environment represents
18
19
  attr_reader :cwd
19
20
 
20
21
  # The valid name for a Vagrantfile for this environment.
21
22
  attr_reader :vagrantfile_name
22
23
 
23
- # The single VM that this environment represents, in the case of
24
- # multi-VM.
25
- attr_accessor :vm
26
-
27
24
  # The {UI} object to communicate with the outside world.
28
- attr_writer :ui
25
+ attr_reader :ui
29
26
 
30
- # The {Config} object representing the Vagrantfile loader
31
- attr_reader :config_loader
27
+ # The directory to the "home" folder that Vagrant will use to store
28
+ # global state.
29
+ attr_reader :home_path
32
30
 
33
- #---------------------------------------------------------------
34
- # Class Methods
35
- #---------------------------------------------------------------
36
- class << self
37
- # Verifies that VirtualBox is installed and that the version of
38
- # VirtualBox installed is high enough.
39
- def check_virtualbox!
40
- version = VirtualBox.version
41
- raise Errors::VirtualBoxNotDetected if version.nil?
42
- raise Errors::VirtualBoxInvalidVersion, :version => version.to_s if version.to_f < 4.1 || version.to_f >= 4.2
43
- rescue Errors::VirtualBoxNotDetected
44
- # On 64-bit Windows, show a special error. This error is a subclass
45
- # of VirtualBoxNotDetected, so libraries which use Vagrant can just
46
- # rescue VirtualBoxNotDetected.
47
- raise Errors::VirtualBoxNotDetected_Win64 if Util::Platform.windows? && Util::Platform.bit64?
48
-
49
- # Otherwise, reraise the old error
50
- raise
51
- end
52
- end
31
+ # The directory where temporary files for Vagrant go.
32
+ attr_reader :tmp_path
33
+
34
+ # The directory where boxes are stored.
35
+ attr_reader :boxes_path
36
+
37
+ # The path to the default private key
38
+ attr_reader :default_private_key_path
53
39
 
54
40
  # Initializes a new environment with the given options. The options
55
41
  # is a hash where the main available key is `cwd`, which defines where
@@ -58,11 +44,11 @@ module Vagrant
58
44
  # to the `Dir.pwd` (which is the cwd of the executing process).
59
45
  def initialize(opts=nil)
60
46
  opts = {
61
- :parent => nil,
62
- :vm => nil,
63
47
  :cwd => nil,
64
48
  :vagrantfile_name => nil,
65
- :lock_path => nil
49
+ :lock_path => nil,
50
+ :ui_class => nil,
51
+ :home_path => nil
66
52
  }.merge(opts || {})
67
53
 
68
54
  # Set the default working directory to look for the vagrantfile
@@ -74,17 +60,30 @@ module Vagrant
74
60
  opts[:vagrantfile_name] ||= ["Vagrantfile", "vagrantfile"]
75
61
  opts[:vagrantfile_name] = [opts[:vagrantfile_name]] if !opts[:vagrantfile_name].is_a?(Array)
76
62
 
77
- opts.each do |key, value|
78
- instance_variable_set("@#{key}".to_sym, opts[key])
79
- end
63
+ # Set instance variables for all the configuration parameters.
64
+ @cwd = opts[:cwd]
65
+ @vagrantfile_name = opts[:vagrantfile_name]
66
+ @lock_path = opts[:lock_path]
67
+ @home_path = opts[:home_path]
68
+
69
+ ui_class = opts[:ui_class] || UI::Silent
70
+ @ui = ui_class.new("vagrant")
80
71
 
81
72
  @loaded = false
82
73
  @lock_acquired = false
83
74
 
84
- logger.info("environment") { "Environment initialized (#{self})" }
85
- logger.info("environment") { " - cwd: #{cwd}" }
86
- logger.info("environment") { " - parent: #{parent}" }
87
- logger.info("environment") { " - vm: #{vm}" }
75
+ @logger = Log4r::Logger.new("vagrant::environment")
76
+ @logger.info("Environment initialized (#{self})")
77
+ @logger.info(" - cwd: #{cwd}")
78
+
79
+ # Setup the home directory
80
+ setup_home_path
81
+ @tmp_path = @home_path.join("tmp")
82
+ @boxes_path = @home_path.join("boxes")
83
+
84
+ # Setup the default private key
85
+ @default_private_key_path = @home_path.join("insecure_private_key")
86
+ copy_insecure_private_key
88
87
  end
89
88
 
90
89
  #---------------------------------------------------------------
@@ -96,93 +95,21 @@ module Vagrant
96
95
  #
97
96
  # @return [Pathname]
98
97
  def dotfile_path
99
- root_path.join(config.vagrant.dotfile_name) rescue nil
100
- end
101
-
102
- # The path to the home directory and converted into a Pathname object.
103
- #
104
- # @return [Pathname]
105
- def home_path
106
- return parent.home_path if parent
107
- return @_home_path if defined?(@_home_path)
108
-
109
- @_home_path ||= Pathname.new(File.expand_path(ENV["VAGRANT_HOME"] || DEFAULT_HOME))
110
- logger.info("environment") { "Home path: #{@_home_path}" }
111
-
112
- # This is the old default that Vagrant used to be put things into
113
- # up until Vagrant 0.8.0. We keep around an automatic migration
114
- # script here in case any old users upgrade.
115
- old_home = File.expand_path("~/.vagrant")
116
- if File.exists?(old_home) && File.directory?(old_home)
117
- logger.info("environment") { "Found both an old and new Vagrantfile. Migration initiated." }
118
-
119
- # We can't migrate if the home directory already exists
120
- if File.exists?(@_home_path)
121
- ui.warn I18n.t("vagrant.general.home_dir_migration_failed",
122
- :old => old_home,
123
- :new => @_home_path.to_s)
124
- else
125
- # If the new home path doesn't exist, simply transition to it
126
- ui.info I18n.t("vagrant.general.moving_home_dir", :directory => @_home_path)
127
- FileUtils.mv(old_home, @_home_path)
128
- end
129
- end
130
-
131
- # Return the home path
132
- @_home_path
133
- end
134
-
135
- # The path to the Vagrant tmp directory
136
- #
137
- # @return [Pathname]
138
- def tmp_path
139
- home_path.join("tmp")
140
- end
141
-
142
- # The path to the Vagrant boxes directory
143
- #
144
- # @return [Pathname]
145
- def boxes_path
146
- home_path.join("boxes")
147
- end
148
-
149
- # Path to the Vagrant logs directory
150
- #
151
- # @return [Pathname]
152
- def log_path
153
- home_path.join("logs")
154
- end
155
-
156
- # Returns the name of the resource which this environment represents.
157
- # The resource is the VM name if there is a VM it represents, otherwise
158
- # it defaults to "vagrant"
159
- #
160
- # @return [String]
161
- def resource
162
- result = vm.name rescue nil
163
- result || "vagrant"
98
+ return nil if !root_path
99
+ root_path.join(config.global.vagrant.dotfile_name)
164
100
  end
165
101
 
166
102
  # Returns the collection of boxes for the environment.
167
103
  #
168
104
  # @return [BoxCollection]
169
105
  def boxes
170
- return parent.boxes if parent
171
- @_boxes ||= BoxCollection.new(self)
172
- end
173
-
174
- # Returns the box that this environment represents.
175
- #
176
- # @return [Box]
177
- def box
178
- boxes.find(config.vm.box)
106
+ @_boxes ||= BoxCollection.new(boxes_path, action_runner)
179
107
  end
180
108
 
181
109
  # Returns the VMs associated with this environment.
182
110
  #
183
111
  # @return [Hash<Symbol,VM>]
184
112
  def vms
185
- return parent.vms if parent
186
113
  load! if !loaded?
187
114
  @vms ||= load_vms!
188
115
  end
@@ -192,7 +119,8 @@ module Vagrant
192
119
  #
193
120
  # @return [Array<VM>]
194
121
  def vms_ordered
195
- @vms_enum ||= config.vm.defined_vm_keys.map { |name| @vms[name] }
122
+ return @vms.values if !multivm?
123
+ @vms_enum ||= config.global.vm.defined_vm_keys.map { |name| @vms[name] }
196
124
  end
197
125
 
198
126
  # Returns the primary VM associated with this environment. This
@@ -202,7 +130,6 @@ module Vagrant
202
130
  # @return [VM]
203
131
  def primary_vm
204
132
  return vms.values.first if !multivm?
205
- return parent.primary_vm if parent
206
133
 
207
134
  config.vm.defined_vms.each do |name, subvm|
208
135
  return vms[name] if subvm.options[:primary]
@@ -217,11 +144,7 @@ module Vagrant
217
144
  #
218
145
  # @return [Bool]
219
146
  def multivm?
220
- if parent
221
- parent.multivm?
222
- else
223
- vms.length > 1 || vms.keys.first != DEFAULT_VM
224
- end
147
+ vms.length > 1 || vms.keys.first != DEFAULT_VM
225
148
  end
226
149
 
227
150
  # Makes a call to the CLI with the given arguments as if they
@@ -230,36 +153,57 @@ module Vagrant
230
153
  # env.cli("package", "--vagrantfile", "Vagrantfile")
231
154
  #
232
155
  def cli(*args)
233
- CLI.start(args.flatten, :env => self)
234
- end
235
-
236
- # Returns the {UI} for the environment, which is responsible
237
- # for talking with the outside world.
238
- #
239
- # @return [UI]
240
- def ui
241
- @ui ||= if parent
242
- result = parent.ui.clone
243
- result.env = self
244
- result
245
- else
246
- UI.new(self)
247
- end
156
+ CLI.new(args.flatten, self).execute
248
157
  end
249
158
 
250
159
  # Returns the host object associated with this environment.
251
160
  #
252
161
  # @return [Hosts::Base]
253
162
  def host
254
- @host ||= Hosts::Base.load(self, config.vagrant.host)
163
+ return @host if defined?(@host)
164
+
165
+ # Attempt to figure out the host class. Note that the order
166
+ # matters here, so please don't touch. Specifically: The symbol
167
+ # check is done after the detect check because the symbol check
168
+ # will return nil, and we don't want to trigger a detect load.
169
+ host_klass = config.global.vagrant.host
170
+ host_klass = Hosts.detect(Vagrant.hosts) if host_klass.nil? || host_klass == :detect
171
+ host_klass = Vagrant.hosts.get(host_klass) if host_klass.is_a?(Symbol)
172
+
173
+ # If no host class is detected, we use the base class.
174
+ host_klass ||= Hosts::Base
175
+
176
+ @host ||= host_klass.new(@ui)
177
+ end
178
+
179
+ # Action runner for executing actions in the context of this environment.
180
+ #
181
+ # @return [Action::Runner]
182
+ def action_runner
183
+ @action_runner ||= Action::Runner.new(action_registry) do
184
+ {
185
+ :action_runner => action_runner,
186
+ :box_collection => boxes,
187
+ :global_config => config.global,
188
+ :host => host,
189
+ :root_path => root_path,
190
+ :tmp_path => tmp_path,
191
+ :ui => @ui
192
+ }
193
+ end
255
194
  end
256
195
 
257
- # Returns the {Action} class for this environment which allows actions
258
- # to be executed (middleware chains) in the context of this environment.
196
+ # Action registry for registering new actions with this environment.
259
197
  #
260
- # @return [Action]
261
- def actions
262
- @actions ||= Action.new(self)
198
+ # @return [Registry]
199
+ def action_registry
200
+ return @action_registry if defined?(@action_registry)
201
+
202
+ # The action registry hasn't been loaded yet, so load it
203
+ # and setup the built-in actions with it.
204
+ @action_registry = Registry.new
205
+ Vagrant::Action.builtin!(@action_registry)
206
+ @action_registry
263
207
  end
264
208
 
265
209
  # Loads on initial access and reads data from the global data store.
@@ -270,7 +214,6 @@ module Vagrant
270
214
  #
271
215
  # @return [DataStore]
272
216
  def global_data
273
- return parent.global_data if parent
274
217
  @global_data ||= DataStore.new(File.expand_path("global_data.json", home_path))
275
218
  end
276
219
 
@@ -281,40 +224,9 @@ module Vagrant
281
224
  #
282
225
  # @return [DataStore]
283
226
  def local_data
284
- return parent.local_data if parent
285
227
  @local_data ||= DataStore.new(dotfile_path)
286
228
  end
287
229
 
288
- # Accesses the logger for Vagrant. This logger is a _detailed_
289
- # logger which should be used to log internals only. For outward
290
- # facing information, use {#ui}.
291
- #
292
- # @return [Logger]
293
- def logger
294
- return parent.logger if parent
295
- return @logger if @logger
296
-
297
- # Figure out where the output should go to.
298
- output = nil
299
- if ENV["VAGRANT_LOG"] == "STDOUT"
300
- output = STDOUT
301
- elsif ENV["VAGRANT_LOG"] == "NULL"
302
- output = nil
303
- elsif ENV["VAGRANT_LOG"]
304
- output = ENV["VAGRANT_LOG"]
305
- else
306
- output = nil #log_path.join("#{Time.now.to_i}.log")
307
- end
308
-
309
- # Create the logger and custom formatter
310
- @logger = Logger.new(output)
311
- @logger.formatter = Proc.new do |severity, datetime, progname, msg|
312
- "#{datetime} - #{progname} - [#{resource}] #{msg}\n"
313
- end
314
-
315
- @logger
316
- end
317
-
318
230
  # The root path is the path where the top-most (loaded last)
319
231
  # Vagrantfile resides. It can be considered the project root for
320
232
  # this environment.
@@ -379,7 +291,7 @@ module Vagrant
379
291
  # will trigger the environment to load if it hasn't loaded yet (see
380
292
  # {#load!}).
381
293
  #
382
- # @return [Config::Top]
294
+ # @return [Config::Container]
383
295
  def config
384
296
  load! if !loaded?
385
297
  @config
@@ -403,15 +315,7 @@ module Vagrant
403
315
  def load!
404
316
  if !loaded?
405
317
  @loaded = true
406
-
407
- if !parent
408
- # We only need to check the virtualbox version once, so do it on
409
- # the parent most environment and then forget about it
410
- logger.info("environment") { "Environment not loaded. Checking virtual box version..." }
411
- self.class.check_virtualbox!
412
- end
413
-
414
- logger.info("environment") { "Loading configuration..." }
318
+ @logger.info("Loading configuration...")
415
319
  load_config!
416
320
  end
417
321
 
@@ -419,11 +323,12 @@ module Vagrant
419
323
  end
420
324
 
421
325
  # Reloads the configuration of this environment.
422
- def reload_config!
423
- @config = nil
424
- @config_loader = nil
326
+ def reload!
327
+ # Reload the configuration
425
328
  load_config!
426
- self
329
+
330
+ # Clear the VMs because this can now be diferent due to configuration
331
+ @vms = nil
427
332
  end
428
333
 
429
334
  # Loads this environment's configuration and stores it in the {#config}
@@ -431,86 +336,162 @@ module Vagrant
431
336
  # this environment, meaning that it will use the given root directory
432
337
  # to load the Vagrantfile into that context.
433
338
  def load_config!
434
- first_run = @config.nil?
435
-
436
- # First load the initial, non config-dependent Vagrantfiles
437
- @config_loader ||= Config.new(parent ? parent.config_loader : nil)
438
- @config_loader.load_order = [:default, :box, :home, :root, :sub_vm]
439
- @config_loader.set(:default, File.expand_path("config/default.rb", Vagrant.source_root))
440
-
441
- vagrantfile_name.each do |rootfile|
442
- if !first_run && vm && box
339
+ # Initialize the config loader
340
+ config_loader = Config::Loader.new
341
+ config_loader.load_order = [:default, :box, :home, :root, :vm]
342
+
343
+ inner_load = lambda do |*args|
344
+ # This is for Ruby 1.8.7 compatibility. Ruby 1.8.7 doesn't allow
345
+ # default arguments for lambdas, so we get around by doing a *args
346
+ # and setting the args here.
347
+ subvm = args[0]
348
+ box = args[1]
349
+
350
+ # Default Vagrantfile first. This is the Vagrantfile that ships
351
+ # with Vagrant.
352
+ config_loader.set(:default, File.expand_path("config/default.rb", Vagrant.source_root))
353
+
354
+ if box
443
355
  # We load the box Vagrantfile
444
- box_vagrantfile = box.directory.join(rootfile)
445
- @config_loader.set(:box, box_vagrantfile) if box_vagrantfile.exist?
356
+ box_vagrantfile = find_vagrantfile(box.directory)
357
+ config_loader.set(:box, box_vagrantfile) if box_vagrantfile
446
358
  end
447
359
 
448
- if !first_run && home_path
360
+ if home_path
449
361
  # Load the home Vagrantfile
450
- home_vagrantfile = home_path.join(rootfile)
451
- @config_loader.set(:home, home_vagrantfile) if home_vagrantfile.exist?
362
+ home_vagrantfile = find_vagrantfile(home_path)
363
+ config_loader.set(:home, home_vagrantfile) if home_vagrantfile
452
364
  end
453
365
 
454
366
  if root_path
455
367
  # Load the Vagrantfile in this directory
456
- root_vagrantfile = root_path.join(rootfile)
457
- @config_loader.set(:root, root_vagrantfile) if root_vagrantfile.exist?
368
+ root_vagrantfile = find_vagrantfile(root_path)
369
+ config_loader.set(:root, root_vagrantfile) if root_vagrantfile
458
370
  end
371
+
372
+ if subvm
373
+ # We have subvm configuration, so set that up as well.
374
+ config_loader.set(:vm, subvm.proc_stack)
375
+ end
376
+
377
+ # Execute the configuration stack and store the result as the final
378
+ # value in the config ivar.
379
+ config_loader.load
459
380
  end
460
381
 
461
- # If this environment is representing a sub-VM, then we push that
462
- # proc on as the last configuration.
463
- if vm
464
- subvm = parent.config.vm.defined_vms[vm.name]
465
- @config_loader.set(:sub_vm, subvm.proc_stack) if subvm
382
+ # For the global configuration, we only need to load the configuration
383
+ # in a single pass, since nothing is conditional on the configuration.
384
+ global = inner_load.call
385
+
386
+ # For each virtual machine represented by this environment, we have
387
+ # to load the configuration in two-passes. We do this because the
388
+ # first pass is used to determine the box for the VM. The second pass
389
+ # is used to also load the box Vagrantfile.
390
+ defined_vm_keys = global.vm.defined_vm_keys.dup
391
+ defined_vms = global.vm.defined_vms.dup
392
+
393
+ # If this isn't a multi-VM environment, then setup the default VM
394
+ # to simply be our configuration.
395
+ if defined_vm_keys.empty?
396
+ defined_vm_keys << DEFAULT_VM
397
+ defined_vms[DEFAULT_VM] = Config::VMConfig::SubVM.new
466
398
  end
467
399
 
468
- # Execute the configuration stack and store the result as the final
469
- # value in the config ivar.
470
- @config = @config_loader.load(self)
400
+ vm_configs = defined_vm_keys.map do |vm_name|
401
+ @logger.debug("Loading configuration for VM: #{vm_name}")
471
402
 
472
- if first_run
473
- # After the first run we want to load the configuration again since
474
- # it can change due to box Vagrantfiles and home directory Vagrantfiles
475
- load_home_directory!
476
- load_config!
403
+ subvm = defined_vms[vm_name]
404
+
405
+ # First pass, first run.
406
+ config = inner_load[subvm]
407
+
408
+ # Second pass, with the box
409
+ config = inner_load[subvm, boxes.find(config.vm.box)]
410
+ config.vm.name = vm_name
411
+
412
+ # Return the final configuration for this VM
413
+ config
414
+ end
415
+
416
+ # Finally, we have our configuration. Set it and forget it.
417
+ @config = Config::Container.new(global, vm_configs)
418
+ end
419
+
420
+ # Loads the persisted VM (if it exists) for this environment.
421
+ def load_vms!
422
+ result = {}
423
+
424
+ # Load all the virtual machine instances.
425
+ config.vms.each do |name|
426
+ result[name] = Vagrant::VM.new(name, self, config.for_vm(name))
477
427
  end
428
+
429
+ result
478
430
  end
479
431
 
480
- # Loads the home directory path and creates the necessary subdirectories
481
- # within the home directory if they're not already created.
482
- def load_home_directory!
432
+ # This sets the `@home_path` variable properly.
433
+ #
434
+ # @return [Pathname]
435
+ def setup_home_path
436
+ @home_path = Pathname.new(File.expand_path(@home_path ||
437
+ ENV["VAGRANT_HOME"] ||
438
+ DEFAULT_HOME))
439
+ @logger.info("Home path: #{@home_path}")
440
+
483
441
  # Setup the array of necessary home directories
484
- dirs = [home_path]
485
- dirs += HOME_SUBDIRS.collect { |subdir| home_path.join(subdir) }
442
+ dirs = [@home_path]
443
+ dirs += HOME_SUBDIRS.collect { |subdir| @home_path.join(subdir) }
486
444
 
487
445
  # Go through each required directory, creating it if it doesn't exist
488
446
  dirs.each do |dir|
489
447
  next if File.directory?(dir)
490
448
 
491
- ui.info I18n.t("vagrant.general.creating_home_dir", :directory => dir)
492
- FileUtils.mkdir_p(dir)
449
+ begin
450
+ @logger.info("Creating: #{dir}")
451
+ FileUtils.mkdir_p(dir)
452
+ rescue Errno::EACCES
453
+ raise Errors::HomeDirectoryNotAccessible, :home_path => @home_path.to_s
454
+ end
493
455
  end
494
456
  end
495
457
 
496
- # Loads the persisted VM (if it exists) for this environment.
497
- def load_vms!
498
- result = {}
458
+ protected
459
+
460
+ # This method copies the private key into the home directory if it
461
+ # doesn't already exist.
462
+ #
463
+ # This must be done because `ssh` requires that the key is chmod
464
+ # 0600, but if Vagrant is installed as a separate user, then the
465
+ # effective uid won't be able to read the key. So the key is copied
466
+ # to the home directory and chmod 0600.
467
+ def copy_insecure_private_key
468
+ if !@default_private_key_path.exist?
469
+ @logger.info("Copying private key to home directory")
470
+ FileUtils.cp(File.expand_path("keys/vagrant", Vagrant.source_root),
471
+ @default_private_key_path)
472
+ end
499
473
 
500
- # Load the VM UUIDs from the local data store
501
- (local_data[:active] || {}).each do |name, uuid|
502
- result[name.to_sym] = Vagrant::VM.find(uuid, self, name.to_sym)
474
+ if !Util::Platform.windows?
475
+ # On Windows, permissions don't matter as much, so don't worry
476
+ # about doing chmod.
477
+ if Util::FileMode.from_octal(@default_private_key_path.stat.mode) != "600"
478
+ @logger.info("Changing permissions on private key to 0600")
479
+ @default_private_key_path.chmod(0600)
480
+ end
503
481
  end
482
+ end
504
483
 
505
- # For any VMs which aren't created, create a blank VM instance for
506
- # them
507
- all_keys = config.vm.defined_vm_keys
508
- all_keys = [DEFAULT_VM] if all_keys.empty?
509
- all_keys.each do |name|
510
- result[name] = Vagrant::VM.new(:name => name, :env => self) if !result.has_key?(name)
484
+ # Finds the Vagrantfile in the given directory.
485
+ #
486
+ # @param [Pathname] path Path to search in.
487
+ # @return [Pathname]
488
+ def find_vagrantfile(search_path)
489
+ @vagrantfile_name.each do |vagrantfile|
490
+ current_path = search_path.join(vagrantfile)
491
+ return current_path if current_path.exist?
511
492
  end
512
493
 
513
- result
494
+ nil
514
495
  end
515
496
  end
516
497
  end