vagrant 0.8.10 → 0.9.0

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 (324) hide show
  1. data/CHANGELOG.md +77 -1
  2. data/Gemfile +0 -14
  3. data/LICENSE +1 -1
  4. data/bin/vagrant +47 -20
  5. data/config/default.rb +6 -14
  6. data/lib/vagrant.rb +132 -5
  7. data/lib/vagrant/action.rb +45 -123
  8. data/lib/vagrant/action/box/destroy.rb +7 -3
  9. data/lib/vagrant/action/box/download.rb +8 -8
  10. data/lib/vagrant/action/box/package.rb +2 -2
  11. data/lib/vagrant/action/box/unpackage.rb +13 -7
  12. data/lib/vagrant/action/box/verify.rb +5 -5
  13. data/lib/vagrant/action/builder.rb +23 -19
  14. data/lib/vagrant/action/builtin.rb +117 -79
  15. data/lib/vagrant/action/env/set.rb +7 -4
  16. data/lib/vagrant/action/environment.rb +3 -41
  17. data/lib/vagrant/action/general/package.rb +14 -29
  18. data/lib/vagrant/action/general/validate.rb +2 -2
  19. data/lib/vagrant/action/runner.rb +53 -0
  20. data/lib/vagrant/action/vm/boot.rb +9 -9
  21. data/lib/vagrant/action/vm/check_accessible.rb +2 -2
  22. data/lib/vagrant/action/vm/check_box.rb +10 -12
  23. data/lib/vagrant/action/vm/check_guest_additions.rb +8 -8
  24. data/lib/vagrant/action/vm/check_port_collisions.rb +85 -0
  25. data/lib/vagrant/action/vm/clean_machine_folder.rb +4 -4
  26. data/lib/vagrant/action/vm/clear_forwarded_ports.rb +3 -11
  27. data/lib/vagrant/action/vm/clear_network_interfaces.rb +31 -0
  28. data/lib/vagrant/action/vm/clear_shared_folders.rb +2 -11
  29. data/lib/vagrant/action/vm/customize.rb +19 -9
  30. data/lib/vagrant/action/vm/destroy.rb +4 -4
  31. data/lib/vagrant/action/vm/destroy_unused_network_interfaces.rb +2 -12
  32. data/lib/vagrant/action/vm/discard_state.rb +4 -4
  33. data/lib/vagrant/action/vm/export.rb +13 -8
  34. data/lib/vagrant/action/vm/forward_ports.rb +55 -102
  35. data/lib/vagrant/action/vm/halt.rb +9 -6
  36. data/lib/vagrant/action/vm/host_name.rb +4 -4
  37. data/lib/vagrant/action/vm/import.rb +19 -10
  38. data/lib/vagrant/action/vm/match_mac_address.rb +4 -9
  39. data/lib/vagrant/action/vm/network.rb +300 -94
  40. data/lib/vagrant/action/vm/nfs.rb +41 -26
  41. data/lib/vagrant/action/vm/package.rb +1 -1
  42. data/lib/vagrant/action/vm/package_vagrantfile.rb +5 -2
  43. data/lib/vagrant/action/vm/provision.rb +42 -13
  44. data/lib/vagrant/action/vm/provisioner_cleanup.rb +2 -2
  45. data/lib/vagrant/action/vm/{clear_nfs_exports.rb → prune_nfs_exports.rb} +7 -7
  46. data/lib/vagrant/action/vm/resume.rb +4 -4
  47. data/lib/vagrant/action/vm/setup_package_files.rb +54 -0
  48. data/lib/vagrant/action/vm/share_folders.rb +63 -39
  49. data/lib/vagrant/action/vm/suspend.rb +4 -4
  50. data/lib/vagrant/action/warden.rb +13 -6
  51. data/lib/vagrant/box.rb +9 -55
  52. data/lib/vagrant/box_collection.rb +22 -17
  53. data/lib/vagrant/cli.rb +62 -47
  54. data/lib/vagrant/command.rb +18 -20
  55. data/lib/vagrant/command/base.rb +135 -90
  56. data/lib/vagrant/command/box.rb +46 -21
  57. data/lib/vagrant/command/box_add.rb +33 -0
  58. data/lib/vagrant/command/box_list.rb +25 -0
  59. data/lib/vagrant/command/box_remove.rb +23 -0
  60. data/lib/vagrant/command/box_repackage.rb +23 -0
  61. data/lib/vagrant/command/destroy.rb +16 -5
  62. data/lib/vagrant/command/halt.rb +25 -7
  63. data/lib/vagrant/command/init.rb +30 -7
  64. data/lib/vagrant/command/package.rb +49 -18
  65. data/lib/vagrant/command/provision.rb +22 -9
  66. data/lib/vagrant/command/reload.rb +18 -5
  67. data/lib/vagrant/command/resume.rb +18 -5
  68. data/lib/vagrant/command/ssh.rb +69 -31
  69. data/lib/vagrant/command/ssh_config.rb +37 -22
  70. data/lib/vagrant/command/status.rb +22 -20
  71. data/lib/vagrant/command/suspend.rb +18 -5
  72. data/lib/vagrant/command/up.rb +41 -8
  73. data/lib/vagrant/communication.rb +7 -0
  74. data/lib/vagrant/communication/base.rb +56 -0
  75. data/lib/vagrant/communication/ssh.rb +200 -0
  76. data/lib/vagrant/config.rb +29 -103
  77. data/lib/vagrant/config/base.rb +18 -26
  78. data/lib/vagrant/config/container.rb +37 -0
  79. data/lib/vagrant/config/error_recorder.rb +1 -1
  80. data/lib/vagrant/config/loader.rb +125 -0
  81. data/lib/vagrant/config/nfs.rb +1 -3
  82. data/lib/vagrant/config/package.rb +1 -3
  83. data/lib/vagrant/config/ssh.rb +31 -16
  84. data/lib/vagrant/config/top.rb +36 -25
  85. data/lib/vagrant/config/vagrant.rb +2 -5
  86. data/lib/vagrant/config/vm.rb +115 -56
  87. data/lib/vagrant/config/vm/provisioner.rb +16 -20
  88. data/lib/vagrant/config/vm/sub_vm.rb +1 -1
  89. data/lib/vagrant/data_store.rb +23 -15
  90. data/lib/vagrant/downloaders/base.rb +7 -5
  91. data/lib/vagrant/downloaders/file.rb +4 -4
  92. data/lib/vagrant/downloaders/http.rb +4 -5
  93. data/lib/vagrant/driver.rb +7 -0
  94. data/lib/vagrant/driver/virtualbox.rb +121 -0
  95. data/lib/vagrant/driver/virtualbox_4_0.rb +411 -0
  96. data/lib/vagrant/driver/virtualbox_4_1.rb +411 -0
  97. data/lib/vagrant/driver/virtualbox_base.rb +284 -0
  98. data/lib/vagrant/environment.rb +221 -240
  99. data/lib/vagrant/errors.rb +74 -25
  100. data/lib/vagrant/guest.rb +16 -0
  101. data/lib/vagrant/guest/arch.rb +48 -0
  102. data/lib/vagrant/{systems → guest}/base.rb +30 -18
  103. data/lib/vagrant/guest/debian.rb +61 -0
  104. data/lib/vagrant/{systems → guest}/freebsd.rb +11 -18
  105. data/lib/vagrant/guest/gentoo.rb +32 -0
  106. data/lib/vagrant/guest/linux.rb +78 -0
  107. data/lib/vagrant/{systems → guest}/linux/config.rb +2 -4
  108. data/lib/vagrant/guest/linux/error.rb +9 -0
  109. data/lib/vagrant/guest/redhat.rb +66 -0
  110. data/lib/vagrant/guest/solaris.rb +114 -0
  111. data/lib/vagrant/{systems → guest}/suse.rb +2 -2
  112. data/lib/vagrant/guest/ubuntu.rb +23 -0
  113. data/lib/vagrant/hosts.rb +23 -6
  114. data/lib/vagrant/hosts/arch.rb +7 -3
  115. data/lib/vagrant/hosts/base.rb +36 -46
  116. data/lib/vagrant/hosts/bsd.rb +53 -16
  117. data/lib/vagrant/hosts/fedora.rb +14 -0
  118. data/lib/vagrant/hosts/freebsd.rb +6 -36
  119. data/lib/vagrant/hosts/linux.rb +45 -20
  120. data/lib/vagrant/hosts/windows.rb +16 -0
  121. data/lib/vagrant/provisioners.rb +10 -7
  122. data/lib/vagrant/provisioners/base.rb +11 -34
  123. data/lib/vagrant/provisioners/chef.rb +30 -26
  124. data/lib/vagrant/provisioners/chef_client.rb +37 -23
  125. data/lib/vagrant/provisioners/chef_solo.rb +61 -16
  126. data/lib/vagrant/provisioners/puppet.rb +70 -38
  127. data/lib/vagrant/provisioners/puppet_server.rb +12 -13
  128. data/lib/vagrant/provisioners/shell.rb +24 -24
  129. data/lib/vagrant/registry.rb +49 -0
  130. data/lib/vagrant/ssh.rb +82 -153
  131. data/lib/vagrant/ui.rb +118 -50
  132. data/lib/vagrant/util/busy.rb +1 -1
  133. data/lib/vagrant/util/file_mode.rb +12 -0
  134. data/lib/vagrant/util/network_ip.rb +28 -0
  135. data/lib/vagrant/util/platform.rb +1 -0
  136. data/lib/vagrant/util/subprocess.rb +227 -0
  137. data/lib/vagrant/version.rb +1 -1
  138. data/lib/vagrant/vm.rb +111 -97
  139. data/tasks/acceptance.rake +3 -3
  140. data/tasks/test.rake +7 -2
  141. data/templates/commands/init/Vagrantfile.erb +11 -4
  142. data/templates/{ssh_config.erb → commands/ssh_config/config.erb} +0 -0
  143. data/templates/guests/arch/network_dhcp.erb +7 -0
  144. data/templates/guests/arch/network_static.erb +7 -0
  145. data/templates/guests/debian/network_dhcp.erb +6 -0
  146. data/templates/guests/debian/network_static.erb +7 -0
  147. data/templates/guests/gentoo/network_dhcp.erb +4 -0
  148. data/templates/guests/gentoo/network_static.erb +4 -0
  149. data/templates/guests/redhat/network_dhcp.erb +6 -0
  150. data/templates/guests/redhat/network_static.erb +7 -0
  151. data/templates/locales/en.yml +241 -122
  152. data/templates/{chef_server_client.erb → provisioners/chef_client/client.erb} +0 -0
  153. data/templates/{chef_solo_solo.erb → provisioners/chef_solo/solo.erb} +0 -0
  154. data/test/acceptance/base.rb +10 -10
  155. data/test/acceptance/box_test.rb +28 -6
  156. data/test/acceptance/destroy_test.rb +1 -1
  157. data/test/acceptance/halt_test.rb +4 -4
  158. data/test/acceptance/init_test.rb +3 -3
  159. data/test/acceptance/networking/host_only_test.rb +37 -0
  160. data/test/acceptance/networking/port_forward_test.rb +125 -0
  161. data/test/acceptance/package_test.rb +46 -0
  162. data/test/acceptance/provisioning/basic_test.rb +61 -0
  163. data/test/acceptance/provisioning/chef_solo_test.rb +37 -0
  164. data/test/acceptance/provisioning/shell_test.rb +53 -0
  165. data/test/acceptance/resume_test.rb +1 -1
  166. data/test/acceptance/skeletons/chef_solo_basic/README.md +3 -0
  167. data/test/acceptance/skeletons/chef_solo_basic/cookbooks/basic/recipes/default.rb +5 -0
  168. data/test/acceptance/skeletons/chef_solo_json/README.md +3 -0
  169. data/test/acceptance/skeletons/chef_solo_json/cookbooks/basic/recipes/default.rb +6 -0
  170. data/test/acceptance/skeletons/provisioner_multi/README.md +3 -0
  171. data/test/acceptance/skeletons/provisioner_multi/cookbooks/basic/recipes/default.rb +5 -0
  172. data/test/acceptance/ssh_test.rb +7 -2
  173. data/test/acceptance/support/config.rb +1 -1
  174. data/test/acceptance/support/isolated_environment.rb +41 -150
  175. data/test/acceptance/support/matchers/match_output.rb +1 -1
  176. data/test/acceptance/support/matchers/succeed.rb +14 -0
  177. data/test/acceptance/support/network_tests.rb +29 -0
  178. data/test/acceptance/support/output.rb +9 -1
  179. data/test/acceptance/support/shared/base_context.rb +16 -9
  180. data/test/acceptance/support/shared/command_examples.rb +4 -4
  181. data/test/acceptance/suspend_test.rb +1 -1
  182. data/test/acceptance/up_basic_test.rb +26 -7
  183. data/test/acceptance/up_with_box_url.rb +1 -1
  184. data/test/acceptance/vagrant_test.rb +1 -1
  185. data/test/acceptance/version_test.rb +0 -5
  186. data/test/support/isolated_environment.rb +46 -0
  187. data/test/{acceptance/support → support}/tempdir.rb +0 -0
  188. data/test/unit/base.rb +21 -0
  189. data/test/unit/support/isolated_environment.rb +39 -0
  190. data/test/unit/support/shared/base_context.rb +30 -0
  191. data/test/unit/vagrant/action/builder_test.rb +126 -177
  192. data/test/unit/vagrant/action/environment_test.rb +10 -21
  193. data/test/unit/vagrant/action/runner_test.rb +65 -0
  194. data/test/unit/vagrant/action/warden_test.rb +64 -97
  195. data/test/unit/vagrant/box_collection_test.rb +44 -33
  196. data/test/unit/vagrant/box_test.rb +25 -65
  197. data/test/unit/vagrant/command/base_test.rb +141 -14
  198. data/test/unit/vagrant/config/base_test.rb +16 -43
  199. data/test/unit/vagrant/config/loader_test.rb +79 -0
  200. data/test/unit/vagrant/config/top_test.rb +69 -0
  201. data/test/unit/vagrant/config/vm_test.rb +62 -47
  202. data/test/unit/vagrant/config_test.rb +16 -151
  203. data/test/unit/vagrant/data_store_test.rb +43 -61
  204. data/test/unit/vagrant/downloaders/base_test.rb +12 -22
  205. data/test/unit/vagrant/downloaders/file_test.rb +58 -31
  206. data/test/unit/vagrant/downloaders/http_test.rb +12 -86
  207. data/test/unit/vagrant/environment_test.rb +107 -536
  208. data/test/unit/vagrant/hosts_test.rb +36 -0
  209. data/test/unit/vagrant/registry_test.rb +56 -0
  210. data/test/unit/vagrant/util/file_checksum_test.rb +23 -0
  211. data/test/unit/vagrant/util/hash_with_indifferent_access_test.rb +23 -24
  212. data/test/unit/vagrant/util/network_ip_test.rb +17 -0
  213. data/test/unit/vagrant/util/retryable_test.rb +90 -34
  214. data/test/unit/vagrant_test.rb +27 -0
  215. data/test/{unit → unit_legacy}/locales/en.yml +0 -0
  216. data/test/{unit → unit_legacy}/test_helper.rb +0 -0
  217. data/test/{unit → unit_legacy}/vagrant/action/box/destroy_test.rb +0 -0
  218. data/test/{unit → unit_legacy}/vagrant/action/box/download_test.rb +0 -0
  219. data/test/{unit → unit_legacy}/vagrant/action/box/package_test.rb +0 -0
  220. data/test/{unit → unit_legacy}/vagrant/action/box/unpackage_test.rb +0 -0
  221. data/test/{unit → unit_legacy}/vagrant/action/box/verify_test.rb +0 -0
  222. data/test/{unit → unit_legacy}/vagrant/action/env/set_test.rb +0 -0
  223. data/test/{unit → unit_legacy}/vagrant/action/general/package_test.rb +0 -0
  224. data/test/{unit → unit_legacy}/vagrant/action/general/validate_test.rb +0 -0
  225. data/test/{unit → unit_legacy}/vagrant/action/vm/boot_test.rb +0 -0
  226. data/test/{unit → unit_legacy}/vagrant/action/vm/check_accessible_test.rb +0 -0
  227. data/test/{unit → unit_legacy}/vagrant/action/vm/check_box_test.rb +0 -0
  228. data/test/{unit → unit_legacy}/vagrant/action/vm/check_guest_additions_test.rb +0 -0
  229. data/test/{unit → unit_legacy}/vagrant/action/vm/clean_machine_folder_test.rb +0 -0
  230. data/test/{unit → unit_legacy}/vagrant/action/vm/clear_forwarded_ports_test.rb +0 -0
  231. data/test/{unit → unit_legacy}/vagrant/action/vm/clear_nfs_exports_test.rb +0 -0
  232. data/test/{unit → unit_legacy}/vagrant/action/vm/clear_shared_folders_test.rb +0 -0
  233. data/test/{unit → unit_legacy}/vagrant/action/vm/customize_test.rb +0 -0
  234. data/test/{unit → unit_legacy}/vagrant/action/vm/destroy_test.rb +0 -0
  235. data/test/{unit → unit_legacy}/vagrant/action/vm/destroy_unused_network_interfaces_test.rb +0 -0
  236. data/test/{unit → unit_legacy}/vagrant/action/vm/discard_state_test.rb +0 -0
  237. data/test/{unit → unit_legacy}/vagrant/action/vm/export_test.rb +0 -0
  238. data/test/{unit → unit_legacy}/vagrant/action/vm/forward_ports_helpers_test.rb +0 -0
  239. data/test/{unit → unit_legacy}/vagrant/action/vm/forward_ports_test.rb +0 -0
  240. data/test/{unit → unit_legacy}/vagrant/action/vm/halt_test.rb +0 -0
  241. data/test/{unit → unit_legacy}/vagrant/action/vm/host_name_test.rb +0 -0
  242. data/test/{unit → unit_legacy}/vagrant/action/vm/import_test.rb +0 -0
  243. data/test/{unit → unit_legacy}/vagrant/action/vm/match_mac_address_test.rb +0 -0
  244. data/test/{unit → unit_legacy}/vagrant/action/vm/modify_test.rb +0 -0
  245. data/test/{unit → unit_legacy}/vagrant/action/vm/network_test.rb +0 -0
  246. data/test/{unit → unit_legacy}/vagrant/action/vm/nfs_helpers_test.rb +0 -0
  247. data/test/{unit → unit_legacy}/vagrant/action/vm/nfs_test.rb +0 -0
  248. data/test/{unit → unit_legacy}/vagrant/action/vm/package_test.rb +0 -0
  249. data/test/{unit → unit_legacy}/vagrant/action/vm/package_vagrantfile_test.rb +0 -0
  250. data/test/{unit → unit_legacy}/vagrant/action/vm/provision_test.rb +0 -0
  251. data/test/{unit → unit_legacy}/vagrant/action/vm/provisioner_cleanup_test.rb +0 -0
  252. data/test/{unit → unit_legacy}/vagrant/action/vm/resume_test.rb +0 -0
  253. data/test/{unit → unit_legacy}/vagrant/action/vm/share_folders_test.rb +0 -0
  254. data/test/{unit → unit_legacy}/vagrant/action/vm/suspend_test.rb +0 -0
  255. data/test/{unit → unit_legacy}/vagrant/action_test.rb +0 -0
  256. data/test/unit_legacy/vagrant/box_collection_test.rb +45 -0
  257. data/test/unit_legacy/vagrant/box_test.rb +74 -0
  258. data/test/{unit → unit_legacy}/vagrant/cli_test.rb +0 -0
  259. data/test/unit_legacy/vagrant/command/base_test.rb +23 -0
  260. data/test/{unit → unit_legacy}/vagrant/command/group_base_test.rb +0 -0
  261. data/test/{unit → unit_legacy}/vagrant/command/helpers_test.rb +0 -0
  262. data/test/{unit → unit_legacy}/vagrant/command/init_test.rb +0 -0
  263. data/test/{unit → unit_legacy}/vagrant/command/package_test.rb +0 -0
  264. data/test/unit_legacy/vagrant/config/base_test.rb +52 -0
  265. data/test/{unit → unit_legacy}/vagrant/config/error_recorder_test.rb +0 -0
  266. data/test/{unit → unit_legacy}/vagrant/config/ssh_test.rb +0 -0
  267. data/test/{unit → unit_legacy}/vagrant/config/vagrant_test.rb +0 -0
  268. data/test/{unit → unit_legacy}/vagrant/config/vm/provisioner_test.rb +0 -0
  269. data/test/unit_legacy/vagrant/config/vm_test.rb +47 -0
  270. data/test/unit_legacy/vagrant/config_test.rb +148 -0
  271. data/test/unit_legacy/vagrant/downloaders/http_test.rb +93 -0
  272. data/test/unit_legacy/vagrant/environment_test.rb +539 -0
  273. data/test/{unit → unit_legacy}/vagrant/errors_test.rb +0 -0
  274. data/test/{unit → unit_legacy}/vagrant/hosts/base_test.rb +0 -0
  275. data/test/{unit → unit_legacy}/vagrant/hosts/bsd_test.rb +0 -0
  276. data/test/{unit → unit_legacy}/vagrant/hosts/linux_test.rb +0 -0
  277. data/test/{unit → unit_legacy}/vagrant/plugin_test.rb +0 -0
  278. data/test/{unit → unit_legacy}/vagrant/provisioners/base_test.rb +0 -0
  279. data/test/{unit → unit_legacy}/vagrant/provisioners/chef_client_test.rb +0 -0
  280. data/test/{unit → unit_legacy}/vagrant/provisioners/chef_solo_test.rb +0 -0
  281. data/test/{unit → unit_legacy}/vagrant/provisioners/chef_test.rb +0 -0
  282. data/test/{unit → unit_legacy}/vagrant/provisioners/puppet_server_test.rb +0 -0
  283. data/test/{unit → unit_legacy}/vagrant/provisioners/puppet_test.rb +0 -0
  284. data/test/{unit → unit_legacy}/vagrant/provisioners/shell_test.rb +0 -0
  285. data/test/{unit → unit_legacy}/vagrant/ssh/session_test.rb +0 -0
  286. data/test/{unit → unit_legacy}/vagrant/ssh_test.rb +0 -0
  287. data/test/{unit → unit_legacy}/vagrant/systems/base_test.rb +0 -0
  288. data/test/{unit → unit_legacy}/vagrant/systems/linux_test.rb +0 -0
  289. data/test/{unit → unit_legacy}/vagrant/util/busy_test.rb +0 -0
  290. data/test/{unit → unit_legacy}/vagrant/util/counter_test.rb +0 -0
  291. data/test/{unit → unit_legacy}/vagrant/util/platform_test.rb +0 -0
  292. data/test/{unit → unit_legacy}/vagrant/util/stacked_proc_runner_test.rb +0 -0
  293. data/test/{unit → unit_legacy}/vagrant/util/template_renderer_test.rb +0 -0
  294. data/test/{unit → unit_legacy}/vagrant/vm_test.rb +0 -0
  295. data/vagrant.gemspec +7 -9
  296. metadata +214 -216
  297. data/keys/vagrant.ppk +0 -26
  298. data/lib/vagrant/action/box.rb +0 -11
  299. data/lib/vagrant/action/env.rb +0 -7
  300. data/lib/vagrant/action/general.rb +0 -8
  301. data/lib/vagrant/action/vm.rb +0 -34
  302. data/lib/vagrant/action/vm/forward_ports_helpers.rb +0 -28
  303. data/lib/vagrant/action/vm/modify.rb +0 -37
  304. data/lib/vagrant/action/vm/nfs_helpers.rb +0 -11
  305. data/lib/vagrant/command/group_base.rb +0 -107
  306. data/lib/vagrant/command/helpers.rb +0 -33
  307. data/lib/vagrant/command/named_base.rb +0 -14
  308. data/lib/vagrant/command/upgrade_to_060.rb +0 -45
  309. data/lib/vagrant/command/version.rb +0 -13
  310. data/lib/vagrant/ssh/session.rb +0 -136
  311. data/lib/vagrant/systems.rb +0 -13
  312. data/lib/vagrant/systems/arch.rb +0 -34
  313. data/lib/vagrant/systems/debian.rb +0 -36
  314. data/lib/vagrant/systems/gentoo.rb +0 -27
  315. data/lib/vagrant/systems/linux.rb +0 -82
  316. data/lib/vagrant/systems/linux/error.rb +0 -9
  317. data/lib/vagrant/systems/redhat.rb +0 -48
  318. data/lib/vagrant/systems/solaris.rb +0 -113
  319. data/lib/vagrant/systems/ubuntu.rb +0 -17
  320. data/templates/network_entry_arch.erb +0 -9
  321. data/templates/network_entry_debian.erb +0 -8
  322. data/templates/network_entry_gentoo.erb +0 -5
  323. data/templates/network_entry_redhat.erb +0 -9
  324. data/test/unit/vagrant/ui_test.rb +0 -29
