tnargav 1.2.2

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 (452) hide show
  1. data/.gitignore +31 -0
  2. data/.gitsetup.yml +5 -0
  3. data/.travis.yml +7 -0
  4. data/.yardopts +1 -0
  5. data/CHANGELOG.md +1067 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE +21 -0
  8. data/README.md +89 -0
  9. data/Rakefile +18 -0
  10. data/bin/vagrant +106 -0
  11. data/config/default.rb +36 -0
  12. data/contrib/README.md +12 -0
  13. data/contrib/bash/completion.sh +3 -0
  14. data/contrib/emacs/vagrant.el +8 -0
  15. data/contrib/vim/vagrantfile.vim +9 -0
  16. data/keys/README.md +17 -0
  17. data/keys/vagrant +27 -0
  18. data/keys/vagrant.pub +1 -0
  19. data/lib/vagrant/action/builder.rb +174 -0
  20. data/lib/vagrant/action/builtin/box_add.rb +81 -0
  21. data/lib/vagrant/action/builtin/call.rb +67 -0
  22. data/lib/vagrant/action/builtin/config_validate.rb +30 -0
  23. data/lib/vagrant/action/builtin/confirm.rb +38 -0
  24. data/lib/vagrant/action/builtin/destroy_confirm.rb +21 -0
  25. data/lib/vagrant/action/builtin/env_set.rb +24 -0
  26. data/lib/vagrant/action/builtin/graceful_halt.rb +73 -0
  27. data/lib/vagrant/action/builtin/handle_box_url.rb +77 -0
  28. data/lib/vagrant/action/builtin/handle_forwarded_port_collisions.rb +134 -0
  29. data/lib/vagrant/action/builtin/lock.rb +57 -0
  30. data/lib/vagrant/action/builtin/nfs.rb +118 -0
  31. data/lib/vagrant/action/builtin/provision.rb +70 -0
  32. data/lib/vagrant/action/builtin/set_hostname.rb +27 -0
  33. data/lib/vagrant/action/builtin/ssh_exec.rb +42 -0
  34. data/lib/vagrant/action/builtin/ssh_run.rb +43 -0
  35. data/lib/vagrant/action/general/package.rb +103 -0
  36. data/lib/vagrant/action/hook.rb +107 -0
  37. data/lib/vagrant/action/runner.rb +69 -0
  38. data/lib/vagrant/action/warden.rb +103 -0
  39. data/lib/vagrant/action.rb +43 -0
  40. data/lib/vagrant/batch_action.rb +113 -0
  41. data/lib/vagrant/box.rb +97 -0
  42. data/lib/vagrant/box_collection.rb +375 -0
  43. data/lib/vagrant/cli.rb +82 -0
  44. data/lib/vagrant/config/loader.rb +222 -0
  45. data/lib/vagrant/config/v1/dummy_config.rb +13 -0
  46. data/lib/vagrant/config/v1/loader.rb +105 -0
  47. data/lib/vagrant/config/v1/root.rb +60 -0
  48. data/lib/vagrant/config/v1.rb +9 -0
  49. data/lib/vagrant/config/v2/dummy_config.rb +13 -0
  50. data/lib/vagrant/config/v2/loader.rb +141 -0
  51. data/lib/vagrant/config/v2/root.rb +105 -0
  52. data/lib/vagrant/config/v2/util.rb +21 -0
  53. data/lib/vagrant/config/v2.rb +9 -0
  54. data/lib/vagrant/config/version_base.rb +80 -0
  55. data/lib/vagrant/config.rb +61 -0
  56. data/lib/vagrant/environment.rb +843 -0
  57. data/lib/vagrant/errors.rb +570 -0
  58. data/lib/vagrant/guest.rb +163 -0
  59. data/lib/vagrant/hosts.rb +28 -0
  60. data/lib/vagrant/machine.rb +325 -0
  61. data/lib/vagrant/machine_state.rb +45 -0
  62. data/lib/vagrant/plugin/v1/command.rb +169 -0
  63. data/lib/vagrant/plugin/v1/communicator.rb +98 -0
  64. data/lib/vagrant/plugin/v1/config.rb +112 -0
  65. data/lib/vagrant/plugin/v1/errors.rb +15 -0
  66. data/lib/vagrant/plugin/v1/guest.rb +92 -0
  67. data/lib/vagrant/plugin/v1/host.rb +66 -0
  68. data/lib/vagrant/plugin/v1/manager.rb +131 -0
  69. data/lib/vagrant/plugin/v1/plugin.rb +229 -0
  70. data/lib/vagrant/plugin/v1/provider.rb +68 -0
  71. data/lib/vagrant/plugin/v1/provisioner.rb +50 -0
  72. data/lib/vagrant/plugin/v1.rb +19 -0
  73. data/lib/vagrant/plugin/v2/command.rb +234 -0
  74. data/lib/vagrant/plugin/v2/communicator.rb +98 -0
  75. data/lib/vagrant/plugin/v2/components.rb +47 -0
  76. data/lib/vagrant/plugin/v2/config.rb +136 -0
  77. data/lib/vagrant/plugin/v2/errors.rb +15 -0
  78. data/lib/vagrant/plugin/v2/guest.rb +78 -0
  79. data/lib/vagrant/plugin/v2/host.rb +66 -0
  80. data/lib/vagrant/plugin/v2/manager.rb +173 -0
  81. data/lib/vagrant/plugin/v2/plugin.rb +226 -0
  82. data/lib/vagrant/plugin/v2/provider.rb +69 -0
  83. data/lib/vagrant/plugin/v2/provisioner.rb +47 -0
  84. data/lib/vagrant/plugin/v2.rb +22 -0
  85. data/lib/vagrant/plugin.rb +6 -0
  86. data/lib/vagrant/registry.rb +78 -0
  87. data/lib/vagrant/ui.rb +215 -0
  88. data/lib/vagrant/util/ansi_escape_code_remover.rb +34 -0
  89. data/lib/vagrant/util/busy.rb +59 -0
  90. data/lib/vagrant/util/counter.rb +24 -0
  91. data/lib/vagrant/util/downloader.rb +146 -0
  92. data/lib/vagrant/util/file_checksum.rb +38 -0
  93. data/lib/vagrant/util/file_mode.rb +12 -0
  94. data/lib/vagrant/util/hash_with_indifferent_access.rb +63 -0
  95. data/lib/vagrant/util/is_port_open.rb +38 -0
  96. data/lib/vagrant/util/line_ending_helpers.rb +14 -0
  97. data/lib/vagrant/util/network_ip.rb +28 -0
  98. data/lib/vagrant/util/platform.rb +58 -0
  99. data/lib/vagrant/util/retryable.rb +31 -0
  100. data/lib/vagrant/util/safe_chdir.rb +33 -0
  101. data/lib/vagrant/util/safe_exec.rb +36 -0
  102. data/lib/vagrant/util/safe_puts.rb +31 -0
  103. data/lib/vagrant/util/scoped_hash_override.rb +45 -0
  104. data/lib/vagrant/util/ssh.rb +150 -0
  105. data/lib/vagrant/util/stacked_proc_runner.rb +35 -0
  106. data/lib/vagrant/util/string_block_editor.rb +77 -0
  107. data/lib/vagrant/util/subprocess.rb +273 -0
  108. data/lib/vagrant/util/template_renderer.rb +83 -0
  109. data/lib/vagrant/util/which.rb +43 -0
  110. data/lib/vagrant/util.rb +12 -0
  111. data/lib/vagrant/version.rb +6 -0
  112. data/lib/vagrant.rb +258 -0
  113. data/plugins/README.md +5 -0
  114. data/plugins/commands/box/command/add.rb +51 -0
  115. data/plugins/commands/box/command/list.rb +41 -0
  116. data/plugins/commands/box/command/remove.rb +37 -0
  117. data/plugins/commands/box/command/repackage.rb +43 -0
  118. data/plugins/commands/box/command/root.rb +75 -0
  119. data/plugins/commands/box/plugin.rb +15 -0
  120. data/plugins/commands/destroy/command.rb +31 -0
  121. data/plugins/commands/destroy/plugin.rb +18 -0
  122. data/plugins/commands/halt/command.rb +33 -0
  123. data/plugins/commands/halt/plugin.rb +18 -0
  124. data/plugins/commands/init/command.rb +40 -0
  125. data/plugins/commands/init/plugin.rb +18 -0
  126. data/plugins/commands/package/command.rb +83 -0
  127. data/plugins/commands/package/plugin.rb +18 -0
  128. data/plugins/commands/plugin/action/bundler_check.rb +25 -0
  129. data/plugins/commands/plugin/action/install_gem.rb +81 -0
  130. data/plugins/commands/plugin/action/license_plugin.rb +54 -0
  131. data/plugins/commands/plugin/action/list_plugins.rb +54 -0
  132. data/plugins/commands/plugin/action/prune_gems.rb +149 -0
  133. data/plugins/commands/plugin/action/uninstall_plugin.rb +23 -0
  134. data/plugins/commands/plugin/action.rb +52 -0
  135. data/plugins/commands/plugin/command/base.rb +22 -0
  136. data/plugins/commands/plugin/command/install.rb +58 -0
  137. data/plugins/commands/plugin/command/license.rb +31 -0
  138. data/plugins/commands/plugin/command/list.rb +28 -0
  139. data/plugins/commands/plugin/command/root.rb +75 -0
  140. data/plugins/commands/plugin/command/uninstall.rb +28 -0
  141. data/plugins/commands/plugin/gem_helper.rb +74 -0
  142. data/plugins/commands/plugin/plugin.rb +22 -0
  143. data/plugins/commands/plugin/state_file.rb +57 -0
  144. data/plugins/commands/provision/command.rb +34 -0
  145. data/plugins/commands/provision/plugin.rb +18 -0
  146. data/plugins/commands/reload/command.rb +37 -0
  147. data/plugins/commands/reload/plugin.rb +18 -0
  148. data/plugins/commands/resume/command.rb +25 -0
  149. data/plugins/commands/resume/plugin.rb +17 -0
  150. data/plugins/commands/ssh/command.rb +63 -0
  151. data/plugins/commands/ssh/plugin.rb +17 -0
  152. data/plugins/commands/ssh_config/command.rb +49 -0
  153. data/plugins/commands/ssh_config/plugin.rb +18 -0
  154. data/plugins/commands/status/command.rb +39 -0
  155. data/plugins/commands/status/plugin.rb +18 -0
  156. data/plugins/commands/suspend/command.rb +25 -0
  157. data/plugins/commands/suspend/plugin.rb +18 -0
  158. data/plugins/commands/up/command.rb +57 -0
  159. data/plugins/commands/up/plugin.rb +17 -0
  160. data/plugins/commands/up/start_mixins.rb +26 -0
  161. data/plugins/communicators/ssh/communicator.rb +342 -0
  162. data/plugins/communicators/ssh/plugin.rb +19 -0
  163. data/plugins/guests/arch/cap/change_host_name.rb +18 -0
  164. data/plugins/guests/arch/cap/configure_networks.rb +23 -0
  165. data/plugins/guests/arch/guest.rb +11 -0
  166. data/plugins/guests/arch/plugin.rb +25 -0
  167. data/plugins/guests/debian/cap/change_host_name.rb +18 -0
  168. data/plugins/guests/debian/cap/configure_networks.rb +61 -0
  169. data/plugins/guests/debian/guest.rb +9 -0
  170. data/plugins/guests/debian/plugin.rb +25 -0
  171. data/plugins/guests/fedora/cap/configure_networks.rb +59 -0
  172. data/plugins/guests/fedora/cap/network_scripts_dir.rb +15 -0
  173. data/plugins/guests/fedora/guest.rb +11 -0
  174. data/plugins/guests/fedora/plugin.rb +25 -0
  175. data/plugins/guests/freebsd/cap/change_host_name.rb +14 -0
  176. data/plugins/guests/freebsd/cap/configure_networks.rb +39 -0
  177. data/plugins/guests/freebsd/cap/halt.rb +16 -0
  178. data/plugins/guests/freebsd/cap/mount_nfs_folder.rb +14 -0
  179. data/plugins/guests/freebsd/guest.rb +14 -0
  180. data/plugins/guests/freebsd/plugin.rb +35 -0
  181. data/plugins/guests/gentoo/cap/change_host_name.rb +17 -0
  182. data/plugins/guests/gentoo/cap/configure_networks.rb +43 -0
  183. data/plugins/guests/gentoo/guest.rb +9 -0
  184. data/plugins/guests/gentoo/plugin.rb +25 -0
  185. data/plugins/guests/linux/cap/halt.rb +16 -0
  186. data/plugins/guests/linux/cap/mount_nfs.rb +30 -0
  187. data/plugins/guests/linux/cap/mount_virtualbox_shared_folder.rb +40 -0
  188. data/plugins/guests/linux/cap/read_ip_address.rb +17 -0
  189. data/plugins/guests/linux/cap/shell_expand_guest_path.rb +26 -0
  190. data/plugins/guests/linux/guest.rb +11 -0
  191. data/plugins/guests/linux/plugin.rb +40 -0
  192. data/plugins/guests/openbsd/cap/halt.rb +16 -0
  193. data/plugins/guests/openbsd/guest.rb +11 -0
  194. data/plugins/guests/openbsd/plugin.rb +20 -0
  195. data/plugins/guests/pld/cap/network_scripts_dir.rb +11 -0
  196. data/plugins/guests/pld/guest.rb +11 -0
  197. data/plugins/guests/pld/plugin.rb +20 -0
  198. data/plugins/guests/redhat/cap/change_host_name.rb +18 -0
  199. data/plugins/guests/redhat/cap/configure_networks.rb +60 -0
  200. data/plugins/guests/redhat/cap/network_scripts_dir.rb +11 -0
  201. data/plugins/guests/redhat/guest.rb +11 -0
  202. data/plugins/guests/redhat/plugin.rb +30 -0
  203. data/plugins/guests/solaris/cap/change_host_name.rb +17 -0
  204. data/plugins/guests/solaris/cap/configure_networks.rb +25 -0
  205. data/plugins/guests/solaris/cap/halt.rb +21 -0
  206. data/plugins/guests/solaris/cap/mount_virtualbox_shared_folder.rb +28 -0
  207. data/plugins/guests/solaris/config.rb +18 -0
  208. data/plugins/guests/solaris/guest.rb +14 -0
  209. data/plugins/guests/solaris/plugin.rb +40 -0
  210. data/plugins/guests/suse/cap/change_host_name.rb +18 -0
  211. data/plugins/guests/suse/cap/network_scripts_dir.rb +11 -0
  212. data/plugins/guests/suse/guest.rb +11 -0
  213. data/plugins/guests/suse/plugin.rb +25 -0
  214. data/plugins/guests/ubuntu/cap/change_host_name.rb +23 -0
  215. data/plugins/guests/ubuntu/guest.rb +32 -0
  216. data/plugins/guests/ubuntu/plugin.rb +20 -0
  217. data/plugins/hosts/arch/host.rb +68 -0
  218. data/plugins/hosts/arch/plugin.rb +15 -0
  219. data/plugins/hosts/bsd/host.rb +102 -0
  220. data/plugins/hosts/bsd/plugin.rb +15 -0
  221. data/plugins/hosts/fedora/host.rb +51 -0
  222. data/plugins/hosts/fedora/plugin.rb +15 -0
  223. data/plugins/hosts/freebsd/host.rb +43 -0
  224. data/plugins/hosts/freebsd/plugin.rb +15 -0
  225. data/plugins/hosts/gentoo/host.rb +24 -0
  226. data/plugins/hosts/gentoo/plugin.rb +15 -0
  227. data/plugins/hosts/linux/host.rb +95 -0
  228. data/plugins/hosts/linux/plugin.rb +15 -0
  229. data/plugins/hosts/opensuse/host.rb +34 -0
  230. data/plugins/hosts/opensuse/plugin.rb +15 -0
  231. data/plugins/hosts/windows/host.rb +17 -0
  232. data/plugins/hosts/windows/plugin.rb +15 -0
  233. data/plugins/kernel_v1/config/nfs.rb +20 -0
  234. data/plugins/kernel_v1/config/package.rb +17 -0
  235. data/plugins/kernel_v1/config/ssh.rb +46 -0
  236. data/plugins/kernel_v1/config/vagrant.rb +31 -0
  237. data/plugins/kernel_v1/config/vm.rb +184 -0
  238. data/plugins/kernel_v1/plugin.rb +44 -0
  239. data/plugins/kernel_v2/config/nfs.rb +14 -0
  240. data/plugins/kernel_v2/config/package.rb +13 -0
  241. data/plugins/kernel_v2/config/ssh.rb +76 -0
  242. data/plugins/kernel_v2/config/ssh_connect.rb +40 -0
  243. data/plugins/kernel_v2/config/vagrant.rb +13 -0
  244. data/plugins/kernel_v2/config/vm.rb +416 -0
  245. data/plugins/kernel_v2/config/vm_provisioner.rb +55 -0
  246. data/plugins/kernel_v2/config/vm_subvm.rb +30 -0
  247. data/plugins/kernel_v2/plugin.rb +44 -0
  248. data/plugins/providers/virtualbox/action/boot.rb +49 -0
  249. data/plugins/providers/virtualbox/action/check_accessible.rb +23 -0
  250. data/plugins/providers/virtualbox/action/check_created.rb +21 -0
  251. data/plugins/providers/virtualbox/action/check_guest_additions.rb +45 -0
  252. data/plugins/providers/virtualbox/action/check_running.rb +21 -0
  253. data/plugins/providers/virtualbox/action/check_virtualbox.rb +22 -0
  254. data/plugins/providers/virtualbox/action/clean_machine_folder.rb +43 -0
  255. data/plugins/providers/virtualbox/action/clear_forwarded_ports.rb +18 -0
  256. data/plugins/providers/virtualbox/action/clear_network_interfaces.rb +31 -0
  257. data/plugins/providers/virtualbox/action/clear_shared_folders.rb +17 -0
  258. data/plugins/providers/virtualbox/action/created.rb +20 -0
  259. data/plugins/providers/virtualbox/action/customize.rb +36 -0
  260. data/plugins/providers/virtualbox/action/destroy.rb +19 -0
  261. data/plugins/providers/virtualbox/action/destroy_unused_network_interfaces.rb +16 -0
  262. data/plugins/providers/virtualbox/action/discard_state.rb +20 -0
  263. data/plugins/providers/virtualbox/action/export.rb +57 -0
  264. data/plugins/providers/virtualbox/action/forced_halt.rb +25 -0
  265. data/plugins/providers/virtualbox/action/forward_ports.rb +87 -0
  266. data/plugins/providers/virtualbox/action/import.rb +51 -0
  267. data/plugins/providers/virtualbox/action/is_paused.rb +20 -0
  268. data/plugins/providers/virtualbox/action/is_running.rb +20 -0
  269. data/plugins/providers/virtualbox/action/is_saved.rb +20 -0
  270. data/plugins/providers/virtualbox/action/match_mac_address.rb +21 -0
  271. data/plugins/providers/virtualbox/action/message_already_running.rb +16 -0
  272. data/plugins/providers/virtualbox/action/message_not_created.rb +16 -0
  273. data/plugins/providers/virtualbox/action/message_not_running.rb +16 -0
  274. data/plugins/providers/virtualbox/action/message_will_not_destroy.rb +17 -0
  275. data/plugins/providers/virtualbox/action/network.rb +410 -0
  276. data/plugins/providers/virtualbox/action/package.rb +20 -0
  277. data/plugins/providers/virtualbox/action/package_vagrantfile.rb +33 -0
  278. data/plugins/providers/virtualbox/action/prepare_forwarded_port_collision_params.rb +35 -0
  279. data/plugins/providers/virtualbox/action/prepare_nfs_settings.rb +64 -0
  280. data/plugins/providers/virtualbox/action/prune_nfs_exports.rb +20 -0
  281. data/plugins/providers/virtualbox/action/resume.rb +25 -0
  282. data/plugins/providers/virtualbox/action/sane_defaults.rb +91 -0
  283. data/plugins/providers/virtualbox/action/set_name.rb +40 -0
  284. data/plugins/providers/virtualbox/action/setup_package_files.rb +51 -0
  285. data/plugins/providers/virtualbox/action/share_folders.rb +128 -0
  286. data/plugins/providers/virtualbox/action/suspend.rb +20 -0
  287. data/plugins/providers/virtualbox/action.rb +311 -0
  288. data/plugins/providers/virtualbox/config.rb +86 -0
  289. data/plugins/providers/virtualbox/driver/base.rb +360 -0
  290. data/plugins/providers/virtualbox/driver/meta.rb +142 -0
  291. data/plugins/providers/virtualbox/driver/version_4_0.rb +485 -0
  292. data/plugins/providers/virtualbox/driver/version_4_1.rb +485 -0
  293. data/plugins/providers/virtualbox/driver/version_4_2.rb +482 -0
  294. data/plugins/providers/virtualbox/model/forwarded_port.rb +58 -0
  295. data/plugins/providers/virtualbox/plugin.rb +42 -0
  296. data/plugins/providers/virtualbox/provider.rb +92 -0
  297. data/plugins/providers/virtualbox/util/compile_forwarded_ports.rb +31 -0
  298. data/plugins/provisioners/ansible/config.rb +72 -0
  299. data/plugins/provisioners/ansible/plugin.rb +23 -0
  300. data/plugins/provisioners/ansible/provisioner.rb +45 -0
  301. data/plugins/provisioners/cfengine/cap/debian/cfengine_install.rb +19 -0
  302. data/plugins/provisioners/cfengine/cap/linux/cfengine_installed.rb +14 -0
  303. data/plugins/provisioners/cfengine/cap/linux/cfengine_needs_bootstrap.rb +34 -0
  304. data/plugins/provisioners/cfengine/cap/redhat/cfengine_install.rb +24 -0
  305. data/plugins/provisioners/cfengine/config.rb +120 -0
  306. data/plugins/provisioners/cfengine/plugin.rb +42 -0
  307. data/plugins/provisioners/cfengine/provisioner.rb +136 -0
  308. data/plugins/provisioners/chef/config/base.rb +85 -0
  309. data/plugins/provisioners/chef/config/chef_client.rb +57 -0
  310. data/plugins/provisioners/chef/config/chef_solo.rb +87 -0
  311. data/plugins/provisioners/chef/plugin.rb +33 -0
  312. data/plugins/provisioners/chef/provisioner/base.rb +93 -0
  313. data/plugins/provisioners/chef/provisioner/chef_client.rb +107 -0
  314. data/plugins/provisioners/chef/provisioner/chef_solo.rb +192 -0
  315. data/plugins/provisioners/puppet/config/puppet.rb +70 -0
  316. data/plugins/provisioners/puppet/config/puppet_server.rb +16 -0
  317. data/plugins/provisioners/puppet/plugin.rb +33 -0
  318. data/plugins/provisioners/puppet/provisioner/puppet.rb +117 -0
  319. data/plugins/provisioners/puppet/provisioner/puppet_server.rb +67 -0
  320. data/plugins/provisioners/shell/config.rb +56 -0
  321. data/plugins/provisioners/shell/plugin.rb +23 -0
  322. data/plugins/provisioners/shell/provisioner.rb +86 -0
  323. data/tasks/acceptance.rake +113 -0
  324. data/tasks/bundler.rake +3 -0
  325. data/tasks/test.rake +20 -0
  326. data/templates/commands/init/Vagrantfile.erb +111 -0
  327. data/templates/commands/ssh_config/config.erb +16 -0
  328. data/templates/config/messages.erb +14 -0
  329. data/templates/config/validation_failed.erb +7 -0
  330. data/templates/guests/arch/network_dhcp.erb +4 -0
  331. data/templates/guests/arch/network_static.erb +6 -0
  332. data/templates/guests/debian/network_dhcp.erb +11 -0
  333. data/templates/guests/debian/network_static.erb +7 -0
  334. data/templates/guests/fedora/network_dhcp.erb +6 -0
  335. data/templates/guests/fedora/network_static.erb +13 -0
  336. data/templates/guests/freebsd/network_dhcp.erb +3 -0
  337. data/templates/guests/freebsd/network_static.erb +3 -0
  338. data/templates/guests/gentoo/network_dhcp.erb +4 -0
  339. data/templates/guests/gentoo/network_static.erb +4 -0
  340. data/templates/guests/redhat/network_dhcp.erb +6 -0
  341. data/templates/guests/redhat/network_static.erb +8 -0
  342. data/templates/locales/en.yml +1126 -0
  343. data/templates/nfs/exports.erb +5 -0
  344. data/templates/nfs/exports_freebsd.erb +5 -0
  345. data/templates/nfs/exports_linux.erb +5 -0
  346. data/templates/package_Vagrantfile.erb +11 -0
  347. data/templates/provisioners/chef_client/client.erb +32 -0
  348. data/templates/provisioners/chef_solo/solo.erb +25 -0
  349. data/templates/rgloader.rb +9 -0
  350. data/test/acceptance/base.rb +48 -0
  351. data/test/acceptance/box_test.rb +99 -0
  352. data/test/acceptance/destroy_test.rb +37 -0
  353. data/test/acceptance/halt_test.rb +72 -0
  354. data/test/acceptance/init_test.rb +33 -0
  355. data/test/acceptance/networking/host_only_test.rb +37 -0
  356. data/test/acceptance/networking/port_forward_test.rb +125 -0
  357. data/test/acceptance/package_test.rb +46 -0
  358. data/test/acceptance/provisioning/basic_test.rb +61 -0
  359. data/test/acceptance/provisioning/chef_solo_test.rb +37 -0
  360. data/test/acceptance/provisioning/shell_test.rb +53 -0
  361. data/test/acceptance/resume_test.rb +17 -0
  362. data/test/acceptance/shared_folders_test.rb +84 -0
  363. data/test/acceptance/skeletons/chef_solo_basic/README.md +3 -0
  364. data/test/acceptance/skeletons/chef_solo_basic/cookbooks/basic/recipes/default.rb +5 -0
  365. data/test/acceptance/skeletons/chef_solo_json/README.md +3 -0
  366. data/test/acceptance/skeletons/chef_solo_json/cookbooks/basic/recipes/default.rb +6 -0
  367. data/test/acceptance/skeletons/provisioner_multi/README.md +3 -0
  368. data/test/acceptance/skeletons/provisioner_multi/cookbooks/basic/recipes/default.rb +5 -0
  369. data/test/acceptance/ssh_test.rb +46 -0
  370. data/test/acceptance/support/config.rb +42 -0
  371. data/test/acceptance/support/isolated_environment.rb +118 -0
  372. data/test/acceptance/support/matchers/have_color.rb +9 -0
  373. data/test/acceptance/support/matchers/match_output.rb +14 -0
  374. data/test/acceptance/support/matchers/succeed.rb +14 -0
  375. data/test/acceptance/support/network_tests.rb +29 -0
  376. data/test/acceptance/support/output.rb +95 -0
  377. data/test/acceptance/support/shared/base_context.rb +72 -0
  378. data/test/acceptance/support/shared/command_examples.rb +33 -0
  379. data/test/acceptance/support/virtualbox.rb +36 -0
  380. data/test/acceptance/suspend_test.rb +56 -0
  381. data/test/acceptance/up_basic_test.rb +33 -0
  382. data/test/acceptance/up_with_box_url.rb +40 -0
  383. data/test/acceptance/vagrant_test.rb +47 -0
  384. data/test/acceptance/version_test.rb +15 -0
  385. data/test/config/acceptance_boxes.yml +7 -0
  386. data/test/support/isolated_environment.rb +46 -0
  387. data/test/support/tempdir.rb +43 -0
  388. data/test/unit/base.rb +27 -0
  389. data/test/unit/support/dummy_provider.rb +16 -0
  390. data/test/unit/support/isolated_environment.rb +179 -0
  391. data/test/unit/support/shared/base_context.rb +104 -0
  392. data/test/unit/vagrant/action/builder_test.rb +242 -0
  393. data/test/unit/vagrant/action/builtin/call_test.rb +145 -0
  394. data/test/unit/vagrant/action/builtin/confirm_test.rb +36 -0
  395. data/test/unit/vagrant/action/builtin/env_set_test.rb +20 -0
  396. data/test/unit/vagrant/action/builtin/graceful_halt_test.rb +61 -0
  397. data/test/unit/vagrant/action/builtin/lock_test.rb +98 -0
  398. data/test/unit/vagrant/action/builtin/ssh_exec_test.rb +57 -0
  399. data/test/unit/vagrant/action/hook_test.rb +120 -0
  400. data/test/unit/vagrant/action/runner_test.rb +71 -0
  401. data/test/unit/vagrant/action/warden_test.rb +92 -0
  402. data/test/unit/vagrant/batch_action_test.rb +36 -0
  403. data/test/unit/vagrant/box_collection_test.rb +237 -0
  404. data/test/unit/vagrant/box_test.rb +122 -0
  405. data/test/unit/vagrant/cli_test.rb +27 -0
  406. data/test/unit/vagrant/config/loader_test.rb +184 -0
  407. data/test/unit/vagrant/config/v1/dummy_config_test.rb +24 -0
  408. data/test/unit/vagrant/config/v1/loader_test.rb +145 -0
  409. data/test/unit/vagrant/config/v1/root_test.rb +40 -0
  410. data/test/unit/vagrant/config/v2/dummy_config_test.rb +24 -0
  411. data/test/unit/vagrant/config/v2/loader_test.rb +151 -0
  412. data/test/unit/vagrant/config/v2/root_test.rb +97 -0
  413. data/test/unit/vagrant/config/v2/util_test.rb +21 -0
  414. data/test/unit/vagrant/config_test.rb +66 -0
  415. data/test/unit/vagrant/environment_test.rb +721 -0
  416. data/test/unit/vagrant/guest_test.rb +166 -0
  417. data/test/unit/vagrant/hosts_test.rb +37 -0
  418. data/test/unit/vagrant/machine_state_test.rb +26 -0
  419. data/test/unit/vagrant/machine_test.rb +384 -0
  420. data/test/unit/vagrant/plugin/v1/command_test.rb +143 -0
  421. data/test/unit/vagrant/plugin/v1/communicator_test.rb +9 -0
  422. data/test/unit/vagrant/plugin/v1/config_test.rb +50 -0
  423. data/test/unit/vagrant/plugin/v1/host_test.rb +5 -0
  424. data/test/unit/vagrant/plugin/v1/manager_test.rb +114 -0
  425. data/test/unit/vagrant/plugin/v1/plugin_test.rb +267 -0
  426. data/test/unit/vagrant/plugin/v1/provider_test.rb +18 -0
  427. data/test/unit/vagrant/plugin/v2/command_test.rb +238 -0
  428. data/test/unit/vagrant/plugin/v2/communicator_test.rb +9 -0
  429. data/test/unit/vagrant/plugin/v2/components_test.rb +17 -0
  430. data/test/unit/vagrant/plugin/v2/config_test.rb +60 -0
  431. data/test/unit/vagrant/plugin/v2/host_test.rb +5 -0
  432. data/test/unit/vagrant/plugin/v2/manager_test.rb +174 -0
  433. data/test/unit/vagrant/plugin/v2/plugin_test.rb +305 -0
  434. data/test/unit/vagrant/plugin/v2/provider_test.rb +18 -0
  435. data/test/unit/vagrant/registry_test.rb +128 -0
  436. data/test/unit/vagrant/util/ansi_escape_code_remover_test.rb +16 -0
  437. data/test/unit/vagrant/util/downloader_test.rb +57 -0
  438. data/test/unit/vagrant/util/file_checksum_test.rb +23 -0
  439. data/test/unit/vagrant/util/hash_with_indifferent_access_test.rb +38 -0
  440. data/test/unit/vagrant/util/is_port_open_test.rb +53 -0
  441. data/test/unit/vagrant/util/line_endings_helper_test.rb +16 -0
  442. data/test/unit/vagrant/util/network_ip_test.rb +17 -0
  443. data/test/unit/vagrant/util/retryable_test.rb +106 -0
  444. data/test/unit/vagrant/util/safe_chdir_test.rb +43 -0
  445. data/test/unit/vagrant/util/scoped_hash_override_test.rb +48 -0
  446. data/test/unit/vagrant/util/ssh_test.rb +30 -0
  447. data/test/unit/vagrant/util/string_block_editor_test.rb +106 -0
  448. data/test/unit/vagrant/util/which_test.rb +43 -0
  449. data/test/unit/vagrant_test.rb +56 -0
  450. data/tnargav.gemspec +69 -0
  451. data/vagrant.gemspec +69 -0
  452. metadata +730 -0
