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,222 @@
1
+ require "pathname"
2
+
3
+ require "log4r"
4
+
5
+ module Vagrant
6
+ module Config
7
+ # This class is responsible for loading Vagrant configuration,
8
+ # usually in the form of Vagrantfiles.
9
+ #
10
+ # Loading works by specifying the sources for the configuration
11
+ # as well as the order the sources should be loaded. Configuration
12
+ # set later always overrides those set earlier; this is how
13
+ # configuration "scoping" is implemented.
14
+ class Loader
15
+ # Initializes a configuration loader.
16
+ #
17
+ # @param [Registry] versions A registry of the available versions and
18
+ # their associated loaders.
19
+ # @param [Array] version_order An array of the order of the versions
20
+ # in the registry. This is used to determine if upgrades are
21
+ # necessary. Additionally, the last version in this order is always
22
+ # considered the "current" version.
23
+ def initialize(versions, version_order)
24
+ @logger = Log4r::Logger.new("vagrant::config::loader")
25
+ @config_cache = {}
26
+ @proc_cache = {}
27
+ @sources = {}
28
+ @versions = versions
29
+ @version_order = version_order
30
+ end
31
+
32
+ # Set the configuration data for the given name.
33
+ #
34
+ # The `name` should be a symbol and must uniquely identify the data
35
+ # being given.
36
+ #
37
+ # `data` can either be a path to a Ruby Vagrantfile or a `Proc` directly.
38
+ # `data` can also be an array of such values.
39
+ #
40
+ # At this point, no configuration is actually loaded. Note that calling
41
+ # `set` multiple times with the same name will override any previously
42
+ # set values. In this way, the last set data for a given name wins.
43
+ def set(name, sources)
44
+ @logger.info("Set #{name.inspect} = #{sources.inspect}")
45
+
46
+ # Sources should be an array
47
+ sources = [sources] if !sources.kind_of?(Array)
48
+
49
+ # Gather the procs for every source, since that is what we care about.
50
+ procs = []
51
+ sources.each do |source|
52
+ if !@proc_cache.has_key?(source)
53
+ # Load the procs for this source and cache them. This caching
54
+ # avoids the issue where a file may have side effects when loading
55
+ # and loading it multiple times causes unexpected behavior.
56
+ @logger.debug("Populating proc cache for #{source.inspect}")
57
+ @proc_cache[source] = procs_for_source(source)
58
+ end
59
+
60
+ # Add on to the array of procs we're going to use
61
+ procs.concat(@proc_cache[source])
62
+ end
63
+
64
+ # Set this source by name.
65
+ @sources[name] = procs
66
+ end
67
+
68
+ # This loads the configuration sources in the given order and returns
69
+ # an actual configuration object that is ready to be used.
70
+ #
71
+ # @param [Array<Symbol>] order The order of configuration to load.
72
+ # @return [Object] The configuration object. This is different for
73
+ # each configuration version.
74
+ def load(order)
75
+ @logger.info("Loading configuration in order: #{order.inspect}")
76
+
77
+ unknown_sources = @sources.keys - order
78
+ if !unknown_sources.empty?
79
+ # TODO: Raise exception here perhaps.
80
+ @logger.error("Unknown config sources: #{unknown_sources.inspect}")
81
+ end
82
+
83
+ # Get the current version config class to use
84
+ current_version = @version_order.last
85
+ current_config_klass = @versions.get(current_version)
86
+
87
+ # This will hold our result
88
+ result = current_config_klass.init
89
+
90
+ # Keep track of the warnings and errors that may come from
91
+ # upgrading the Vagrantfiles
92
+ warnings = []
93
+ errors = []
94
+
95
+ order.each do |key|
96
+ next if !@sources.has_key?(key)
97
+
98
+ @sources[key].each do |version, proc|
99
+ if !@config_cache.has_key?(proc)
100
+ @logger.debug("Loading from: #{key} (evaluating)")
101
+
102
+ # Get the proper version loader for this version and load
103
+ version_loader = @versions.get(version)
104
+ version_config = version_loader.load(proc)
105
+
106
+ # Store the errors/warnings associated with loading this
107
+ # configuration. We'll store these for later.
108
+ version_warnings = []
109
+ version_errors = []
110
+
111
+ # If this version is not the current version, then we need
112
+ # to upgrade to the latest version.
113
+ if version != current_version
114
+ @logger.debug("Upgrading config from version #{version} to #{current_version}")
115
+ version_index = @version_order.index(version)
116
+ current_index = @version_order.index(current_version)
117
+
118
+ (version_index + 1).upto(current_index) do |index|
119
+ next_version = @version_order[index]
120
+ @logger.debug("Upgrading config to version #{next_version}")
121
+
122
+ # Get the loader of this version and ask it to upgrade
123
+ loader = @versions.get(next_version)
124
+ upgrade_result = loader.upgrade(version_config)
125
+
126
+ this_warnings = upgrade_result[1]
127
+ this_errors = upgrade_result[2]
128
+ @logger.debug("Upgraded to version #{next_version} with " +
129
+ "#{this_warnings.length} warnings and " +
130
+ "#{this_errors.length} errors")
131
+
132
+ # Append loading this to the version warnings and errors
133
+ version_warnings += this_warnings
134
+ version_errors += this_errors
135
+
136
+ # Store the new upgraded version
137
+ version_config = upgrade_result[0]
138
+ end
139
+ end
140
+
141
+ # Cache the loaded configuration along with any warnings
142
+ # or errors so that they can be retrieved later.
143
+ @config_cache[proc] = [version_config, version_warnings, version_errors]
144
+ else
145
+ @logger.debug("Loading from: #{key} (cache)")
146
+ end
147
+
148
+ # Merge the configurations
149
+ cache_data = @config_cache[proc]
150
+ result = current_config_klass.merge(result, cache_data[0])
151
+
152
+ # Append the total warnings/errors
153
+ warnings += cache_data[1]
154
+ errors += cache_data[2]
155
+ end
156
+ end
157
+
158
+ @logger.debug("Configuration loaded successfully, finalizing and returning")
159
+ [current_config_klass.finalize(result), warnings, errors]
160
+ end
161
+
162
+ protected
163
+
164
+ # This returns an array of `Proc` objects for the given source.
165
+ # The `Proc` objects returned will expect a single argument for
166
+ # the configuration object and are expected to mutate this
167
+ # configuration object.
168
+ def procs_for_source(source)
169
+ # Convert all pathnames to strings so we just have their path
170
+ source = source.to_s if source.is_a?(Pathname)
171
+
172
+ if source.is_a?(Array)
173
+ # An array must be formatted as [version, proc], so verify
174
+ # that and then return it
175
+ raise ArgumentError, "String source must have format [version, proc]" if source.length != 2
176
+
177
+ # Return it as an array since we're expected to return an array
178
+ # of [version, proc] pairs, but an array source only has one.
179
+ return [source]
180
+ elsif source.is_a?(String)
181
+ # Strings are considered paths, so load them
182
+ return procs_for_path(source)
183
+ else
184
+ raise ArgumentError, "Unknown configuration source: #{source.inspect}"
185
+ end
186
+ end
187
+
188
+ # This returns an array of `Proc` objects for the given path source.
189
+ #
190
+ # @param [String] path Path to the file which contains the proper
191
+ # `Vagrant.configure` calls.
192
+ # @return [Array<Proc>]
193
+ def procs_for_path(path)
194
+ @logger.debug("Load procs for pathname: #{path}")
195
+
196
+ return Config.capture_configures do
197
+ begin
198
+ Kernel.load path
199
+ rescue SyntaxError => e
200
+ # Report syntax errors in a nice way.
201
+ raise Errors::VagrantfileSyntaxError, :file => e.message
202
+ rescue SystemExit
203
+ # Continue raising that exception...
204
+ raise
205
+ rescue Vagrant::Errors::VagrantError
206
+ # Continue raising known Vagrant errors since they already
207
+ # contain well worded error messages and context.
208
+ raise
209
+ rescue Exception => e
210
+ @logger.error("Vagrantfile load error: #{e.message}")
211
+ @logger.error(e.backtrace.join("\n"))
212
+
213
+ # Report the generic exception
214
+ raise Errors::VagrantfileLoadError,
215
+ :path => path,
216
+ :message => e.message
217
+ end
218
+ end
219
+ end
220
+ end
221
+ end
222
+ end
@@ -0,0 +1,13 @@
1
+ module Vagrant
2
+ module Config
3
+ module V1
4
+ # This is a configuration object that can have anything done
5
+ # to it. Anything, and it just appears to keep working.
6
+ class DummyConfig
7
+ def method_missing(name, *args, &block)
8
+ DummyConfig.new
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,105 @@
1
+ require "vagrant/config/v1/root"
2
+
3
+ module Vagrant
4
+ module Config
5
+ module V1
6
+ # This is the loader that handles configuration loading for V1
7
+ # configurations.
8
+ class Loader < VersionBase
9
+ # Returns a bare empty configuration object.
10
+ #
11
+ # @return [V1::Root]
12
+ def self.init
13
+ new_root_object
14
+ end
15
+
16
+ # Finalizes the configuration by making sure there is at least
17
+ # one VM defined in it.
18
+ def self.finalize(config)
19
+ # Call the `#finalize` method on each of the configuration keys.
20
+ # They're expected to modify themselves in our case.
21
+ config.finalize!
22
+
23
+ # Return the object
24
+ config
25
+ end
26
+
27
+ # Loads the configuration for the given proc and returns a configuration
28
+ # object.
29
+ #
30
+ # @param [Proc] config_proc
31
+ # @return [Object]
32
+ def self.load(config_proc)
33
+ # Create a root configuration object
34
+ root = new_root_object
35
+
36
+ # Call the proc with the root
37
+ config_proc.call(root)
38
+
39
+ # Return the root object, which doubles as the configuration object
40
+ # we actually use for accessing as well.
41
+ root
42
+ end
43
+
44
+ # Merges two configuration objects.
45
+ #
46
+ # @param [V1::Root] old The older root config.
47
+ # @param [V1::Root] new The newer root config.
48
+ # @return [V1::Root]
49
+ def self.merge(old, new)
50
+ # Grab the internal states, we use these heavily throughout the process
51
+ old_state = old.__internal_state
52
+ new_state = new.__internal_state
53
+
54
+ # The config map for the new object is the old one merged with the
55
+ # new one.
56
+ config_map = old_state["config_map"].merge(new_state["config_map"])
57
+
58
+ # Merge the keys.
59
+ old_keys = old_state["keys"]
60
+ new_keys = new_state["keys"]
61
+ keys = {}
62
+ old_keys.each do |key, old_value|
63
+ if new_keys.has_key?(key)
64
+ # We need to do a merge, which we expect to be available
65
+ # on the config class itself.
66
+ keys[key] = old_value.merge(new_keys[key])
67
+ else
68
+ # We just take the old value, but dup it so that we can modify.
69
+ keys[key] = old_value.dup
70
+ end
71
+ end
72
+
73
+ new_keys.each do |key, new_value|
74
+ # Add in the keys that the new class has that we haven't merged.
75
+ if !keys.has_key?(key)
76
+ keys[key] = new_value.dup
77
+ end
78
+ end
79
+
80
+ # Return the final root object
81
+ V1::Root.new(config_map, keys)
82
+ end
83
+
84
+ protected
85
+
86
+ def self.new_root_object
87
+ # Get all the registered configuration objects and use them. If
88
+ # we're currently on version 1, then we load all the config objects,
89
+ # otherwise we load only the upgrade safe ones, since we're
90
+ # obviously being loaded for an upgrade.
91
+ config_map = nil
92
+ plugin_manager = Vagrant.plugin("1").manager
93
+ if Config::CURRENT_VERSION == "1"
94
+ config_map = plugin_manager.config
95
+ else
96
+ config_map = plugin_manager.config_upgrade_safe
97
+ end
98
+
99
+ # Create the configuration root object
100
+ V1::Root.new(config_map)
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,60 @@
1
+ require "set"
2
+
3
+ module Vagrant
4
+ module Config
5
+ module V1
6
+ # This is the root configuration class. An instance of this is what
7
+ # is passed into version 1 Vagrant configuration blocks.
8
+ class Root
9
+ # Initializes a root object that maps the given keys to specific
10
+ # configuration classes.
11
+ #
12
+ # @param [Hash] config_map Map of key to config class.
13
+ def initialize(config_map, keys=nil)
14
+ @keys = keys || {}
15
+ @config_map = config_map
16
+ @missing_key_calls = Set.new
17
+ end
18
+
19
+ # We use method_missing as a way to get the configuration that is
20
+ # used for Vagrant and load the proper configuration classes for
21
+ # each.
22
+ def method_missing(name, *args)
23
+ return @keys[name] if @keys.has_key?(name)
24
+
25
+ config_klass = @config_map[name.to_sym]
26
+ if config_klass
27
+ # Instantiate the class and return the instance
28
+ @keys[name] = config_klass.new
29
+ return @keys[name]
30
+ else
31
+ # Record access to a missing key as an error
32
+ @missing_key_calls.add(name.to_s)
33
+ return DummyConfig.new
34
+ end
35
+ end
36
+
37
+ # Called to finalize this object just prior to it being used by
38
+ # the Vagrant system. The "!" signifies that this is expected to
39
+ # mutate itself.
40
+ def finalize!
41
+ @keys.each do |_key, instance|
42
+ instance.finalize!
43
+ end
44
+ end
45
+
46
+ # Returns the internal state of the root object. This is used
47
+ # by outside classes when merging, and shouldn't be called directly.
48
+ # Note the strange method name is to attempt to avoid any name
49
+ # clashes with potential configuration keys.
50
+ def __internal_state
51
+ {
52
+ "config_map" => @config_map,
53
+ "keys" => @keys,
54
+ "missing_key_calls" => @missing_key_calls
55
+ }
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,9 @@
1
+ module Vagrant
2
+ module Config
3
+ module V1
4
+ autoload :DummyConfig, "vagrant/config/v1/dummy_config"
5
+ autoload :Loader, "vagrant/config/v1/loader"
6
+ autoload :Root, "vagrant/config/v1/root"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ module Vagrant
2
+ module Config
3
+ module V2
4
+ # This is a configuration object that can have anything done
5
+ # to it. Anything, and it just appears to keep working.
6
+ class DummyConfig
7
+ def method_missing(name, *args, &block)
8
+ DummyConfig.new
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,141 @@
1
+ require "vagrant/config/v2/root"
2
+
3
+ module Vagrant
4
+ module Config
5
+ module V2
6
+ # This is the loader that handles configuration loading for V2
7
+ # configurations.
8
+ class Loader < VersionBase
9
+ # Returns a bare empty configuration object.
10
+ #
11
+ # @return [V2::Root]
12
+ def self.init
13
+ new_root_object
14
+ end
15
+
16
+ # Finalizes the configuration by making sure there is at least
17
+ # one VM defined in it.
18
+ def self.finalize(config)
19
+ # Call the `#finalize` method on each of the configuration keys.
20
+ # They're expected to modify themselves in our case.
21
+ config.finalize!
22
+
23
+ # Return the object
24
+ config
25
+ end
26
+
27
+ # Loads the configuration for the given proc and returns a configuration
28
+ # object.
29
+ #
30
+ # @param [Proc] config_proc
31
+ # @return [Object]
32
+ def self.load(config_proc)
33
+ # Create a root configuration object
34
+ root = new_root_object
35
+
36
+ # Call the proc with the root
37
+ config_proc.call(root)
38
+
39
+ # Return the root object, which doubles as the configuration object
40
+ # we actually use for accessing as well.
41
+ root
42
+ end
43
+
44
+ # Merges two configuration objects.
45
+ #
46
+ # @param [V2::Root] old The older root config.
47
+ # @param [V2::Root] new The newer root config.
48
+ # @return [V2::Root]
49
+ def self.merge(old, new)
50
+ # Grab the internal states, we use these heavily throughout the process
51
+ old_state = old.__internal_state
52
+ new_state = new.__internal_state
53
+
54
+ # The config map for the new object is the old one merged with the
55
+ # new one.
56
+ config_map = old_state["config_map"].merge(new_state["config_map"])
57
+
58
+ # Merge the keys.
59
+ old_keys = old_state["keys"]
60
+ new_keys = new_state["keys"]
61
+ keys = {}
62
+ old_keys.each do |key, old_value|
63
+ if new_keys.has_key?(key)
64
+ # We need to do a merge, which we expect to be available
65
+ # on the config class itself.
66
+ keys[key] = old_value.merge(new_keys[key])
67
+ else
68
+ # We just take the old value, but dup it so that we can modify.
69
+ keys[key] = old_value.dup
70
+ end
71
+ end
72
+
73
+ new_keys.each do |key, new_value|
74
+ # Add in the keys that the new class has that we haven't merged.
75
+ if !keys.has_key?(key)
76
+ keys[key] = new_value.dup
77
+ end
78
+ end
79
+
80
+ # Merge the missing keys
81
+ new_missing_key_calls =
82
+ old_state["missing_key_calls"] + new_state["missing_key_calls"]
83
+
84
+ # Return the final root object
85
+ V2::Root.new(config_map).tap do |result|
86
+ result.__set_internal_state({
87
+ "config_map" => config_map,
88
+ "keys" => keys,
89
+ "missing_key_calls" => new_missing_key_calls
90
+ })
91
+ end
92
+ end
93
+
94
+ # Upgrade a V1 configuration to a V2 configuration. We do this by
95
+ # creating a V2 configuration, and calling "upgrade" on each of the
96
+ # V1 configurations, expecting them to set the right settings on the
97
+ # new root.
98
+ #
99
+ # @param [V1::Root] old
100
+ # @return [Array] A 3-tuple result.
101
+ def self.upgrade(old)
102
+ # Get a new root
103
+ root = new_root_object
104
+
105
+ # Store the warnings/errors
106
+ warnings = []
107
+ errors = []
108
+
109
+ # Go through the old keys and upgrade them if they can be
110
+ old.__internal_state["keys"].each do |_, old_value|
111
+ if old_value.respond_to?(:upgrade)
112
+ result = old_value.upgrade(root)
113
+
114
+ # Sanity check to guard against random return values
115
+ if result.is_a?(Array)
116
+ warnings += result[0]
117
+ errors += result[1]
118
+ end
119
+ end
120
+ end
121
+
122
+ old.__internal_state["missing_key_calls"].to_a.sort.each do |key|
123
+ warnings << I18n.t("vagrant.config.loader.bad_v1_key", :key => key)
124
+ end
125
+
126
+ [root, warnings, errors]
127
+ end
128
+
129
+ protected
130
+
131
+ def self.new_root_object
132
+ # Get all the registered plugins for V2
133
+ config_map = Vagrant.plugin("2").manager.config
134
+
135
+ # Create the configuration root object
136
+ V2::Root.new(config_map)
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,105 @@
1
+ require "set"
2
+
3
+ require "vagrant/config/v2/util"
4
+
5
+ module Vagrant
6
+ module Config
7
+ module V2
8
+ # This is the root configuration class. An instance of this is what
9
+ # is passed into version 1 Vagrant configuration blocks.
10
+ class Root
11
+ # Initializes a root object that maps the given keys to specific
12
+ # configuration classes.
13
+ #
14
+ # @param [Hash] config_map Map of key to config class.
15
+ def initialize(config_map, keys=nil)
16
+ @keys = keys || {}
17
+ @config_map = config_map
18
+ @missing_key_calls = Set.new
19
+ end
20
+
21
+ # We use method_missing as a way to get the configuration that is
22
+ # used for Vagrant and load the proper configuration classes for
23
+ # each.
24
+ def method_missing(name, *args)
25
+ return @keys[name] if @keys.has_key?(name)
26
+
27
+ config_klass = @config_map[name.to_sym]
28
+ if config_klass
29
+ # Instantiate the class and return the instance
30
+ @keys[name] = config_klass.new
31
+ return @keys[name]
32
+ else
33
+ # Record access to a missing key as an error
34
+ @missing_key_calls.add(name.to_s)
35
+ return DummyConfig.new
36
+ end
37
+ end
38
+
39
+ # Called to finalize this object just prior to it being used by
40
+ # the Vagrant system. The "!" signifies that this is expected to
41
+ # mutate itself.
42
+ def finalize!
43
+ @keys.each do |_key, instance|
44
+ instance.finalize!
45
+ end
46
+ end
47
+
48
+ # This validates the configuration and returns a hash of error
49
+ # messages by section. If there are no errors, an empty hash
50
+ # is returned.
51
+ #
52
+ # @param [Environment] env
53
+ # @return [Hash]
54
+ def validate(machine)
55
+ # Go through each of the configuration keys and validate
56
+ errors = {}
57
+ @keys.each do |_key, instance|
58
+ if instance.respond_to?(:validate)
59
+ # Validate this single item, and if we have errors then
60
+ # we merge them into our total errors list.
61
+ result = instance.validate(machine)
62
+ if result && !result.empty?
63
+ errors = Util.merge_errors(errors, result)
64
+ end
65
+ end
66
+ end
67
+
68
+ # Go through and delete empty keys
69
+ errors.keys.each do |key|
70
+ errors.delete(key) if errors[key].empty?
71
+ end
72
+
73
+ # If we have missing keys, record those as errors
74
+ if !@missing_key_calls.empty?
75
+ errors["Vagrant"] = @missing_key_calls.to_a.sort.map do |key|
76
+ I18n.t("vagrant.config.root.bad_key", :key => key)
77
+ end
78
+ end
79
+
80
+ errors
81
+ end
82
+
83
+ # Returns the internal state of the root object. This is used
84
+ # by outside classes when merging, and shouldn't be called directly.
85
+ # Note the strange method name is to attempt to avoid any name
86
+ # clashes with potential configuration keys.
87
+ def __internal_state
88
+ {
89
+ "config_map" => @config_map,
90
+ "keys" => @keys,
91
+ "missing_key_calls" => @missing_key_calls
92
+ }
93
+ end
94
+
95
+ # This sets the internal state. This is used by the core to do some
96
+ # merging logic and shouldn't be used by the general public.
97
+ def __set_internal_state(state)
98
+ @config_map = state["config_map"] if state.has_key?("config_map")
99
+ @keys = state["keys"] if state.has_key?("keys")
100
+ @missing_key_calls = state["missing_key_calls"] if state.has_key?("missing_key_calls")
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,21 @@
1
+ module Vagrant
2
+ module Config
3
+ module V2
4
+ class Util
5
+ # This merges two error hashes from validate methods.
6
+ #
7
+ # @param [Hash] first
8
+ # @param [Hash] second
9
+ # @return [Hash] Merged result
10
+ def self.merge_errors(first, second)
11
+ first.dup.tap do |result|
12
+ second.each do |key, value|
13
+ result[key] ||= []
14
+ result[key] += value
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end