@@ -1,5 +1,5 @@
1
1
  module Vagrant
2
- class Action
2
+ module Action
3
3
  module VM
4
4
  class Halt
5
5
  def initialize(app, env, options=nil)
@@ -8,12 +8,15 @@ module Vagrant
8
8
  end
9
9
 
10
10
  def call(env)
11
- if env["vm"].created? && env["vm"].vm.running?
12
- env["vm"].system.halt if !env["force"]
11
+ if env[:vm].state == :running
12
+ if !env["force"]
13
+ env[:ui].info I18n.t("vagrant.actions.vm.halt.graceful")
14
+ env[:vm].guest.halt
15
+ end
13
16
 
14
- if env["vm"].vm.state(true) != :powered_off
15
- env.ui.info I18n.t("vagrant.actions.vm.halt.force")
16
- env["vm"].vm.stop
17
+ if env[:vm].state != :poweroff
18
+ env[:ui].info I18n.t("vagrant.actions.vm.halt.force")
19
+ env[:vm].driver.halt
17
20
  end
18
21
 
19
22
  # Sleep for a second to verify that the VM properly
@@ -1,5 +1,5 @@
1
1
  module Vagrant
2
- class Action
2
+ module Action
3
3
  module VM
4
4
  class HostName
5
5
  def initialize(app, env)
