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,113 @@
1
+ require 'thread'
2
+
3
+ require "log4r"
4
+
5
+ module Vagrant
6
+ # This class executes multiple actions as a single batch, parallelizing
7
+ # the action calls if possible.
8
+ class BatchAction
9
+ def initialize(allow_parallel=true)
10
+ @actions = []
11
+ @allow_parallel = allow_parallel
12
+ @logger = Log4r::Logger.new("vagrant::batch_action")
13
+ end
14
+
15
+ # Add an action to the batch of actions that will be run.
16
+ #
17
+ # This will **not** run the action now. The action will be run
18
+ # when {#run} is called.
19
+ #
20
+ # @param [Machine] machine The machine to run the action on
21
+ # @param [Symbol] action The action to run
22
+ # @param [Hash] options Any additional options to send in.
23
+ def action(machine, action, options=nil)
24
+ @actions << [machine, action, options]
25
+ end
26
+
27
+ # Run all the queued up actions, parallelizing if possible.
28
+ #
29
+ # This will parallelize if and only if the provider of every machine
30
+ # supports parallelization and parallelization is possible from
31
+ # initialization of the class.
32
+ def run
33
+ par = false
34
+
35
+ if @allow_parallel
36
+ par = true
37
+ @logger.info("Enabling parallelization by default.")
38
+ end
39
+
40
+ if par
41
+ @actions.each do |machine, _, _|
42
+ if !machine.provider_options[:parallel]
43
+ @logger.info("Disabling parallelization because provider doesn't support it: #{machine.provider_name}")
44
+ par = false
45
+ break
46
+ end
47
+ end
48
+ end
49
+
50
+ @logger.info("Batch action will parallelize: #{par.inspect}")
51
+
52
+ threads = []
53
+ @actions.each do |machine, action, options|
54
+ @logger.info("Starting action: #{machine} #{action} #{options}")
55
+
56
+ # Create the new thread to run our action. This is basically just
57
+ # calling the action but also contains some error handling in it
58
+ # as well.
59
+ thread = Thread.new do
60
+ Thread.current[:error] = nil
61
+
62
+ begin
63
+ machine.send(:action, action, options)
64
+ rescue Exception => e
65
+ # If we're not parallelizing, then raise the error
66
+ raise if !par
67
+
68
+ # Store the exception that will be processed later
69
+ Thread.current[:error] = e
70
+ end
71
+ end
72
+
73
+ # Set some attributes on the thread for later
74
+ thread[:machine] = machine
75
+
76
+ thread.join if !par
77
+ threads << thread
78
+ end
79
+
80
+ errors = []
81
+
82
+ threads.each do |thread|
83
+ # Wait for the thread to complete
84
+ thread.join
85
+
86
+ # If the thread had an error, then store the error to show later
87
+ if thread[:error]
88
+ e = thread[:error]
89
+ # If the error isn't a Vagrant error, then store the backtrace
90
+ # as well.
91
+ if !thread[:error].is_a?(Errors::VagrantError)
92
+ e = thread[:error]
93
+ message = e.message
94
+ message += "\n"
95
+ message += "\n#{e.backtrace.join("\n")}"
96
+
97
+ errors << I18n.t("vagrant.general.batch_unexpected_error",
98
+ :machine => thread[:machine].name,
99
+ :message => message)
100
+ else
101
+ errors << I18n.t("vagrant.general.batch_vagrant_error",
102
+ :machine => thread[:machine].name,
103
+ :message => thread[:error].message)
104
+ end
105
+ end
106
+ end
107
+
108
+ if !errors.empty?
109
+ raise Errors::BatchMultiError, :message => errors.join("\n\n")
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,97 @@
1
+ require 'fileutils'
2
+
3
+ require "json"
4
+ require "log4r"
5
+
6
+ require "vagrant/util/platform"
7
+ require "vagrant/util/safe_chdir"
8
+ require "vagrant/util/subprocess"
9
+
10
+ module Vagrant
11
+ # Represents a "box," which is a package Vagrant environment that is used
12
+ # as a base image when creating a new guest machine.
13
+ class Box
14
+ include Comparable
15
+
16
+ # The box name. This is the logical name used when adding the box.
17
+ #
18
+ # @return [String]
19
+ attr_reader :name
20
+
21
+ # This is the provider that this box is built for.
22
+ #
23
+ # @return [Symbol]
24
+ attr_reader :provider
25
+
26
+ # This is the directory on disk where this box exists.
27
+ #
28
+ # @return [Pathname]
29
+ attr_reader :directory
30
+
31
+ # This is the metadata for the box. This is read from the "metadata.json"
32
+ # file that all boxes require.
33
+ #
34
+ # @return [Hash]
35
+ attr_reader :metadata
36
+
37
+ # This is used to initialize a box.
38
+ #
39
+ # @param [String] name Logical name of the box.
40
+ # @param [Symbol] provider The provider that this box implements.
41
+ # @param [Pathname] directory The directory where this box exists on
42
+ # disk.
43
+ def initialize(name, provider, directory)
44
+ @name = name
45
+ @provider = provider
46
+ @directory = directory
47
+
48
+ metadata_file = directory.join("metadata.json")
49
+ raise Errors::BoxMetadataFileNotFound, :name => @name if !metadata_file.file?
50
+ @metadata = JSON.parse(directory.join("metadata.json").read)
51
+
52
+ @logger = Log4r::Logger.new("vagrant::box")
53
+ end
54
+
55
+ # This deletes the box. This is NOT undoable.
56
+ def destroy!
57
+ # Delete the directory to delete the box.
58
+ FileUtils.rm_r(@directory)
59
+
60
+ # Just return true always
61
+ true
62
+ rescue Errno::ENOENT
63
+ # This means the directory didn't exist. Not a problem.
64
+ return true
65
+ end
66
+
67
+ # This repackages this box and outputs it to the given path.
68
+ #
69
+ # @param [Pathname] path The full path (filename included) of where
70
+ # to output this box.
71
+ # @return [Boolean] true if this succeeds.
72
+ def repackage(path)
73
+ @logger.debug("Repackaging box '#{@name}' to: #{path}")
74
+
75
+ Util::SafeChdir.safe_chdir(@directory) do
76
+ # Find all the files in our current directory and tar it up!
77
+ files = Dir.glob(File.join(".", "**", "*"))
78
+
79
+ # Package!
80
+ Util::Subprocess.execute("bsdtar", "-czf", path.to_s, *files)
81
+ end
82
+
83
+ @logger.info("Repackaged box '#{@name}' successfully: #{path}")
84
+
85
+ true
86
+ end
87
+
88
+ # Implemented for comparison with other boxes. Comparison is
89
+ # implemented by comparing names and providers.
90
+ def <=>(other)
91
+ return super if !other.is_a?(self.class)
92
+
93
+ # Comparison is done by composing the name and provider
94
+ "#{@name}-#{@provider}" <=> "#{other.name}-#{other.provider}"
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,375 @@
1
+ require "digest/sha1"
2
+ require "thread"
3
+ require "tmpdir"
4
+
5
+ require "log4r"
6
+
7
+ require "vagrant/util/subprocess"
8
+
9
+ module Vagrant
10
+ # Represents a collection a boxes found on disk. This provides methods
11
+ # for accessing/finding individual boxes, adding new boxes, or deleting
12
+ # boxes.
13
+ class BoxCollection
14
+ TEMP_PREFIX = "vagrant-box-add-temp-"
15
+
16
+ # The directory where the boxes in this collection are stored.
17
+ #
18
+ # A box collection matches a very specific folder structure that Vagrant
19
+ # expects in order to easily manage and modify boxes. The folder structure
20
+ # is the following:
21
+ #
22
+ # COLLECTION_ROOT/BOX_NAME/PROVIDER/metadata.json
23
+ #
24
+ # Where:
25
+ #
26
+ # * COLLECTION_ROOT - This is the root of the box collection, and is
27
+ # the directory given to the initializer.
28
+ # * BOX_NAME - The name of the box. This is a logical name given by
29
+ # the user of Vagrant.
30
+ # * PROVIDER - The provider that the box was built for (VirtualBox,
31
+ # VMWare, etc.).
32
+ # * metadata.json - A simple JSON file that at the bare minimum
33
+ # contains a "provider" key that matches the provider for the
34
+ # box. This metadata JSON, however, can contain anything.
35
+ #
36
+ # @return [Pathname]
37
+ attr_reader :directory
38
+
39
+ # Initializes the collection.
40
+ #
41
+ # @param [Pathname] directory The directory that contains the collection
42
+ # of boxes.
43
+ def initialize(directory, options=nil)
44
+ options ||= {}
45
+
46
+ @directory = directory
47
+ @lock = Mutex.new
48
+ @temp_root = options[:temp_dir_root]
49
+ @logger = Log4r::Logger.new("vagrant::box_collection")
50
+ end
51
+
52
+ # This adds a new box to the system.
53
+ #
54
+ # There are some exceptional cases:
55
+ # * BoxAlreadyExists - The box you're attempting to add already exists.
56
+ # * BoxProviderDoesntMatch - If the given box provider doesn't match the
57
+ # actual box provider in the untarred box.
58
+ # * BoxUnpackageFailure - An invalid tar file.
59
+ # * BoxUpgradeRequired - You're attempting to add a box when there is a
60
+ # V1 box with the same name that must first be upgraded.
61
+ #
62
+ # Preconditions:
63
+ # * File given in `path` must exist.
64
+ #
65
+ # @param [Pathname] path Path to the box file on disk.
66
+ # @param [String] name Logical name for the box.
67
+ # @param [Symbol] provider The provider that the box should be for. This
68
+ # will be verified with the `metadata.json` file in the box and is
69
+ # meant as a basic check. If this isn't given, then whatever provider
70
+ # the box represents will be added.
71
+ # @param [Boolean] force If true, any existing box with the same name
72
+ # and provider will be replaced.
73
+ def add(path, name, provider=nil, force=false)
74
+ with_collection_lock do
75
+ # A helper to check if a box exists. We store this in a variable
76
+ # since we call it multiple times.
77
+ check_box_exists = lambda do |box_provider|
78
+ box = find(name, box_provider)
79
+ next if !box
80
+
81
+ if !force
82
+ @logger.error("Box already exists, can't add: #{name} #{box_provider}")
83
+ raise Errors::BoxAlreadyExists, :name => name, :provider => box_provider
84
+ end
85
+
86
+ # We're forcing, so just delete the old box
87
+ @logger.info("Box already exists, but forcing so removing: #{name} #{box_provider}")
88
+ box.destroy!
89
+ end
90
+
91
+ log_provider = provider ? provider : "any provider"
92
+ @logger.debug("Adding box: #{name} (#{log_provider}) from #{path}")
93
+
94
+ # Verify the box doesn't exist early if we're given a provider. This
95
+ # can potentially speed things up considerably since we don't need
96
+ # to unpack any files.
97
+ check_box_exists.call(provider) if provider
98
+
99
+ # Verify that a V1 box doesn't exist. If it does, then we signal
100
+ # to the user that we need an upgrade.
101
+ raise Errors::BoxUpgradeRequired, :name => name if v1_box?(@directory.join(name))
102
+
103
+ # Create a temporary directory since we're not sure at this point if
104
+ # the box we're unpackaging already exists (if no provider was given)
105
+ with_temp_dir do |temp_dir|
106
+ # Extract the box into a temporary directory.
107
+ @logger.debug("Unpacking box into temporary directory: #{temp_dir}")
108
+ result = Util::Subprocess.execute(
109
+ "bsdtar", "-v", "-x", "-m", "-C", temp_dir.to_s, "-f", path.to_s)
110
+ raise Errors::BoxUnpackageFailure, :output => result.stderr.to_s if result.exit_code != 0
111
+
112
+ # If we get a V1 box, we want to update it in place
113
+ if v1_box?(temp_dir)
114
+ @logger.debug("Added box is a V1 box. Upgrading in place.")
115
+ temp_dir = v1_upgrade(temp_dir)
116
+ end
117
+
118
+ # We re-wrap ourselves in the safety net in case we upgraded.
119
+ # If we didn't upgrade, then this is still safe because the
120
+ # helper will only delete the directory if it exists
121
+ with_temp_dir(temp_dir) do |final_temp_dir|
122
+ # Get an instance of the box we just added before it is finalized
123
+ # in the system so we can inspect and use its metadata.
124
+ box = Box.new(name, provider, final_temp_dir)
125
+
126
+ # Get the provider, since we'll need that to at the least add it
127
+ # to the system or check that it matches what is given to us.
128
+ box_provider = box.metadata["provider"]
129
+
130
+ if provider
131
+ # Verify that the given provider matches what the box has.
132
+ if box_provider.to_sym != provider
133
+ @logger.error("Added box provider doesnt match expected: #{box_provider}")
134
+ raise Errors::BoxProviderDoesntMatch, :expected => provider, :actual => box_provider
135
+ end
136
+ else
137
+ # We weren't given a provider, so store this one.
138
+ provider = box_provider.to_sym
139
+
140
+ # Verify the box doesn't already exist
141
+ check_box_exists.call(provider)
142
+ end
143
+
144
+ # Create the directory for this box, not including the provider
145
+ box_dir = @directory.join(name)
146
+ box_dir.mkpath
147
+ @logger.debug("Box directory: #{box_dir}")
148
+
149
+ # This is the final directory we'll move it to
150
+ final_dir = box_dir.join(provider.to_s)
151
+ if final_dir.exist?
152
+ @logger.debug("Removing existing provider directory...")
153
+ final_dir.rmtree
154
+ end
155
+
156
+ # Move to final destination
157
+ final_dir.mkpath
158
+
159
+ # Go through each child and copy them one-by-one. This avoids
160
+ # an issue where on Windows cross-device directory copies are
161
+ # failing for some reason. [GH-1424]
162
+ final_temp_dir.children(true).each do |f|
163
+ destination = final_dir.join(f.basename)
164
+ @logger.debug("Moving: #{f} => #{destination}")
165
+ FileUtils.mv(f, destination)
166
+ end
167
+ end
168
+ end
169
+ end
170
+
171
+ # Return the box
172
+ find(name, provider)
173
+ end
174
+
175
+ # This returns an array of all the boxes on the system, given by
176
+ # their name and their provider.
177
+ #
178
+ # @return [Array] Array of `[name, provider]` pairs of the boxes
179
+ # installed on this system. An optional third element in the array
180
+ # may specify `:v1` if the box is a version 1 box.
181
+ def all
182
+ results = []
183
+
184
+ with_collection_lock do
185
+ @logger.debug("Finding all boxes in: #{@directory}")
186
+ @directory.children(true).each do |child|
187
+ # Ignore non-directories, since files are not interesting to
188
+ # us in our folder structure.
189
+ next if !child.directory?
190
+
191
+ box_name = child.basename.to_s
192
+
193
+ # If this is a V1 box, we still return that name, but specify
194
+ # that the box is a V1 box.
195
+ if v1_box?(child)
196
+ @logger.debug("V1 box found: #{box_name}")
197
+ results << [box_name, :virtualbox, :v1]
198
+ next
199
+ end
200
+
201
+ # Otherwise, traverse the subdirectories and see what providers
202
+ # we have.
203
+ child.children(true).each do |provider|
204
+ # Verify this is a potentially valid box. If it looks
205
+ # correct enough then include it.
206
+ if provider.directory? && provider.join("metadata.json").file?
207
+ provider_name = provider.basename.to_s.to_sym
208
+ @logger.debug("Box: #{box_name} (#{provider_name})")
209
+ results << [box_name, provider_name]
210
+ else
211
+ @logger.debug("Invalid box, ignoring: #{provider}")
212
+ end
213
+ end
214
+ end
215
+ end
216
+
217
+ results
218
+ end
219
+
220
+ # Find a box in the collection with the given name and provider.
221
+ #
222
+ # @param [String] name Name of the box (logical name).
223
+ # @Param [String] provider Provider that the box implements.
224
+ # @return [Box] The box found, or `nil` if not found.
225
+ def find(name, provider)
226
+ with_collection_lock do
227
+ # First look directly for the box we're asking for.
228
+ box_directory = @directory.join(name, provider.to_s, "metadata.json")
229
+ @logger.info("Searching for box: #{name} (#{provider}) in #{box_directory}")
230
+ if box_directory.file?
231
+ @logger.info("Box found: #{name} (#{provider})")
232
+ return Box.new(name, provider, box_directory.dirname)
233
+ end
234
+
235
+ # If we're looking for a VirtualBox box, then we check if there is
236
+ # a V1 box.
237
+ if provider == :virtualbox
238
+ # Check if a V1 version of this box exists, and if so, raise an
239
+ # exception notifying the caller that the box exists but needs
240
+ # to be upgraded. We don't do the upgrade here because it can be
241
+ # a fairly intensive activity and don't want to immediately degrade
242
+ # user performance on a find.
243
+ #
244
+ # To determine if it is a V1 box we just do a simple heuristic
245
+ # based approach.
246
+ @logger.info("Searching for V1 box: #{name}")
247
+ if v1_box?(@directory.join(name))
248
+ @logger.warn("V1 box found: #{name}")
249
+ raise Errors::BoxUpgradeRequired, :name => name
250
+ end
251
+ end
252
+ end
253
+
254
+ # Didn't find it, return nil
255
+ @logger.info("Box not found: #{name} (#{provider})")
256
+ nil
257
+ end
258
+
259
+ # Upgrades a V1 box with the given name to a V2 box. If a box with the
260
+ # given name doesn't exist, then a `BoxNotFound` exception will be raised.
261
+ # If the given box is found but is not a V1 box then `true` is returned
262
+ # because this just works fine.
263
+ #
264
+ # @return [Boolean] `true` otherwise an exception is raised.
265
+ def upgrade(name)
266
+ with_collection_lock do
267
+ @logger.debug("Upgrade request for box: #{name}")
268
+ box_dir = @directory.join(name)
269
+
270
+ # If the box doesn't exist at all, raise an exception
271
+ raise Errors::BoxNotFound, :name => name if !box_dir.directory?
272
+
273
+ if v1_box?(box_dir)
274
+ @logger.debug("V1 box #{name} found. Upgrading!")
275
+
276
+ # First we actually perform the upgrade
277
+ temp_dir = v1_upgrade(box_dir)
278
+
279
+ # Rename the temporary directory to the provider.
280
+ FileUtils.mv(temp_dir.to_s, box_dir.join("virtualbox").to_s)
281
+ @logger.info("Box '#{name}' upgraded from V1 to V2.")
282
+ end
283
+ end
284
+
285
+ # We did it! Or the v1 box didn't exist so it doesn't matter.
286
+ return true
287
+ end
288
+
289
+ protected
290
+
291
+ # This checks if the given directory represents a V1 box on the
292
+ # system.
293
+ #
294
+ # @param [Pathname] dir Directory where the box is unpacked.
295
+ # @return [Boolean]
296
+ def v1_box?(dir)
297
+ # We detect a V1 box given by whether there is a "box.ovf" which
298
+ # is a heuristic but is pretty accurate.
299
+ dir.join("box.ovf").file?
300
+ end
301
+
302
+ # This upgrades the V1 box contained unpacked in the given directory
303
+ # and returns the directory of the upgraded version. This is
304
+ # _destructive_ to the contents of the old directory. That is, the
305
+ # contents of the old V1 box will be destroyed or moved.
306
+ #
307
+ # Preconditions:
308
+ # * `dir` is a valid V1 box. Verify with {#v1_box?}
309
+ #
310
+ # @param [Pathname] dir Directory where the V1 box is unpacked.
311
+ # @return [Pathname] Path to the unpackaged V2 box.
312
+ def v1_upgrade(dir)
313
+ @logger.debug("Upgrading box in directory: #{dir}")
314
+
315
+ temp_dir = Pathname.new(Dir.mktmpdir(TEMP_PREFIX, @temp_root))
316
+ @logger.debug("Temporary directory for upgrading: #{temp_dir}")
317
+
318
+ # Move all the things into the temporary directory
319
+ dir.children(true).each do |child|
320
+ # Don't move the temp_dir
321
+ next if child == temp_dir
322
+
323
+ # Move every other directory into the temporary directory
324
+ @logger.debug("Copying to upgrade directory: #{child}")
325
+ FileUtils.mv(child, temp_dir.join(child.basename))
326
+ end
327
+
328
+ # If there is no metadata.json file, make one, since this is how
329
+ # we determine if the box is a V2 box.
330
+ metadata_file = temp_dir.join("metadata.json")
331
+ if !metadata_file.file?
332
+ metadata_file.open("w") do |f|
333
+ f.write(JSON.generate({
334
+ :provider => "virtualbox"
335
+ }))
336
+ end
337
+ end
338
+
339
+ # Return the temporary directory
340
+ temp_dir
341
+ end
342
+
343
+ # This locks the region given by the block with a lock on this
344
+ # collection.
345
+ def with_collection_lock
346
+ lock = @lock
347
+
348
+ begin
349
+ lock.synchronize {}
350
+ rescue ThreadError
351
+ # If we already hold the lock, just create a new lock so
352
+ # we definitely don't block and don't get an error.
353
+ lock = Mutex.new
354
+ end
355
+
356
+ lock.synchronize do
357
+ return yield
358
+ end
359
+ end
360
+
361
+ # This is a helper that makes sure that our temporary directories
362
+ # are cleaned up no matter what.
363
+ #
364
+ # @param [String] dir Path to a temporary directory
365
+ # @return [Object] The result of whatever the yield is
366
+ def with_temp_dir(dir=nil)
367
+ dir ||= Dir.mktmpdir(TEMP_PREFIX, @temp_root)
368
+ dir = Pathname.new(dir)
369
+
370
+ yield dir
371
+ ensure
372
+ dir.rmtree if dir.exist?
373
+ end
374
+ end
375
+ end
@@ -0,0 +1,82 @@
1
+ require 'log4r'
2
+ require 'optparse'
3
+
4
+ module Vagrant
5
+ # Manages the command line interface to Vagrant.
6
+ class CLI < Vagrant.plugin("2", :command)
7
+ def initialize(argv, env)
8
+ super
9
+
10
+ @logger = Log4r::Logger.new("vagrant::cli")
11
+ @main_args, @sub_command, @sub_args = split_main_and_subcommand(argv)
12
+
13
+ @logger.info("CLI: #{@main_args.inspect} #{@sub_command.inspect} #{@sub_args.inspect}")
14
+ end
15
+
16
+ def execute
17
+ if @main_args.include?("-v") || @main_args.include?("--version")
18
+ # Version short-circuits the whole thing. Just print
19
+ # the version and exit.
20
+ @env.ui.info(I18n.t("vagrant.commands.version.output",
21
+ :version => Vagrant::VERSION),
22
+ :prefix => false)
23
+
24
+ return 0
25
+ elsif @main_args.include?("-h") || @main_args.include?("--help")
26
+ # Help is next in short-circuiting everything. Print
27
+ # the help and exit.
28
+ help
29
+ return 0
30
+ end
31
+
32
+ # If we reached this far then we must have a subcommand. If not,
33
+ # then we also just print the help and exit.
34
+ command_class = nil
35
+ if @sub_command
36
+ command_class = Vagrant.plugin("2").manager.commands[@sub_command.to_sym]
37
+ end
38
+
39
+ if !command_class || !@sub_command
40
+ help
41
+ return 1
42
+ end
43
+ @logger.debug("Invoking command class: #{command_class} #{@sub_args.inspect}")
44
+
45
+ # Initialize and execute the command class, returning the exit status.
46
+ result = command_class.new(@sub_args, @env).execute
47
+ result = 0 if !result.is_a?(Fixnum)
48
+ return result
49
+ end
50
+
51
+ # This prints out the help for the CLI.
52
+ def help
53
+ # We use the optionparser for this. Its just easier. We don't use
54
+ # an optionparser above because I don't think the performance hits
55
+ # of creating a whole object are worth checking only a couple flags.
56
+ opts = OptionParser.new do |o|
57
+ o.banner = "Usage: vagrant [-v] [-h] command [<args>]"
58
+ o.separator ""
59
+ o.on("-v", "--version", "Print the version and exit.")
60
+ o.on("-h", "--help", "Print this help.")
61
+ o.separator ""
62
+ o.separator "Available subcommands:"
63
+
64
+ # Add the available subcommands as separators in order to print them
65
+ # out as well.
66
+ keys = []
67
+ Vagrant.plugin("2").manager.commands.each do |key, _|
68
+ keys << key
69
+ end
70
+
71
+ keys.sort.each do |key|
72
+ o.separator " #{key}"
73
+ end
74
+
75
+ o.separator ""
76
+ o.separator "For help on any individual command run `vagrant COMMAND -h`"
77
+ end
78
+
79
+ @env.ui.info(opts.help, :prefix => false)
80
+ end
81
+ end
82
+ end