@@ -0,0 +1,843 @@
1
+ require 'fileutils'
2
+ require 'json'
3
+ require 'pathname'
4
+ require 'set'
5
+ require 'thread'
6
+
7
+ require 'log4r'
8
+
9
+ require 'vagrant/util/file_mode'
10
+ require 'vagrant/util/platform'
11
+
12
+ module Vagrant
13
+ # Represents a single Vagrant environment. A "Vagrant environment" is
14
+ # defined as basically a folder with a "Vagrantfile." This class allows
15
+ # access to the VMs, CLI, etc. all in the scope of this environment.
16
+ class Environment
17
+ DEFAULT_LOCAL_DATA = ".vagrant"
18
+
19
+ # The `cwd` that this environment represents
20
+ attr_reader :cwd
21
+
22
+ # The persistent data directory where global data can be stored. It
23
+ # is up to the creator of the data in this directory to properly
24
+ # remove it when it is no longer needed.
25
+ #
26
+ # @return [Pathname]
27
+ attr_reader :data_dir
28
+
29
+ # The valid name for a Vagrantfile for this environment.
30
+ attr_reader :vagrantfile_name
31
+
32
+ # The {UI} object to communicate with the outside world.
33
+ attr_reader :ui
34
+
35
+ # This is the UI class to use when creating new UIs.
36
+ attr_reader :ui_class
37
+
38
+ # The directory to the "home" folder that Vagrant will use to store
39
+ # global state.
40
+ attr_reader :home_path
41
+
42
+ # The directory to the directory where local, environment-specific
43
+ # data is stored.
44
+ attr_reader :local_data_path
45
+
46
+ # The directory where temporary files for Vagrant go.
47
+ attr_reader :tmp_path
48
+
49
+ # The directory where boxes are stored.
50
+ attr_reader :boxes_path
51
+
52
+ # The path where the plugins are stored (gems)
53
+ attr_reader :gems_path
54
+
55
+ # The path to the default private key
56
+ attr_reader :default_private_key_path
57
+
58
+ # Initializes a new environment with the given options. The options
59
+ # is a hash where the main available key is `cwd`, which defines where
60
+ # the environment represents. There are other options available but
61
+ # they shouldn't be used in general. If `cwd` is nil, then it defaults
62
+ # to the `Dir.pwd` (which is the cwd of the executing process).
63
+ def initialize(opts=nil)
64
+ opts = {
65
+ :cwd => nil,
66
+ :home_path => nil,
67
+ :local_data_path => nil,
68
+ :lock_path => nil,
69
+ :ui_class => nil,
70
+ :vagrantfile_name => nil
71
+ }.merge(opts || {})
72
+
73
+ # Set the default working directory to look for the vagrantfile
74
+ opts[:cwd] ||= ENV["VAGRANT_CWD"] if ENV.has_key?("VAGRANT_CWD")
75
+ opts[:cwd] ||= Dir.pwd
76
+ opts[:cwd] = Pathname.new(opts[:cwd])
77
+ raise Errors::EnvironmentNonExistentCWD if !opts[:cwd].directory?
78
+
79
+ # Set the default ui class
80
+ opts[:ui_class] ||= UI::Silent
81
+
82
+ # Set the Vagrantfile name up. We append "Vagrantfile" and "vagrantfile" so that
83
+ # those continue to work as well, but anything custom will take precedence.
84
+ opts[:vagrantfile_name] ||= ENV["VAGRANT_VAGRANTFILE"] if \
85
+ ENV.has_key?("VAGRANT_VAGRANTFILE")
86
+ opts[:vagrantfile_name] ||= ["Vagrantfile", "vagrantfile"]
87
+ opts[:vagrantfile_name] = [opts[:vagrantfile_name]] if \
88
+ !opts[:vagrantfile_name].is_a?(Array)
89
+
90
+ # Set instance variables for all the configuration parameters.
91
+ @cwd = opts[:cwd]
92
+ @home_path = opts[:home_path]
93
+ @lock_path = opts[:lock_path]
94
+ @vagrantfile_name = opts[:vagrantfile_name]
95
+ @ui = opts[:ui_class].new
96
+ @ui_class = opts[:ui_class]
97
+
98
+ # This is the batch lock, that enforces that only one {BatchAction}
99
+ # runs at a time from {#batch}.
100
+ @batch_lock = Mutex.new
101
+
102
+ @lock_acquired = false
103
+
104
+ @logger = Log4r::Logger.new("vagrant::environment")
105
+ @logger.info("Environment initialized (#{self})")
106
+ @logger.info(" - cwd: #{cwd}")
107
+
108
+ # Setup the home directory
109
+ setup_home_path
110
+ @boxes_path = @home_path.join("boxes")
111
+ @data_dir = @home_path.join("data")
112
+ @gems_path = @home_path.join("gems")
113
+ @tmp_path = @home_path.join("tmp")
114
+
115
+ # Setup the local data directory. If a configuration path is given,
116
+ # then it is expanded relative to the working directory. Otherwise,
117
+ # we use the default which is expanded relative to the root path.
118
+ @local_data_path = nil
119
+ if opts[:local_data_path]
120
+ @local_data_path = Pathname.new(File.expand_path(opts[:local_data_path], @cwd))
121
+ elsif !root_path.nil?
122
+ @local_data_path = root_path.join(DEFAULT_LOCAL_DATA)
123
+ end
124
+
125
+ setup_local_data_path
126
+
127
+ # Setup the default private key
128
+ @default_private_key_path = @home_path.join("insecure_private_key")
129
+ copy_insecure_private_key
130
+
131
+ # Load the plugins
132
+ load_plugins
133
+
134
+ # Call the environment load hooks
135
+ hook(:environment_load)
136
+ end
137
+
138
+ # Return a human-friendly string for pretty printed or inspected
139
+ # instances.
140
+ #
141
+ # @return [String]
142
+ def inspect
143
+ "#<#{self.class}: #{@cwd}>"
144
+ end
145
+
146
+ #---------------------------------------------------------------
147
+ # Helpers
148
+ #---------------------------------------------------------------
149
+
150
+ # Returns a list of machines that this environment is currently
151
+ # managing that physically have been created.
152
+ #
153
+ # An "active" machine is a machine that Vagrant manages that has
154
+ # been created. The machine itself may be in any state such as running,
155
+ # suspended, etc. but if a machine is "active" then it exists.
156
+ #
157
+ # Note that the machines in this array may no longer be present in
158
+ # the Vagrantfile of this environment. In this case the machine can
159
+ # be considered an "orphan." Determining which machines are orphan
160
+ # and which aren't is not currently a supported feature, but will
161
+ # be in a future version.
162
+ #
163
+ # @return [Array<String, Symbol>]
164
+ def active_machines
165
+ machine_folder = @local_data_path.join("machines")
166
+
167
+ # If the machine folder is not a directory then we just return
168
+ # an empty array since no active machines exist.
169
+ return [] if !machine_folder.directory?
170
+
171
+ # Traverse the machines folder accumulate a result
172
+ result = []
173
+
174
+ machine_folder.children(true).each do |name_folder|
175
+ # If this isn't a directory then it isn't a machine
176
+ next if !name_folder.directory?
177
+
178
+ name = name_folder.basename.to_s.to_sym
179
+ name_folder.children(true).each do |provider_folder|
180
+ # If this isn't a directory then it isn't a provider
181
+ next if !provider_folder.directory?
182
+
183
+ # If this machine doesn't have an ID, then ignore
184
+ next if !provider_folder.join("id").file?
185
+
186
+ provider = provider_folder.basename.to_s.to_sym
187
+ result << [name, provider]
188
+ end
189
+ end
190
+
191
+ # Return the results
192
+ result
193
+ end
194
+
195
+ # This creates a new batch action, yielding it, and then running it
196
+ # once the block is called.
197
+ #
198
+ # This handles the case where batch actions are disabled by the
199
+ # VAGRANT_NO_PARALLEL environmental variable.
200
+ def batch(parallel=true)
201
+ parallel = false if ENV["VAGRANT_NO_PARALLEL"]
202
+
203
+ @batch_lock.synchronize do
204
+ BatchAction.new(parallel).tap do |b|
205
+ # Yield it so that the caller can setup actions
206
+ yield b
207
+
208
+ # And run it!
209
+ b.run
210
+ end
211
+ end
212
+ end
213
+
214
+ # This returns the provider name for the default provider for this
215
+ # environment. The provider returned is currently hardcoded to "virtualbox"
216
+ # but one day should be a detected valid, best-case provider for this
217
+ # environment.
218
+ #
219
+ # @return [Symbol] Name of the default provider.
220
+ def default_provider
221
+ (ENV['VAGRANT_DEFAULT_PROVIDER'] || :virtualbox).to_sym
222
+ end
223
+
224
+ # Returns the collection of boxes for the environment.
225
+ #
226
+ # @return [BoxCollection]
227
+ def boxes
228
+ @_boxes ||= BoxCollection.new(boxes_path, temp_dir_root: tmp_path)
229
+ end
230
+
231
+ # This is the global config, comprised of loading configuration from
232
+ # the default, home, and root Vagrantfiles. This configuration is only
233
+ # really useful for reading the list of virtual machines, since each
234
+ # individual VM can override _most_ settings.
235
+ #
236
+ # This is lazy-loaded upon first use.
237
+ #
238
+ # @return [Object]
239
+ def config_global
240
+ return @config_global if @config_global
241
+
242
+ @logger.info("Initializing config...")
243
+
244
+ home_vagrantfile = nil
245
+ root_vagrantfile = nil
246
+ home_vagrantfile = find_vagrantfile(home_path) if home_path
247
+ root_vagrantfile = find_vagrantfile(root_path) if root_path
248
+
249
+ # Create the configuration loader and set the sources that are global.
250
+ # We use this to load the configuration, and the list of machines we are
251
+ # managing. Then, the actual individual configuration is loaded for
252
+ # each {#machine} call.
253
+ @config_loader = Config::Loader.new(Config::VERSIONS, Config::VERSIONS_ORDER)
254
+ @config_loader.set(:default, File.expand_path("config/default.rb", Vagrant.source_root))
255
+ @config_loader.set(:home, home_vagrantfile) if home_vagrantfile
256
+ @config_loader.set(:root, root_vagrantfile) if root_vagrantfile
257
+
258
+ # Make the initial call to get the "global" config. This is mostly
259
+ # only useful to get the list of machines that we are managing.
260
+ # Because of this, we ignore any warnings or errors.
261
+ @config_global, _ = @config_loader.load([:default, :home, :root])
262
+
263
+ # Return the config
264
+ @config_global
265
+ end
266
+
267
+ # This defines a hook point where plugin action hooks that are registered
268
+ # against the given name will be run in the context of this environment.
269
+ #
270
+ # @param [Symbol] name Name of the hook.
271
+ def hook(name)
272
+ @logger.info("Running hook: #{name}")
273
+ callable = Action::Builder.new
274
+ action_runner.run(
275
+ callable,
276
+ :action_name => name,
277
+ :env => self)
278
+ end
279
+
280
+ # This returns a machine with the proper provider for this environment.
281
+ # The machine named by `name` must be in this environment.
282
+ #
283
+ # @param [Symbol] name Name of the machine (as configured in the
284
+ # Vagrantfile).
285
+ # @param [Symbol] provider The provider that this machine should be
286
+ # backed by.
287
+ # @param [Boolean] refresh If true, then if there is a cached version
288
+ # it is reloaded.
289
+ # @return [Machine]
290
+ def machine(name, provider, refresh=false)
291
+ @logger.info("Getting machine: #{name} (#{provider})")
292
+
293
+ # Compose the cache key of the name and provider, and return from
294
+ # the cache if we have that.
295
+ cache_key = [name, provider]
296
+ @machines ||= {}
297
+ if refresh
298
+ @logger.info("Refreshing machine (busting cache): #{name} (#{provider})")
299
+ @machines.delete(cache_key)
300
+ end
301
+
302
+ if @machines.has_key?(cache_key)
303
+ @logger.info("Returning cached machine: #{name} (#{provider})")
304
+ return @machines[cache_key]
305
+ end
306
+
307
+ @logger.info("Uncached load of machine.")
308
+ sub_vm = config_global.vm.defined_vms[name]
309
+ if !sub_vm
310
+ raise Errors::MachineNotFound, :name => name, :provider => provider
311
+ end
312
+
313
+ provider_plugin = Vagrant.plugin("2").manager.providers[provider]
314
+ if !provider_plugin
315
+ raise Errors::ProviderNotFound, :machine => name, :provider => provider
316
+ end
317
+
318
+ # Extra the provider class and options from the plugin data
319
+ provider_cls = provider_plugin[0]
320
+ provider_options = provider_plugin[1]
321
+
322
+ # Build the machine configuration. This requires two passes: The first pass
323
+ # loads in the machine sub-configuration. Since this can potentially
324
+ # define a new box to base the machine from, we then make a second pass
325
+ # with the box Vagrantfile (if it has one).
326
+ vm_config_key = "vm_#{name}".to_sym
327
+ @config_loader.set(vm_config_key, sub_vm.config_procs)
328
+ config, config_warnings, config_errors = \
329
+ @config_loader.load([:default, :home, :root, vm_config_key])
330
+
331
+ # Determine the possible box formats for any boxes and find the box
332
+ box_formats = provider_options[:box_format] || provider
333
+ box = nil
334
+
335
+ # Set this variable in order to keep track of if the box changes
336
+ # too many times.
337
+ original_box = config.vm.box
338
+ box_changed = false
339
+
340
+ load_box_and_overrides = lambda do
341
+ box = find_box(config.vm.box, box_formats) if config.vm.box
342
+
343
+ # If a box was found, then we attempt to load the Vagrantfile for
344
+ # that box. We don't require a box since we allow providers to download
345
+ # boxes and so on.
346
+ if box
347
+ box_vagrantfile = find_vagrantfile(box.directory)
348
+ if box_vagrantfile
349
+ # The box has a custom Vagrantfile, so we load that into the config
350
+ # as well.
351
+ @logger.info("Box exists with Vagrantfile. Reloading machine config.")
352
+ box_config_key = "box_#{box.name}_#{box.provider}".to_sym
353
+ @config_loader.set(box_config_key, box_vagrantfile)
354
+ config, config_warnings, config_errors = \
355
+ @config_loader.load([:default, box_config_key, :home, :root, vm_config_key])
356
+ end
357
+ end
358
+
359
+ # If there are provider overrides for the machine, then we run
360
+ # those as well.
361
+ provider_overrides = config.vm.get_provider_overrides(provider)
362
+ if provider_overrides.length > 0
363
+ @logger.info("Applying #{provider_overrides.length} provider overrides. Reloading config.")
364
+ provider_override_key = "vm_#{name}_#{config.vm.box}_#{provider}".to_sym
365
+ @config_loader.set(provider_override_key, provider_overrides)
366
+ config, config_warnings, config_errors = \
367
+ @config_loader.load([:default, box_config_key, :home, :root, vm_config_key, provider_override_key])
368
+ end
369
+
370
+ if config.vm.box && original_box != config.vm.box
371
+ if box_changed
372
+ # We already changed boxes once, so report an error that a
373
+ # box is attempting to change boxes again.
374
+ raise Errors::BoxConfigChangingBox
375
+ end
376
+
377
+ # The box changed, probably due to the provider override. Let's
378
+ # run the configuration one more time with the new box.
379
+ @logger.info("Box changed to: #{config.vm.box}. Reloading configurations.")
380
+ original_box = config.vm.box
381
+ box_changed = true
382
+
383
+ # Recurse so that we reload all the configurations
384
+ load_box_and_overrides.call
385
+ end
386
+ end
387
+
388
+ # Load the box and overrides configuration
389
+ load_box_and_overrides.call
390
+
391
+ # Get the provider configuration from the final loaded configuration
392
+ provider_config = config.vm.get_provider_config(provider)
393
+
394
+ # Determine the machine data directory and pass it to the machine.
395
+ # XXX: Permissions error here.
396
+ machine_data_path = @local_data_path.join("machines/#{name}/#{provider}")
397
+ FileUtils.mkdir_p(machine_data_path)
398
+
399
+ # If there were warnings or errors we want to output them
400
+ if !config_warnings.empty? || !config_errors.empty?
401
+ # The color of the output depends on whether we have warnings
402
+ # or errors...
403
+ level = config_errors.empty? ? :warn : :error
404
+ output = Util::TemplateRenderer.render(
405
+ "config/messages",
406
+ :warnings => config_warnings,
407
+ :errors => config_errors).chomp
408
+ @ui.send(level, I18n.t("vagrant.general.config_upgrade_messages",
409
+ :output => output))
410
+
411
+ # If we had errors, then we bail
412
+ raise Errors::ConfigUpgradeErrors if !config_errors.empty?
413
+ end
414
+
415
+ # Create the machine and cache it for future calls. This will also
416
+ # return the machine from this method.
417
+ @machines[cache_key] = Machine.new(name, provider, provider_cls, provider_config,
418
+ provider_options, config, machine_data_path, box, self)
419
+ end
420
+
421
+ # This returns a list of the configured machines for this environment.
422
+ # Each of the names returned by this method is valid to be used with
423
+ # the {#machine} method.
424
+ #
425
+ # @return [Array<Symbol>] Configured machine names.
426
+ def machine_names
427
+ config_global.vm.defined_vm_keys.dup
428
+ end
429
+
430
+ # This returns the name of the machine that is the "primary." In the
431
+ # case of a single-machine environment, this is just the single machine
432
+ # name. In the case of a multi-machine environment, then this can
433
+ # potentially be nil if no primary machine is specified.
434
+ #
435
+ # @return [Symbol]
436
+ def primary_machine_name
437
+ # If it is a single machine environment, then return the name
438
+ return machine_names.first if machine_names.length == 1
439
+
440
+ # If it is a multi-machine environment, then return the primary
441
+ config_global.vm.defined_vms.each do |name, subvm|
442
+ return name if subvm.options[:primary]
443
+ end
444
+
445
+ # If no primary was specified, nil it is
446
+ nil
447
+ end
448
+
449
+ # Unload the environment, running completion hooks. The environment
450
+ # should not be used after this (but CAN be, technically). It is
451
+ # recommended to always immediately set the variable to `nil` after
452
+ # running this so you can't accidentally run any more methods. Example:
453
+ #
454
+ # env.unload
455
+ # env = nil
456
+ #
457
+ def unload
458
+ hook(:environment_unload)
459
+ end
460
+
461
+ # Makes a call to the CLI with the given arguments as if they
462
+ # came from the real command line (sometimes they do!). An example:
463
+ #
464
+ # env.cli("package", "--vagrantfile", "Vagrantfile")
465
+ #
466
+ def cli(*args)
467
+ CLI.new(args.flatten, self).execute
468
+ end
469
+
470
+ # Returns the host object associated with this environment.
471
+ #
472
+ # @return [Class]
473
+ def host
474
+ return @host if defined?(@host)
475
+
476
+ # Attempt to figure out the host class. Note that the order
477
+ # matters here, so please don't touch. Specifically: The symbol
478
+ # check is done after the detect check because the symbol check
479
+ # will return nil, and we don't want to trigger a detect load.
480
+ host_klass = config_global.vagrant.host
481
+ if host_klass.nil? || host_klass == :detect
482
+ hosts = Vagrant.plugin("2").manager.hosts.to_hash
483
+
484
+ # Get the flattened list of available hosts
485
+ host_klass = Hosts.detect(hosts)
486
+ end
487
+
488
+ # If no host class is detected, we use the base class.
489
+ host_klass ||= Vagrant.plugin("2", :host)
490
+
491
+ @host ||= host_klass.new(@ui)
492
+ end
493
+
494
+ # Action runner for executing actions in the context of this environment.
495
+ #
496
+ # @return [Action::Runner]
497
+ def action_runner
498
+ @action_runner ||= Action::Runner.new do
499
+ {
500
+ :action_runner => action_runner,
501
+ :box_collection => boxes,
502
+ :global_config => config_global,
503
+ :host => host,
504
+ :gems_path => gems_path,
505
+ :home_path => home_path,
506
+ :root_path => root_path,
507
+ :tmp_path => tmp_path,
508
+ :ui => @ui
509
+ }
510
+ end
511
+ end
512
+
513
+ # The root path is the path where the top-most (loaded last)
514
+ # Vagrantfile resides. It can be considered the project root for
515
+ # this environment.
516
+ #
517
+ # @return [String]
518
+ def root_path
519
+ return @root_path if defined?(@root_path)
520
+
521
+ root_finder = lambda do |path|
522
+ # Note: To remain compatible with Ruby 1.8, we have to use
523
+ # a `find` here instead of an `each`.
524
+ found = vagrantfile_name.find do |rootfile|
525
+ File.exist?(File.join(path.to_s, rootfile))
526
+ end
527
+
528
+ return path if found
529
+ return nil if path.root? || !File.exist?(path)
530
+ root_finder.call(path.parent)
531
+ end
532
+
533
+ @root_path = root_finder.call(cwd)
534
+ end
535
+
536
+ # This returns the path which Vagrant uses to determine the location
537
+ # of the file lock. This is specific to each operating system.
538
+ def lock_path
539
+ @lock_path || tmp_path.join("vagrant.lock")
540
+ end
541
+
542
+ # This locks Vagrant for the duration of the block passed to this
543
+ # method. During this time, any other environment which attempts
544
+ # to lock which points to the same lock file will fail.
545
+ def lock
546
+ # This allows multiple locks in the same process to be nested
547
+ return yield if @lock_acquired
548
+
549
+ File.open(lock_path, "w+") do |f|
550
+ # The file locking fails only if it returns "false." If it
551
+ # succeeds it returns a 0, so we must explicitly check for
552
+ # the proper error case.
553
+ raise Errors::EnvironmentLockedError if f.flock(File::LOCK_EX | File::LOCK_NB) === false
554
+
555
+ begin
556
+ # Mark that we have a lock
557
+ @lock_acquired = true
558
+
559
+ yield
560
+ ensure
561
+ # We need to make sure that no matter what this is always
562
+ # reset to false so we don't think we have a lock when we
563
+ # actually don't.
564
+ @lock_acquired = false
565
+ end
566
+ end
567
+ end
568
+
569
+ #---------------------------------------------------------------
570
+ # Load Methods
571
+ #---------------------------------------------------------------
572
+
573
+ # This sets the `@home_path` variable properly.
574
+ #
575
+ # @return [Pathname]
576
+ def setup_home_path
577
+ @home_path = Pathname.new(File.expand_path(@home_path ||
578
+ ENV["VAGRANT_HOME"] ||
579
+ default_home_path))
580
+ @logger.info("Home path: #{@home_path}")
581
+
582
+ # Setup the list of child directories that need to be created if they
583
+ # don't already exist.
584
+ dirs = [@home_path]
585
+ subdirs = ["boxes", "data", "gems", "rgloader", "tmp"]
586
+ dirs += subdirs.collect { |subdir| @home_path.join(subdir) }
587
+
588
+ # Go through each required directory, creating it if it doesn't exist
589
+ dirs.each do |dir|
590
+ next if File.directory?(dir)
591
+
592
+ begin
593
+ @logger.info("Creating: #{dir}")
594
+ FileUtils.mkdir_p(dir)
595
+ rescue Errno::EACCES
596
+ raise Errors::HomeDirectoryNotAccessible, :home_path => @home_path.to_s
597
+ end
598
+ end
599
+
600
+ # Create the version file to mark the version of the home directory
601
+ # we're using.
602
+ version_file = @home_path.join("setup_version")
603
+ if !version_file.file?
604
+ @logger.debug("Setting up the version file.")
605
+ version_file.open("w") do |f|
606
+ f.write("1.1")
607
+ end
608
+ end
609
+
610
+ # Create the rgloader/loader file so we can use encoded files.
611
+ loader_file = @home_path.join("rgloader", "loader.rb")
612
+ if !loader_file.file?
613
+ source_loader = Vagrant.source_root.join("templates/rgloader.rb")
614
+ FileUtils.cp(source_loader.to_s, loader_file.to_s)
615
+ end
616
+ end
617
+
618
+ # This creates the local data directory and show an error if it
619
+ # couldn't properly be created.
620
+ def setup_local_data_path
621
+ if @local_data_path.nil?
622
+ @logger.warn("No local data path is set. Local data cannot be stored.")
623
+ return
624
+ end
625
+
626
+ @logger.info("Local data path: #{@local_data_path}")
627
+
628
+ # If the local data path is a file, then we are probably seeing an
629
+ # old (V1) "dotfile." In this case, we upgrade it. The upgrade process
630
+ # will remove the old data file if it is successful.
631
+ if @local_data_path.file?
632
+ upgrade_v1_dotfile(@local_data_path)
633
+ end
634
+
635
+ begin
636
+ @logger.debug("Creating: #{@local_data_path}")
637
+ FileUtils.mkdir_p(@local_data_path)
638
+ rescue Errno::EACCES
639
+ raise Errors::LocalDataDirectoryNotAccessible,
640
+ :local_data_path => @local_data_path.to_s
641
+ end
642
+ end
643
+
644
+ protected
645
+
646
+ # This method copies the private key into the home directory if it
647
+ # doesn't already exist.
648
+ #
649
+ # This must be done because `ssh` requires that the key is chmod
650
+ # 0600, but if Vagrant is installed as a separate user, then the
651
+ # effective uid won't be able to read the key. So the key is copied
652
+ # to the home directory and chmod 0600.
653
+ def copy_insecure_private_key
654
+ if !@default_private_key_path.exist?
655
+ @logger.info("Copying private key to home directory")
656
+
657
+ source = File.expand_path("keys/vagrant", Vagrant.source_root)
658
+ destination = @default_private_key_path
659
+
660
+ begin
661
+ FileUtils.cp(source, destination)
662
+ rescue Errno::EACCES
663
+ raise Errors::CopyPrivateKeyFailed,
664
+ :source => source,
665
+ :destination => destination
666
+ end
667
+ end
668
+
669
+ if !Util::Platform.windows?
670
+ # On Windows, permissions don't matter as much, so don't worry
671
+ # about doing chmod.
672
+ if Util::FileMode.from_octal(@default_private_key_path.stat.mode) != "600"
673
+ @logger.info("Changing permissions on private key to 0600")
674
+ @default_private_key_path.chmod(0600)
675
+ end
676
+ end
677
+ end
678
+
679
+ # This returns the default home directory path for Vagrant, which
680
+ # can differ depending on the system.
681
+ #
682
+ # @return [Pathname]
683
+ def default_home_path
684
+ path = "~/.vagrant.d"
685
+
686
+ # On Windows, we default ot the USERPROFILE directory if it
687
+ # is available. This is more compatible with Cygwin and sharing
688
+ # the home directory across shells.
689
+ if Util::Platform.windows? && ENV["USERPROFILE"]
690
+ path = "#{ENV["USERPROFILE"]}/.vagrant.d"
691
+ end
692
+
693
+ Pathname.new(path)
694
+ end
695
+
696
+ # This finds a box for the given name and formats, or returns nil
697
+ # if the box isn't found.
698
+ #
699
+ # @param [String] name Name of the box
700
+ # @param [Array<Symbol>] formats The formats to search for the box.
701
+ # @return [Box]
702
+ def find_box(name, formats)
703
+ # Determine the box formats we support
704
+ formats = [formats] if !formats.is_a?(Array)
705
+
706
+ @logger.info("Provider-supported box formats: #{formats.inspect}")
707
+ formats.each do |format|
708
+ box = nil
709
+
710
+ begin
711
+ box = boxes.find(name, format.to_s)
712
+ rescue Errors::BoxUpgradeRequired
713
+ # Upgrade the box if we must
714
+ @logger.info("Upgrading box during config load: #{name}")
715
+ boxes.upgrade(name)
716
+ retry
717
+ end
718
+
719
+ # If a box was found, we exit
720
+ if box
721
+ @logger.info("Box found with format: #{format}")
722
+ return box
723
+ end
724
+ end
725
+
726
+ nil
727
+ end
728
+
729
+ # Finds the Vagrantfile in the given directory.
730
+ #
731
+ # @param [Pathname] path Path to search in.
732
+ # @return [Pathname]
733
+ def find_vagrantfile(search_path)
734
+ @vagrantfile_name.each do |vagrantfile|
735
+ current_path = search_path.join(vagrantfile)
736
+ return current_path if current_path.exist?
737
+ end
738
+
739
+ nil
740
+ end
741
+
742
+ # Loads the Vagrant plugins by properly setting up RubyGems so that
743
+ # our private gem repository is on the path.
744
+ def load_plugins
745
+ # Add our private gem path to the gem path and reset the paths
746
+ # that Rubygems knows about.
747
+ ENV["GEM_PATH"] = "#{@gems_path}#{::File::PATH_SEPARATOR}#{ENV["GEM_PATH"]}"
748
+ ::Gem.clear_paths
749
+
750
+ # If we're in a Bundler environment, don't load plugins. This only
751
+ # happens in plugin development environments.
752
+ if defined?(Bundler)
753
+ require 'bundler/shared_helpers'
754
+ if Bundler::SharedHelpers.in_bundle?
755
+ @logger.warn("In a bundler environment, not loading environment plugins!")
756
+ return
757
+ end
758
+ end
759
+
760
+ # Load the plugins
761
+ plugins_json_file = @home_path.join("plugins.json")
762
+ @logger.debug("Loading plugins from: #{plugins_json_file}")
763
+ if plugins_json_file.file?
764
+ data = JSON.parse(plugins_json_file.read)
765
+ data["installed"].each do |plugin|
766
+ @logger.info("Loading plugin from JSON: #{plugin}")
767
+ begin
768
+ Vagrant.require_plugin(plugin)
769
+ rescue Errors::PluginLoadError => e
770
+ @ui.error(e.message + "\n")
771
+ rescue Errors::PluginLoadFailed => e
772
+ @ui.error(e.message + "\n")
773
+ end
774
+ end
775
+ end
776
+ end
777
+
778
+ # This upgrades a Vagrant 1.0.x "dotfile" to the new V2 format.
779
+ #
780
+ # This is a destructive process. Once the upgrade is complete, the
781
+ # old dotfile is removed, and the environment becomes incompatible for
782
+ # Vagrant 1.0 environments.
783
+ #
784
+ # @param [Pathname] path The path to the dotfile
785
+ def upgrade_v1_dotfile(path)
786
+ @logger.info("Upgrading V1 dotfile to V2 directory structure...")
787
+
788
+ # First, verify the file isn't empty. If it is an empty file, we
789
+ # just delete it and go on with life.
790
+ contents = path.read.strip
791
+ if contents.strip == ""
792
+ @logger.info("V1 dotfile was empty. Removing and moving on.")
793
+ path.delete
794
+ return
795
+ end
796
+
797
+ # Otherwise, verify there is valid JSON in here since a Vagrant
798
+ # environment would always ensure valid JSON. This is a sanity check
799
+ # to make sure we don't nuke a dotfile that is not ours...
800
+ @logger.debug("Attempting to parse JSON of V1 file")
801
+ json_data = nil
802
+ begin
803
+ json_data = JSON.parse(contents)
804
+ @logger.debug("JSON parsed successfully. Things are okay.")
805
+ rescue JSON::ParserError
806
+ # The file could've been tampered with since Vagrant 1.0.x is
807
+ # supposed to ensure that the contents are valid JSON. Show an error.
808
+ raise Errors::DotfileUpgradeJSONError,
809
+ :state_file => path.to_s
810
+ end
811
+
812
+ # Alright, let's upgrade this guy to the new structure. Start by
813
+ # backing up the old dotfile.
814
+ backup_file = path.dirname.join(".vagrant.v1.#{Time.now.to_i}")
815
+ @logger.info("Renaming old dotfile to: #{backup_file}")
816
+ path.rename(backup_file)
817
+
818
+ # Now, we create the actual local data directory. This should succeed
819
+ # this time since we renamed the old conflicting V1.
820
+ setup_local_data_path
821
+
822
+ if json_data["active"]
823
+ @logger.debug("Upgrading to V2 style for each active VM")
824
+ json_data["active"].each do |name, id|
825
+ @logger.info("Upgrading dotfile: #{name} (#{id})")
826
+
827
+ # Create the machine configuration directory
828
+ directory = @local_data_path.join("machines/#{name}/virtualbox")
829
+ FileUtils.mkdir_p(directory)
830
+
831
+ # Write the ID file
832
+ directory.join("id").open("w+") do |f|
833
+ f.write(id)
834
+ end
835
+ end
836
+ end
837
+
838
+ # Upgrade complete! Let the user know
839
+ @ui.info(I18n.t("vagrant.general.upgraded_v1_dotfile",
840
+ :backup_path => backup_file.to_s))
841
+ end
842
+ end
843
+ end