@@ -9,10 +9,10 @@ module Vagrant
9
9
  def call(env)
10
10
  @app.call(env)
11
11
 
12
- host_name = env["config"].vm.host_name
12
+ host_name = env[:vm].config.vm.host_name
13
13
  if !host_name.nil?
14
- env.ui.info I18n.t("vagrant.actions.vm.host_name.setting")
15
- env["vm"].system.change_host_name(host_name)
14
+ env[:ui].info I18n.t("vagrant.actions.vm.host_name.setting")
15
+ env[:vm].guest.change_host_name(host_name)
16
16
  end
17
17
  end
18
18
  end
@@ -1,5 +1,5 @@
1
1
  module Vagrant
2
- class Action
2
+ module Action
3
3
  module VM
4
4
  class Import
5
5
  def initialize(app, env)
@@ -7,31 +7,40 @@ module Vagrant
7
7
  end
8
8
 
9
9
  def call(env)
10
- env.ui.info I18n.t("vagrant.actions.vm.import.importing", :name => env.env.box.name)
10
+ env[:ui].info I18n.t("vagrant.actions.vm.import.importing", :name => env[:vm].box.name)
11
11
 
12
12
  # Import the virtual machine
13
- env.env.vm.vm = VirtualBox::VM.import(env.env.box.ovf_file.to_s) do |progress|
14
- env.ui.clear_line
15
- env.ui.report_progress(progress.percent, 100, false)
13
+ name = File.basename(env[:vm].env.cwd) + "_#{Time.now.to_i}"
14
+ ovf_file = env[:vm].box.directory.join("box.ovf").to_s
15
+ env[:vm].uuid = env[:vm].driver.import(ovf_file, name) do |progress|
16
+ env[:ui].clear_line
17
+ env[:ui].report_progress(progress, 100, false)
16
18
  end
