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,67 @@
1
+ module Vagrant
2
+ module Action
3
+ module Builtin
4
+ # This middleware class allows a sort of "conditional" run within
5
+ # a single middlware sequence. It takes another middleware runnable,
6
+ # runs it with the same environment, then yields the resulting env to a block,
7
+ # allowing that block to determine the next course of action in the
8
+ # middleware sequence.
9
+ #
10
+ # The first argument to this middleware sequence is anywhere middleware
11
+ # runnable, whether it be a class, lambda, or something else that
12
+ # responds to `call`. This middleware runnable is run with the same
13
+ # environment as this class.
14
+ #
15
+ # After running, {Call} takes the environment and yields it to a block
16
+ # given to initialize the class, along with an instance of {Builder}.
17
+ # The result is used to build up a new sequence on the given builder.
18
+ # This builder is then run.
19
+ class Call
20
+ # For documentation, read the description of the {Call} class.
21
+ #
22
+ # @param [Object] callable A valid middleware runnable object. This
23
+ # can be a class, a lambda, or an object that responds to `call`.
24
+ # @yield [result, builder] This block is expected to build on `builder`
25
+ # which is the next middleware sequence that will be run.
26
+ def initialize(app, env, callable, *callable_args, &block)
27
+ raise ArgumentError, "A block must be given to Call" if !block
28
+
29
+ @app = app
30
+ @callable = callable
31
+ @callable_args = callable_args
32
+ @block = block
33
+ @child_app = nil
34
+ end
35
+
36
+ def call(env)
37
+ runner = Runner.new
38
+
39
+ # Build the callable that we'll run
40
+ callable = Builder.build(@callable, *@callable_args)
41
+
42
+ # Run our callable with our environment
43
+ new_env = runner.run(callable, env)
44
+
45
+ # Build our new builder based on the result
46
+ builder = Builder.new
47
+ @block.call(new_env, builder)
48
+
49
+ # Run the result with our new environment
50
+ @child_app = builder.to_app(new_env)
51
+ final_env = runner.run(@child_app, new_env)
52
+
53
+ # Merge the environment into our original environment
54
+ env.merge!(final_env)
55
+
56
+ # Call the next step using our final environment
57
+ @app.call(env)
58
+ end
59
+
60
+ def recover(env)
61
+ # Call back into our compiled application and recover it.
62
+ @child_app.recover(env) if @child_app
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,30 @@
1
+ require "vagrant/util/template_renderer"
2
+
3
+ module Vagrant
4
+ module Action
5
+ module Builtin
6
+ # This class validates the configuration and raises an exception
7
+ # if there are any validation errors.
8
+ class ConfigValidate
9
+ def initialize(app, env)
10
+ @app = app
11
+ end
12
+
13
+ def call(env)
14
+ if !env.has_key?(:config_validate) || env[:config_validate]
15
+ errors = env[:machine].config.validate(env[:machine])
16
+
17
+ if errors && !errors.empty?
18
+ raise Errors::ConfigInvalid,
19
+ :errors => Util::TemplateRenderer.render(
20
+ "config/validation_failed",
21
+ :errors => errors)
22
+ end
23
+ end
24
+
25
+ @app.call(env)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,38 @@
1
+ module Vagrant
2
+ module Action
3
+ module Builtin
4
+ # This class asks the user to confirm some sort of question with
5
+ # a "Y/N" question. The only parameter is the text to ask the user.
6
+ # The result is placed in `env[:result]` so that it can be used
7
+ # with the {Call} class.
8
+ class Confirm
9
+ # For documentation, read the description of the {Confirm} class.
10
+ #
11
+ # @param [String] message The message to ask the user.
12
+ # @param [Symbol] force_key The key that if present and true in
13
+ # the environment hash will skip the confirmation question.
14
+ def initialize(app, env, message, force_key=nil)
15
+ @app = app
16
+ @message = message
17
+ @force_key = force_key
18
+ end
19
+
20
+ def call(env)
21
+ choice = nil
22
+
23
+ # If we have a force key set and we're forcing, then set
24
+ # the result to "Y"
25
+ choice = "Y" if @force_key && env[@force_key]
26
+
27
+ # If we haven't chosen yes, then ask the user via TTY
28
+ choice = env[:ui].ask(@message) if !choice
29
+
30
+ # The result is only true if the user said "Y"
31
+ env[:result] = choice && choice.upcase == "Y"
32
+
33
+ @app.call(env)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,21 @@
1
+ require_relative "confirm"
2
+
3
+ module Vagrant
4
+ module Action
5
+ module Builtin
6
+ # This class asks the user to confirm the destruction of a machine
7
+ # that Vagrant manages. This is provided as a built-in on top of
8
+ # {Confirm} because it sets up the proper keys and such so that
9
+ # `vagrant destroy -f` works properly.
10
+ class DestroyConfirm < Confirm
11
+ def initialize(app, env)
12
+ force_key = :force_confirm_destroy
13
+ message = I18n.t("vagrant.commands.destroy.confirmation",
14
+ :name => env[:machine].name)
15
+
16
+ super(app, env, message, force_key)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,24 @@
1
+ module Vagrant
2
+ module Action
3
+ module Builtin
4
+ # This middleware class allows you to modify the environment hash
5
+ # in the middle of a middleware sequence. The new environmental data
6
+ # will take affect at this stage in the middleware and will persist
7
+ # through.
8
+ class EnvSet
9
+ def initialize(app, env, new_env=nil)
10
+ @app = app
11
+ @new_env = new_env || {}
12
+ end
13
+
14
+ def call(env)
15
+ # Merge in the new data
16
+ env.merge!(@new_env)
17
+
18
+ # Carry on
19
+ @app.call(env)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,73 @@
1
+ require "log4r"
2
+
3
+ module Vagrant
4
+ module Action
5
+ module Builtin
6
+ # This middleware class will attempt to perform a graceful shutdown
7
+ # of the machine using the guest implementation. This middleware is
8
+ # compatible with the {Call} middleware so you can branch based on
9
+ # the result, which is true if the halt succeeded and false otherwise.
10
+ class GracefulHalt
11
+ # Note: Any of the arguments can be arrays as well.
12
+ #
13
+ # @param [Symbol] target_state The target state ID that means that
14
+ # the machine was properly shut down.
15
+ # @param [Symbol] source_state The source state ID that the machine
16
+ # must be in to be shut down.
17
+ def initialize(app, env, target_state, source_state=nil)
18
+ @app = app
19
+ @logger = Log4r::Logger.new("vagrant::action::builtin::graceful_halt")
20
+ @source_state = source_state
21
+ @target_state = target_state
22
+ end
23
+
24
+ def call(env)
25
+ graceful = true
26
+ graceful = !env[:force_halt] if env.has_key?(:force_halt)
27
+
28
+ # By default, we didn't succeed.
29
+ env[:result] = false
30
+
31
+ if graceful && @source_state
32
+ @logger.info("Verifying source state of machine: #{@source_state.inspect}")
33
+
34
+ # If we're not in the proper source state, then we don't
35
+ # attempt to halt the machine
36
+ current_state = env[:machine].state.id
37
+ if current_state != @source_state
38
+ @logger.info("Invalid source state, not halting: #{current_state}")
39
+ graceful = false
40
+ end
41
+ end
42
+
43
+ # Only attempt to perform graceful shutdown under certain cases
44
+ # checked above.
45
+ if graceful
46
+ env[:ui].info I18n.t("vagrant.actions.vm.halt.graceful")
47
+ env[:machine].guest.capability(:halt)
48
+
49
+ @logger.debug("Waiting for target graceful halt state: #{@target_state}")
50
+ count = 0
51
+ while env[:machine].state.id != @target_state
52
+ count += 1
53
+ return if count >= env[:machine].config.vm.graceful_halt_retry_count
54
+ sleep env[:machine].config.vm.graceful_halt_retry_interval
55
+ end
56
+
57
+ # The result of this matters on whether we reached our
58
+ # proper target state or not.
59
+ env[:result] = env[:machine].state.id == @target_state
60
+
61
+ if env[:result]
62
+ @logger.info("Gracefully halted.")
63
+ else
64
+ @logger.info("Graceful halt failed.")
65
+ end
66
+ end
67
+
68
+ @app.call(env)
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,77 @@
1
+ require "thread"
2
+
3
+ module Vagrant
4
+ module Action
5
+ module Builtin
6
+ # This built-in middleware handles the `box_url` setting, downloading
7
+ # the box if necessary. You should place this early in your middleware
8
+ # sequence for a provider after configuration validation but before
9
+ # you attempt to use any box.
10
+ class HandleBoxUrl
11
+ @@big_lock = Mutex.new
12
+ @@handle_box_url_locks = Hash.new { |h,k| h[k] = Mutex.new }
13
+
14
+ def initialize(app, env)
15
+ @app = app
16
+ end
17
+
18
+ def call(env)
19
+ if !env[:machine].box
20
+ # Get a "big lock" to make sure that our more fine grained
21
+ # lock access is thread safe.
22
+ lock = nil
23
+ @@big_lock.synchronize do
24
+ lock = @@handle_box_url_locks[env[:machine].config.vm.box]
25
+ end
26
+
27
+ # We can assume a box URL is set because the Vagrantfile
28
+ # validation should do this for us. If not, though, we do
29
+ # raise a terrible runtime error.
30
+ box_name = env[:machine].config.vm.box
31
+ box_url = env[:machine].config.vm.box_url
32
+
33
+ lock.synchronize do
34
+ # First see if we actually have the box now.
35
+ has_box = false
36
+
37
+ formats = env[:machine].provider_options[:box_format] ||
38
+ env[:machine].provider_name
39
+ [formats].flatten.each do |format|
40
+ if env[:box_collection].find(box_name, format)
41
+ has_box = true
42
+ break
43
+ end
44
+ end
45
+
46
+ if !has_box
47
+ # Add the box then reload the box collection so that it becomes
48
+ # aware of it.
49
+ env[:ui].info I18n.t(
50
+ "vagrant.actions.vm.check_box.not_found",
51
+ :name => box_name,
52
+ :provider => env[:machine].provider_name)
53
+
54
+ begin
55
+ env[:action_runner].run(Vagrant::Action.action_box_add, {
56
+ :box_name => box_name,
57
+ :box_provider => env[:machine].provider_name,
58
+ :box_url => box_url
59
+ })
60
+ rescue Errors::BoxAlreadyExists
61
+ # Just ignore this, since it means the next part will succeed!
62
+ # This can happen in a multi-threaded environment.
63
+ end
64
+ end
65
+ end
66
+
67
+ # Reload the environment and set the VM to be the new loaded VM.
68
+ env[:machine] = env[:machine].env.machine(
69
+ env[:machine].name, env[:machine].provider_name, true)
70
+ end
71
+
72
+ @app.call(env)
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,134 @@
1
+ require "set"
2
+
3
+ require "log4r"
4
+
5
+ require "vagrant/util/is_port_open"
6
+
7
+ module Vagrant
8
+ module Action
9
+ module Builtin
10
+ # This middleware class will detect and handle collisions with
11
+ # forwarded ports, whether that means raising an error or repairing
12
+ # them automatically.
13
+ #
14
+ # Parameters it takes from the environment hash:
15
+ #
16
+ # * `:port_collision_repair` - If true, it will attempt to repair
17
+ # port collisions. If false, it will raise an exception when
18
+ # there is a collision.
19
+ #
20
+ # * `:port_collision_extra_in_use` - An array of ports that are
21
+ # considered in use.
22
+ #
23
+ # * `:port_collision_remap` - A hash remapping certain host ports
24
+ # to other host ports.
25
+ #
26
+ class HandleForwardedPortCollisions
27
+ include Util::IsPortOpen
28
+
29
+ def initialize(app, env)
30
+ @app = app
31
+ @logger = Log4r::Logger.new("vagrant::action::builtin::handle_port_collisions")
32
+ end
33
+
34
+ def call(env)
35
+ @logger.info("Detecting any forwarded port collisions...")
36
+
37
+ # Get the extra ports we consider in use
38
+ extra_in_use = env[:port_collision_extra_in_use] || []
39
+
40
+ # Get the remap
41
+ remap = env[:port_collision_remap] || {}
42
+
43
+ # Determine the handler we'll use if we have any port collisions
44
+ repair = !!env[:port_collision_repair]
45
+
46
+ # Log out some of our parameters
47
+ @logger.debug("Extra in use: #{extra_in_use.inspect}")
48
+ @logger.debug("Remap: #{remap.inspect}")
49
+ @logger.debug("Repair: #{repair.inspect}")
50
+
51
+ # Determine a list of usable ports for repair
52
+ usable_ports = Set.new(env[:machine].config.vm.usable_port_range)
53
+ usable_ports.subtract(extra_in_use)
54
+
55
+ # Pass one, remove all defined host ports from usable ports
56
+ with_forwarded_ports(env) do |options|
57
+ usable_ports.delete(options[:host])
58
+ end
59
+
60
+ # Pass two, detect/handle any collisions
61
+ with_forwarded_ports(env) do |options|
62
+ guest_port = options[:guest]
63
+ host_port = options[:host]
64
+
65
+ if remap[host_port]
66
+ remap_port = remap[host_port]
67
+ @logger.debug("Remap port override: #{host_port} => #{remap_port}")
68
+ host_port = remap_port
69
+ end
70
+
71
+ # If the port is open (listening for TCP connections)
72
+ if extra_in_use.include?(host_port) || is_port_open?("127.0.0.1", host_port)
73
+ if !repair
74
+ raise Errors::ForwardPortCollision,
75
+ :guest_port => guest_port.to_s,
76
+ :host_port => host_port.to_s
77
+ end
78
+
79
+ @logger.info("Attempting to repair FP collision: #{host_port}")
80
+
81
+ repaired_port = nil
82
+ while !usable_ports.empty?
83
+ # Attempt to repair the forwarded port
84
+ repaired_port = usable_ports.to_a.sort[0]
85
+ usable_ports.delete(repaired_port)
86
+
87
+ # If the port is in use, then we can't use this either...
88
+ if extra_in_use.include?(repaired_port) || is_port_open?("127.0.0.1", repaired_port)
89
+ @logger.info("Reparied port also in use: #{repaired_port}. Trying another...")
90
+ next
91
+ end
92
+
93
+ # We have a port so break out
94
+ break
95
+ end
96
+
97
+ # If we have no usable ports then we can't repair
98
+ if !repaired_port && usable_ports.empty?
99
+ raise Errors::ForwardPortAutolistEmpty,
100
+ :vm_name => env[:machine].name,
101
+ :guest_port => guest_port.to_s,
102
+ :host_port => host_port.to_s
103
+ end
104
+
105
+ # Modify the args in place
106
+ options[:host] = repaired_port
107
+
108
+ @logger.info("Repaired FP collision: #{host_port} to #{repaired_port}")
109
+
110
+ # Notify the user
111
+ env[:ui].info(I18n.t("vagrant.actions.vm.forward_ports.fixed_collision",
112
+ :host_port => host_port.to_s,
113
+ :guest_port => guest_port.to_s,
114
+ :new_port => repaired_port.to_s))
115
+ end
116
+ end
117
+
118
+ @app.call(env)
119
+ end
120
+
121
+ protected
122
+
123
+ def with_forwarded_ports(env)
124
+ env[:machine].config.vm.networks.each do |type, options|
125
+ # Ignore anything but forwarded ports
126
+ next if type != :forwarded_port
127
+
128
+ yield options
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,57 @@
1
+ require "log4r"
2
+
3
+ module Vagrant
4
+ module Action
5
+ module Builtin
6
+ # This class creates a multi-process lock using `flock`. The lock
7
+ # is active for the remainder of the middleware stack.
8
+ class Lock
9
+ def initialize(app, env, options=nil)
10
+ @app = app
11
+ @logger = Log4r::Logger.new("vagrant::action::builtin::lock")
12
+ @options ||= options || {}
13
+ raise ArgumentError, "Please specify a lock path" if !@options[:path]
14
+ raise ArgumentError, "Please specify an exception." if !@options[:exception]
15
+ end
16
+
17
+ def call(env)
18
+ lock_path = @options[:path]
19
+ lock_path = lock_path.call(env) if lock_path.is_a?(Proc)
20
+
21
+ env_key = "has_lock_#{lock_path}"
22
+
23
+ if !env[env_key]
24
+ # If we already have the key in our environment we assume the
25
+ # lock is held by our middleware stack already and we allow
26
+ # nesting.
27
+ File.open(lock_path, "w+") do |f|
28
+ # The file locking fails only if it returns "false." If it
29
+ # succeeds it returns a 0, so we must explicitly check for
30
+ # the proper error case.
31
+ @logger.info("Locking: #{lock_path}")
32
+ if f.flock(File::LOCK_EX | File::LOCK_NB) === false
33
+ exception = @options[:exception]
34
+ exception = exception.call(env) if exception.is_a?(Proc)
35
+ raise exception
36
+ end
37
+
38
+ # Set that we gained the lock and call deeper into the
39
+ # middleware, but make sure we UNSET the lock when we leave.
40
+ begin
41
+ env[env_key] = true
42
+ @app.call(env)
43
+ ensure
44
+ @logger.info("Unlocking: #{lock_path}")
45
+ env[env_key] = false
46
+ f.flock(File::LOCK_UN)
47
+ end
48
+ end
49
+ else
50
+ # Just call up the middleware because we already hold the lock
51
+ @app.call(env)
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,118 @@
1
+ require 'digest/md5'
2
+ require 'fileutils'
3
+ require 'pathname'
4
+
5
+ require "log4r"
6
+
7
+ module Vagrant
8
+ module Action
9
+ module Builtin
10
+ # This built-in middleware exports and mounts NFS shared folders.
11
+ #
12
+ # To use this middleware, two configuration parameters must be given
13
+ # via the environment hash:
14
+ #
15
+ # - `:nfs_host_ip` - The IP of where to mount the NFS folder from.
16
+ # - `:nfs_machine_ip` - The IP of the machine where the NFS folder
17
+ # will be mounted.
18
+ #
19
+ class NFS
20
+ def initialize(app, env)
21
+ @app = app
22
+ @logger = Log4r::Logger.new("vagrant::action::builtin::nfs")
23
+ end
24
+
25
+ def call(env)
26
+ # We forward things along first. We do everything on the tail
27
+ # end of the middleware call.
28
+ @app.call(env)
29
+
30
+ # Used by prepare_permission, so we need to save it
31
+ @env = env
32
+
33
+ folders = {}
34
+ env[:machine].config.vm.synced_folders.each do |id, opts|
35
+ # If this synced folder doesn't enable NFS, ignore it.
36
+ next if !opts[:nfs]
37
+
38
+ # Expand the host path, create it if we have to and
39
+ # store away the folder.
40
+ hostpath = Pathname.new(opts[:hostpath]).expand_path(env[:root_path])
41
+
42
+ if !hostpath.directory? && opts[:create]
43
+ # Host path doesn't exist, so let's create it.
44
+ @logger.debug("Host path doesn't exist, creating: #{hostpath}")
45
+
46
+ begin
47
+ FileUtils.mkpath(hostpath)
48
+ rescue Errno::EACCES
49
+ raise Vagrant::Errors::SharedFolderCreateFailed,
50
+ :path => hostpath.to_s
51
+ end
52
+ end
53
+
54
+ # Set the hostpath back on the options and save it
55
+ opts[:hostpath] = hostpath.to_s
56
+ folders[id] = opts
57
+ end
58
+
59
+ if !folders.empty?
60
+ raise Errors::NFSNoHostIP if !env[:nfs_host_ip]
61
+ raise Errors::NFSNoGuestIP if !env[:nfs_machine_ip]
62
+
63
+ # Prepare the folder, this means setting up various options
64
+ # and such on the folder itself.
65
+ folders.each { |id, opts| prepare_folder(opts) }
66
+
67
+ # Export the folders
68
+ env[:ui].info I18n.t("vagrant.actions.vm.nfs.exporting")
69
+ env[:host].nfs_export(env[:machine].id, env[:nfs_machine_ip], folders)
70
+
71
+ # Mount
72
+ env[:ui].info I18n.t("vagrant.actions.vm.nfs.mounting")
73
+
74
+ # Only mount folders that have a guest path specified.
75
+ mount_folders = {}
76
+ folders.each do |id, opts|
77
+ mount_folders[id] = opts.dup if opts[:guestpath]
78
+ end
79
+
80
+ # Mount them!
81
+ env[:machine].guest.capability(
82
+ :mount_nfs_folder, env[:nfs_host_ip], mount_folders)
83
+ end
84
+ end
85
+
86
+ protected
87
+
88
+ def prepare_folder(opts)
89
+ opts[:map_uid] = prepare_permission(:uid, opts)
90
+ opts[:map_gid] = prepare_permission(:gid, opts)
91
+ opts[:nfs_version] ||= 3
92
+
93
+ # The poor man's UUID. An MD5 hash here is sufficient since
94
+ # we need a 32 character "uuid" to represent the filesystem
95
+ # of an export. Hashing the host path is safe because two of
96
+ # the same host path will hash to the same fsid.
97
+ opts[:uuid] = Digest::MD5.hexdigest(opts[:hostpath])
98
+ end
99
+
100
+ # Prepares the UID/GID settings for a single folder.
101
+ def prepare_permission(perm, opts)
102
+ key = "map_#{perm}".to_sym
103
+ return nil if opts.has_key?(key) && opts[key].nil?
104
+
105
+ # The options on the hash get priority, then the default
106
+ # values
107
+ value = opts.has_key?(key) ? opts[key] : @env[:machine].config.nfs.send(key)
108
+ return value if value != :auto
109
+
110
+ # Get UID/GID from folder if we've made it this far
111
+ # (value == :auto)
112
+ stat = File.stat(opts[:hostpath])
113
+ return stat.send(perm)
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end