17
19
 
18
20
  # Clear the line one last time since the progress meter doesn't disappear
19
21
  # immediately.
20
- env.ui.clear_line
22
+ env[:ui].clear_line
23
+
24
+ # If we got interrupted, then the import could have been
25
+ # interrupted and its not a big deal. Just return out.
26
+ return if env[:interrupted]
21
27
 
22
28
  # Flag as erroneous and return if import failed
23
- raise Errors::VMImportFailure if !env["vm"].vm
29
+ raise Errors::VMImportFailure if !env[:vm].uuid
24
30
 
25
31
  # Import completed successfully. Continue the chain
26
32
  @app.call(env)
27
33
  end
28
34
 
29
35
  def recover(env)
30
- if env["vm"].created?
36
+ if env[:vm].created?
31
37
  return if env["vagrant.error"].is_a?(Errors::VagrantError)
32
38
 
33
- # Interrupted, destroy the VM
34
- env["actions"].run(:destroy)
39
+ # Interrupted, destroy the VM. We note that we don't want to
40
+ # validate the configuration here.
41
+ destroy_env = env.clone
42
+ destroy_env[:validate] = false
43
+ env[:action_runner].run(:destroy, destroy_env)
35
44
  end
36
45
  end
37
46
  end
@@ -1,5 +1,5 @@
1
1
  module Vagrant
2
- class Action
2
+ module Action
3
3
  module VM
4
4
  class MatchMACAddress
5
5
  def initialize(app, env)
@@ -7,16 +7,11 @@ module Vagrant
7
7
  end
8
8
 
9
9
  def call(env)
10
- raise Errors::VMBaseMacNotSpecified if !env.env.config.vm.base_mac
10
+ raise Errors::VMBaseMacNotSpecified if !env[:vm].config.vm.base_mac
11
11
 
12
12
  # Create the proc which we want to use to modify the virtual machine
13
- proc = lambda do |vm|
14
- env.ui.info I18n.t("vagrant.actions.vm.match_mac.matching")
15
- vm.network_adapters.first.mac_address = env["config"].vm.base_mac
16
- end
17
-
18
- # Add the proc to the modification chain
19
- env["vm.modify"].call(proc)
13
+ env[:ui].info I18n.t("vagrant.actions.vm.match_mac.matching")
14
+ env[:vm].driver.set_mac_address(env[:vm].config.vm.base_mac)
20
15
 
21
16
  @app.call(env)
22
17
  end
@@ -1,144 +1,350 @@
1
+ require 'set'
2
+
3
+ require 'log4r'
4
+
5
+ require 'vagrant/util/network_ip'
6
+
1
7
  module Vagrant
2
- class Action
8
+ module Action
3
9
  module VM
4
- # Networking middleware for Vagrant. This enables host only
5
- # networking on VMs if configured as such.
10
+ # This action handles all `config.vm.network` configurations by
11
+ # setting up the VM properly and enabling the networks afterword.
6
12
  class Network
13
+ # Utilities to deal with network addresses
14
+ include Util::NetworkIP
15
+
7
16
  def initialize(app, env)
17
+ @logger = Log4r::Logger.new("vagrant::action::vm::network")
18
+
8
19
  @app = app
20
+ end
21
+
22
+ def call(env)
9
23
  @env = env
10
24
 
11
- if enable_network? && Util::Platform.windows? && Util::Platform.bit64?
12
- raise Errors::NetworkNotImplemented
25
+ # First we have to get the array of adapters that we need
26
+ # to create on the virtual machine itself, as well as the
27
+ # driver-agnostic network configurations for each.
28
+ @logger.debug("Determining adapters and networks...")
29
+ adapters = []
30
+ networks = []
31
+ env[:vm].config.vm.networks.each do |type, args|
32
+ # Get the normalized configuration we'll use around
33
+ config = send("#{type}_config", args)
34
+
35
+ # Get the virtualbox adapter configuration
36
+ adapter = send("#{type}_adapter", config)
37
+ adapters << adapter
38
+
39
+ # Get the network configuration
40
+ network = send("#{type}_network_config", config)
41
+ networks << network
13
42
  end
14
43
 
15
- env["config"].vm.network_options.compact.each do |network_options|
16
- raise Errors::NetworkCollision if !verify_no_bridge_collision(network_options)
44
+ if !adapters.empty?
45
+ # Automatically assign an adapter number to any adapters
46
+ # that aren't explicitly set.
47
+ @logger.debug("Assigning adapter locations...")
48
+ assign_adapter_locations(adapters)
49
+
50
+ # Verify that our adapters are good just prior to enabling them.
51
+ verify_adapters(adapters)
52
+
53
+ # Create all the network interfaces
54
+ @logger.info("Enabling adapters...")
55
+ env[:ui].info I18n.t("vagrant.actions.vm.network.preparing")
56
+ env[:vm].driver.enable_adapters(adapters)
57
+ end
58
+
59
+ # Continue the middleware chain. We're done with our VM
60
+ # setup until after it is booted.
61
+ @app.call(env)
62
+
63
+ if !adapters.empty?
64
+ # Determine the interface numbers for the guest.
65
+ assign_interface_numbers(networks, adapters)
66
+
67
+ # Configure all the network interfaces on the guest.
68
+ env[:ui].info I18n.t("vagrant.actions.vm.network.configuring")
69
+ env[:vm].guest.configure_networks(networks)
17
70
  end
18
71
  end
19
72
 
20
- def call(env)
21
- @env = env
22
- assign_network if enable_network?
73
+ # This method assigns the adapter to use for the adapter.
74
+ # e.g. it says that the first adapter is actually on the
75
+ # virtual machine's 2nd adapter location.
76
+ #
77
+ # It determines the adapter numbers by simply finding the
78
+ # "next available" in each case.
79
+ #
80
+ # The adapters are modified in place by adding an ":adapter"
81
+ # field to each.
82
+ def assign_adapter_locations(adapters)
83
+ available = Set.new(1..8)
23
84
 
24
- @app.call(env)
85
+ # Determine which NICs are actually available.
86
+ interfaces = @env[:vm].driver.read_network_interfaces
87
+ interfaces.each do |number, nic|
88
+ # Remove the number from the available NICs if the
89
+ # NIC is in use.
90
+ available.delete(number) if nic[:type] != :none
91
+ end
25
92
 
26
- if enable_network?
27
- @env.ui.info I18n.t("vagrant.actions.vm.network.enabling")
93
+ # Based on the available set, assign in order to
94
+ # the adapters.
95
+ available = available.to_a.sort
96
+ @logger.debug("Available NICs: #{available.inspect}")
97
+ adapters.each do |adapter|
98
+ # Ignore the adapters that already have been assigned
99
+ if !adapter[:adapter]
100
+ # If we have no available adapters, then that is an exceptional
101
+ # event.
102
+ raise Errors::NetworkNoAdapters if available.empty?
28
103
 
29
- # Prepare for new networks...
30
- options = @env.env.config.vm.network_options.compact
31
- options.each do |network_options|
32
- @env["vm"].system.prepare_host_only_network(network_options)
104
+ # Otherwise, assign as the adapter the next available item
105
+ adapter[:adapter] = available.shift
33
106
  end
107
+ end
108
+ end
34
109
 
35
- # Then enable the networks...
36
- options.each do |network_options|
37
- @env["vm"].system.enable_host_only_network(network_options)
38
- end
110
+ # Verifies that the adapter configurations look good. This will
111
+ # raise an exception in the case that any errors occur.
112
+ def verify_adapters(adapters)
113
+ # Verify that there are no collisions in the adapters being used.
114
+ used = Set.new
115
+ adapters.each do |adapter|
116
+ raise Errors::NetworkAdapterCollision if used.include?(adapter[:adapter])
117
+ used.add(adapter[:adapter])
39
118
  end
40
119
  end
41
120
 
42
- # Verifies that there is no collision with a bridged network interface
43
- # for the given network options.
44
- def verify_no_bridge_collision(net_options)
45
- interfaces = VirtualBox::Global.global.host.network_interfaces
46
- interfaces.each do |ni|
47
- next if ni.interface_type == :host_only
121
+ # Assigns the actual interface number of a network based on the
122
+ # enabled NICs on the virtual machine.
123
+ #
124
+ # This interface number is used by the guest to configure the
125
+ # NIC on the guest VM.
126
+ #
127
+ # The networks are modified in place by adding an ":interface"
128
+ # field to each.
129
+ def assign_interface_numbers(networks, adapters)
130
+ current = 0
131
+ adapter_to_interface = {}
48
132
 
49
- result = if net_options[:name]
50
- true if net_options[:name] == ni.name
51
- else
52
- true if matching_network?(ni, net_options)
133
+ # Make a first pass to assign interface numbers by adapter location
134
+ vm_adapters = @env[:vm].driver.read_network_interfaces
135
+ vm_adapters.each do |number, adapter|
136
+ if adapter[:type] != :none
137
+ # Not used, so assign the interface number and increment
138
+ adapter_to_interface[number] = current
139
+ current += 1
53
140
  end
54
-
55
- return false if result
56
141
  end
57
142
 
58
- true
59
- end
143
+ # Make a pass through the adapters to assign the :interface
144
+ # key to each network configuration.
145
+ adapters.each_index do |i|
146
+ adapter = adapters[i]
147
+ network = networks[i]
60
148
 
61
- def enable_network?
62
- !@env.env.config.vm.network_options.compact.empty?
149
+ # Figure out the interface number by simple lookup
150
+ network[:interface] = adapter_to_interface[adapter[:adapter]]
151
+ end
63
152
  end
64
153
 
65
- # Enables and assigns the host only network to the proper
66
- # adapter on the VM, and saves the adapter.
67
- def assign_network
68
- @env.ui.info I18n.t("vagrant.actions.vm.network.preparing")
69
-
70
- @env.env.config.vm.network_options.compact.each do |network_options|
71
- adapter = @env["vm"].vm.network_adapters[network_options[:adapter]]
72
- adapter.enabled = true
73
- adapter.attachment_type = :host_only
74
- adapter.host_only_interface = network_name(network_options)
75
- adapter.mac_address = network_options[:mac].gsub(':', '') if network_options[:mac]
76
- adapter.save
154
+ def hostonly_config(args)
155
+ ip = args[0]
156
+ options = args[1] || {}
157
+
158
+ # Determine if we're dealing with a static IP or a DHCP-served IP.
159
+ type = ip == :dhcp ? :dhcp : :static
160
+
161
+ # Default IP is in the 20-bit private network block for DHCP based networks
162
+ ip = "172.28.128.1" if type == :dhcp
163
+
164
+ options = {
165
+ :type => type,
166
+ :ip => ip,
167
+ :netmask => "255.255.255.0",
168
+ :adapter => nil,
169
+ :mac => nil,
170
+ :name => nil
171
+ }.merge(options)
172
+
173
+ # Verify that this hostonly network wouldn't conflict with any
174
+ # bridged interfaces
175
+ verify_no_bridge_collision(options)
176
+
177
+ # Get the network address and IP parts which are used for many
178
+ # default calculations
179
+ netaddr = network_address(options[:ip], options[:netmask])
180
+ ip_parts = netaddr.split(".").map { |i| i.to_i }
181
+
182
+ # Calculate the adapter IP, which we assume is the IP ".1" at the
183
+ # end usually.
184
+ adapter_ip = ip_parts.dup
185
+ adapter_ip[3] += 1
186
+ options[:adapter_ip] ||= adapter_ip.join(".")
187
+
188
+ if type == :dhcp
189
+ # Calculate the DHCP server IP, which is the network address
190
+ # with the final octet + 2. So "172.28.0.0" turns into "172.28.0.2"
191
+ dhcp_ip = ip_parts.dup
192
+ dhcp_ip[3] += 2
193
+ options[:dhcp_ip] ||= dhcp_ip.join(".")
194
+
195
+ # Calculate the lower and upper bound for the DHCP server
196
+ dhcp_lower = ip_parts.dup
197
+ dhcp_lower[3] += 3
198
+ options[:dhcp_lower] ||= dhcp_lower.join(".")
199
+
200
+ dhcp_upper = ip_parts.dup
201
+ dhcp_upper[3] = 254
202
+ options[:dhcp_upper] ||= dhcp_upper.join(".")
77
203
  end
204
+
205
+ # Return the hostonly network configuration
206
+ return options
78
207
  end
79
208
 
80
- # Returns the name of the proper host only network, or creates
81
- # it if it does not exist. Vagrant determines if the host only
82
- # network exists by comparing the netmask and the IP.
83
- def network_name(net_options)
84
- # First try to find a matching network
85
- interfaces = VirtualBox::Global.global.host.network_interfaces
86
- interfaces.each do |ni|
87
- # Ignore non-host only interfaces which may also match,
88
- # since they're not valid options.
89
- next if ni.interface_type != :host_only
90
-
91
- if net_options[:name]
92
- return ni.name if net_options[:name] == ni.name
209
+ def hostonly_adapter(config)
210
+ @logger.debug("Searching for matching network: #{config[:ip]}")
211
+ interface = find_matching_hostonly_network(config)
212
+
213
+ if !interface
214
+ @logger.debug("Network not found. Creating if we can.")
215
+
216
+ # It is an error case if a specific name was given but the network
217
+ # doesn't exist.
218
+ if config[:name]
219
+ raise Errors::NetworkNotFound, :name => config[:name]
220
+ end
221
+
222
+ # Otherwise, we create a new network and put the net network
223
+ # in the list of available networks so other network definitions
224
+ # can use it!
225
+ interface = create_hostonly_network(config)
226
+ @logger.debug("Created network: #{interface[:name]}")
227
+ end
228
+
229
+ if config[:type] == :dhcp
230
+ # Check that if there is a DHCP server attached on our interface,
231
+ # then it is identical. Otherwise, we can't set it.
232
+ if interface[:dhcp]
233
+ valid = interface[:dhcp][:ip] == config[:dhcp_ip] &&
234
+ interface[:dhcp][:lower] == config[:dhcp_lower] &&
235
+ interface[:dhcp][:upper] == config[:dhcp_upper]
236
+
237
+ raise Errors::NetworkDHCPAlreadyAttached if !valid
238
+
239
+ @logger.debug("DHCP server already properly configured")
93
240
  else
94
- return ni.name if matching_network?(ni, net_options)
241
+ # Configure the DHCP server for the network.
242
+ @logger.debug("Creating a DHCP server...")
243
+ @env[:vm].driver.create_dhcp_server(interface[:name], config)
95
244
  end
96
245
  end
97
246
 
98
- raise Errors::NetworkNotFound, :name => net_options[:name] if net_options[:name]
247
+ return {
248
+ :adapter => config[:adapter],
249
+ :type => :hostonly,
250
+ :hostonly => interface[:name],
251
+ :mac_address => config[:mac]
252
+ }
253
+ end
254
+
255
+ def hostonly_network_config(config)
256
+ return {
257
+ :type => config[:type],
258
+ :ip => config[:ip],
259
+ :netmask => config[:netmask]
260
+ }
261
+ end
99
262
 
100
- # One doesn't exist, create it.
101
- @env.ui.info I18n.t("vagrant.actions.vm.network.creating")
263
+ # Creates a new hostonly network that matches the network requested
264
+ # by the given host-only network configuration.
265
+ def create_hostonly_network(config)
266
+ # Create the options that are going to be used to create our
267
+ # new network.
268
+ options = config.dup
269
+ options[:ip] = options[:adapter_ip]
102
270
 
103
- ni = interfaces.create
104
- ni.enable_static(network_ip(net_options[:ip], net_options[:netmask]),
105
- net_options[:netmask])
106
- ni.name
271
+ @env[:vm].driver.create_host_only_network(options)
107
272
  end
108
273
 
109
- # Tests if a network matches the given options by applying the
110
- # netmask to the IP of the network and also to the IP of the
111
- # virtual machine and see if they match.
112
- def matching_network?(interface, net_options)
113
- interface.network_mask == net_options[:netmask] &&
114
- apply_netmask(interface.ip_address, interface.network_mask) ==
115
- apply_netmask(net_options[:ip], net_options[:netmask])
274
+ # Finds a host only network that matches our configuration on VirtualBox.
275
+ # This will return nil if a matching network does not exist.
276
+ def find_matching_hostonly_network(config)
277
+ this_netaddr = network_address(config[:ip], config[:netmask])
278
+
279
+ @env[:vm].driver.read_host_only_interfaces.each do |interface|
280
+ if config[:name] && config[:name] == interface[:name]
281
+ return interface
282
+ elsif this_netaddr == network_address(interface[:ip], interface[:netmask])
283
+ return interface
284
+ end
285
+ end
286
+
287
+ nil
116
288
  end
117
289
 
118
- # Applies a netmask to an IP and returns the corresponding
119
- # parts.
120
- def apply_netmask(ip, netmask)
121
- ip = split_ip(ip)
122
- netmask = split_ip(netmask)
290
+ # Verifies that a host-only network subnet would not collide with
291
+ # a bridged networking interface.
292
+ #
293
+ # If the subnets overlap in any way then the host only network
294
+ # will not work because the routing tables will force the traffic
295
+ # onto the real interface rather than the virtualbox interface.
296
+ def verify_no_bridge_collision(options)
297
+ this_netaddr = network_address(options[:ip], options[:netmask])
123
298
 
124
- ip.map do |part|
125
- part & netmask.shift
299
+ @env[:vm].driver.read_bridged_interfaces.each do |interface|
300
+ that_netaddr = network_address(interface[:ip], interface[:netmask])
301
+ raise Errors::NetworkCollision if this_netaddr == that_netaddr
126
302
  end
127
303
  end
128
304
 
129
- # Splits an IP and converts each portion into an int.
130
- def split_ip(ip)
131
- ip.split(".").map do |i|
132
- i.to_i
305
+ def bridged_config(args)
306
+ options = args[0] || {}
307
+
308
+ return {
309
+ :adapter => nil,
310
+ :mac => nil
311
+ }.merge(options)
312
+ end
313
+
314
+ def bridged_adapter(config)
315
+ bridgedifs = @env[:vm].driver.read_bridged_interfaces
316
+
317
+ # Output all the interfaces that are available as choices
318
+ @env[:ui].info I18n.t("vagrant.actions.vm.bridged_networking.available",
319
+ :prefix => false)
320
+ bridgedifs.each_index do |index|
321
+ interface = bridgedifs[index]
322
+ @env[:ui].info("#{index + 1}) #{interface[:name]}", :prefix => false)
133
323
  end
324
+
325
+ # The range of valid choices
326
+ valid = Range.new(1, bridgedifs.length)
327
+
328
+ # The choice that the user has chosen as the bridging interface
329
+ choice = nil
330
+ while !valid.include?(choice)
331
+ choice = @env[:ui].ask("What interface should the network bridge to? ")
332
+ choice = choice.to_i
333
+ end
334
+
335
+ # Given the choice we can now define the adapter we're using
336
+ return {
337
+ :adapter => config[:adapter],
338
+ :type => :bridged,
339
+ :bridge => bridgedifs[choice - 1][:name],
340
+ :mac_address => config[:mac]
341
+ }
134
342
  end
135
343
 
136
- # Returns a "network IP" which is a "good choice" for the IP
137
- # for the actual network based on the netmask.
138
- def network_ip(ip, netmask)
139
- parts = apply_netmask(ip, netmask)
140
- parts[3] += 1;
141
- parts.join(".")
344
+ def bridged_network_config(config)
345
+ return {
346
+ :type => :dhcp
347
+ }
142
348
  end
143
349
  end
144
350
  end