fixed-vagrant 0.7.4.dev

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 (242) hide show
  1. data/.gitignore +15 -0
  2. data/.yardopts +1 -0
  3. data/CHANGELOG.md +272 -0
  4. data/Gemfile +21 -0
  5. data/LICENSE +21 -0
  6. data/README.md +75 -0
  7. data/Rakefile +22 -0
  8. data/bin/vagrant +22 -0
  9. data/config/default.rb +39 -0
  10. data/contrib/README.md +12 -0
  11. data/contrib/emacs/vagrant.el +8 -0
  12. data/contrib/vim/vagrantfile.vim +9 -0
  13. data/keys/README.md +17 -0
  14. data/keys/vagrant +27 -0
  15. data/keys/vagrant.ppk +26 -0
  16. data/keys/vagrant.pub +1 -0
  17. data/lib/vagrant.rb +42 -0
  18. data/lib/vagrant/action.rb +134 -0
  19. data/lib/vagrant/action/box.rb +11 -0
  20. data/lib/vagrant/action/box/destroy.rb +21 -0
  21. data/lib/vagrant/action/box/download.rb +72 -0
  22. data/lib/vagrant/action/box/package.rb +19 -0
  23. data/lib/vagrant/action/box/unpackage.rb +55 -0
  24. data/lib/vagrant/action/box/verify.rb +23 -0
  25. data/lib/vagrant/action/builder.rb +124 -0
  26. data/lib/vagrant/action/builtin.rb +104 -0
  27. data/lib/vagrant/action/env.rb +7 -0
  28. data/lib/vagrant/action/env/set.rb +18 -0
  29. data/lib/vagrant/action/environment.rb +50 -0
  30. data/lib/vagrant/action/general.rb +8 -0
  31. data/lib/vagrant/action/general/package.rb +109 -0
  32. data/lib/vagrant/action/general/validate.rb +19 -0
  33. data/lib/vagrant/action/vm.rb +31 -0
  34. data/lib/vagrant/action/vm/boot.rb +48 -0
  35. data/lib/vagrant/action/vm/check_box.rb +28 -0
  36. data/lib/vagrant/action/vm/check_guest_additions.rb +30 -0
  37. data/lib/vagrant/action/vm/clean_machine_folder.rb +43 -0
  38. data/lib/vagrant/action/vm/clear_forwarded_ports.rb +39 -0
  39. data/lib/vagrant/action/vm/clear_nfs_exports.rb +20 -0
  40. data/lib/vagrant/action/vm/clear_shared_folders.rb +32 -0
  41. data/lib/vagrant/action/vm/customize.rb +21 -0
  42. data/lib/vagrant/action/vm/destroy.rb +19 -0
  43. data/lib/vagrant/action/vm/destroy_unused_network_interfaces.rb +30 -0
  44. data/lib/vagrant/action/vm/discard_state.rb +22 -0
  45. data/lib/vagrant/action/vm/export.rb +52 -0
  46. data/lib/vagrant/action/vm/forward_ports.rb +134 -0
  47. data/lib/vagrant/action/vm/forward_ports_helpers.rb +28 -0
  48. data/lib/vagrant/action/vm/halt.rb +29 -0
  49. data/lib/vagrant/action/vm/host_name.rb +21 -0
  50. data/lib/vagrant/action/vm/import.rb +35 -0
  51. data/lib/vagrant/action/vm/match_mac_address.rb +21 -0
  52. data/lib/vagrant/action/vm/network.rb +139 -0
  53. data/lib/vagrant/action/vm/nfs.rb +159 -0
  54. data/lib/vagrant/action/vm/nfs_helpers.rb +11 -0
  55. data/lib/vagrant/action/vm/package.rb +23 -0
  56. data/lib/vagrant/action/vm/package_vagrantfile.rb +33 -0
  57. data/lib/vagrant/action/vm/provision.rb +41 -0
  58. data/lib/vagrant/action/vm/resume.rb +20 -0
  59. data/lib/vagrant/action/vm/share_folders.rb +70 -0
  60. data/lib/vagrant/action/vm/suspend.rb +20 -0
  61. data/lib/vagrant/action/warden.rb +79 -0
  62. data/lib/vagrant/box.rb +90 -0
  63. data/lib/vagrant/box_collection.rb +53 -0
  64. data/lib/vagrant/cli.rb +55 -0
  65. data/lib/vagrant/command.rb +25 -0
  66. data/lib/vagrant/command/base.rb +106 -0
  67. data/lib/vagrant/command/box.rb +33 -0
  68. data/lib/vagrant/command/destroy.rb +17 -0
  69. data/lib/vagrant/command/group_base.rb +107 -0
  70. data/lib/vagrant/command/halt.rb +18 -0
  71. data/lib/vagrant/command/helpers.rb +33 -0
  72. data/lib/vagrant/command/init.rb +14 -0
  73. data/lib/vagrant/command/named_base.rb +14 -0
  74. data/lib/vagrant/command/package.rb +41 -0
  75. data/lib/vagrant/command/provision.rb +17 -0
  76. data/lib/vagrant/command/reload.rb +17 -0
  77. data/lib/vagrant/command/resume.rb +17 -0
  78. data/lib/vagrant/command/ssh.rb +42 -0
  79. data/lib/vagrant/command/ssh_config.rb +26 -0
  80. data/lib/vagrant/command/status.rb +22 -0
  81. data/lib/vagrant/command/suspend.rb +17 -0
  82. data/lib/vagrant/command/up.rb +19 -0
  83. data/lib/vagrant/command/upgrade_to_060.rb +45 -0
  84. data/lib/vagrant/command/version.rb +13 -0
  85. data/lib/vagrant/config.rb +123 -0
  86. data/lib/vagrant/config/base.rb +85 -0
  87. data/lib/vagrant/config/error_recorder.rb +19 -0
  88. data/lib/vagrant/config/nfs.rb +10 -0
  89. data/lib/vagrant/config/package.rb +9 -0
  90. data/lib/vagrant/config/ssh.rb +33 -0
  91. data/lib/vagrant/config/top.rb +61 -0
  92. data/lib/vagrant/config/vagrant.rb +16 -0
  93. data/lib/vagrant/config/vm.rb +137 -0
  94. data/lib/vagrant/config/vm/provisioner.rb +56 -0
  95. data/lib/vagrant/config/vm/sub_vm.rb +17 -0
  96. data/lib/vagrant/data_store.rb +70 -0
  97. data/lib/vagrant/downloaders.rb +7 -0
  98. data/lib/vagrant/downloaders/base.rb +23 -0
  99. data/lib/vagrant/downloaders/file.rb +22 -0
  100. data/lib/vagrant/downloaders/http.rb +64 -0
  101. data/lib/vagrant/environment.rb +392 -0
  102. data/lib/vagrant/errors.rb +332 -0
  103. data/lib/vagrant/hosts.rb +8 -0
  104. data/lib/vagrant/hosts/arch.rb +27 -0
  105. data/lib/vagrant/hosts/base.rb +78 -0
  106. data/lib/vagrant/hosts/bsd.rb +52 -0
  107. data/lib/vagrant/hosts/linux.rb +47 -0
  108. data/lib/vagrant/plugin.rb +57 -0
  109. data/lib/vagrant/provisioners.rb +9 -0
  110. data/lib/vagrant/provisioners/base.rb +63 -0
  111. data/lib/vagrant/provisioners/chef.rb +130 -0
  112. data/lib/vagrant/provisioners/chef_server.rb +103 -0
  113. data/lib/vagrant/provisioners/chef_solo.rb +142 -0
  114. data/lib/vagrant/provisioners/puppet.rb +137 -0
  115. data/lib/vagrant/provisioners/puppet_server.rb +55 -0
  116. data/lib/vagrant/provisioners/shell.rb +52 -0
  117. data/lib/vagrant/ssh.rb +173 -0
  118. data/lib/vagrant/ssh/session.rb +125 -0
  119. data/lib/vagrant/systems.rb +11 -0
  120. data/lib/vagrant/systems/base.rb +87 -0
  121. data/lib/vagrant/systems/debian.rb +36 -0
  122. data/lib/vagrant/systems/freebsd.rb +84 -0
  123. data/lib/vagrant/systems/gentoo.rb +27 -0
  124. data/lib/vagrant/systems/linux.rb +83 -0
  125. data/lib/vagrant/systems/linux/config.rb +21 -0
  126. data/lib/vagrant/systems/linux/error.rb +9 -0
  127. data/lib/vagrant/systems/redhat.rb +39 -0
  128. data/lib/vagrant/systems/solaris.rb +62 -0
  129. data/lib/vagrant/systems/ubuntu.rb +17 -0
  130. data/lib/vagrant/test_helpers.rb +128 -0
  131. data/lib/vagrant/ui.rb +69 -0
  132. data/lib/vagrant/util.rb +13 -0
  133. data/lib/vagrant/util/busy.rb +59 -0
  134. data/lib/vagrant/util/hash_with_indifferent_access.rb +63 -0
  135. data/lib/vagrant/util/plain_logger.rb +25 -0
  136. data/lib/vagrant/util/platform.rb +65 -0
  137. data/lib/vagrant/util/resource_logger.rb +63 -0
  138. data/lib/vagrant/util/retryable.rb +25 -0
  139. data/lib/vagrant/util/stacked_proc_runner.rb +35 -0
  140. data/lib/vagrant/util/template_renderer.rb +83 -0
  141. data/lib/vagrant/version.rb +6 -0
  142. data/lib/vagrant/vm.rb +177 -0
  143. data/templates/chef_server_client.erb +18 -0
  144. data/templates/chef_solo_solo.erb +19 -0
  145. data/templates/commands/init/Vagrantfile.erb +82 -0
  146. data/templates/config/validation_failed.erb +7 -0
  147. data/templates/locales/en.yml +535 -0
  148. data/templates/network_entry_debian.erb +8 -0
  149. data/templates/network_entry_gentoo.erb +5 -0
  150. data/templates/network_entry_redhat.erb +8 -0
  151. data/templates/nfs/exports.erb +5 -0
  152. data/templates/nfs/exports_linux.erb +5 -0
  153. data/templates/package_Vagrantfile.erb +11 -0
  154. data/templates/ssh_config.erb +9 -0
  155. data/test/locales/en.yml +8 -0
  156. data/test/test_helper.rb +26 -0
  157. data/test/vagrant/action/box/destroy_test.rb +18 -0
  158. data/test/vagrant/action/box/download_test.rb +125 -0
  159. data/test/vagrant/action/box/package_test.rb +25 -0
  160. data/test/vagrant/action/box/unpackage_test.rb +84 -0
  161. data/test/vagrant/action/box/verify_test.rb +30 -0
  162. data/test/vagrant/action/builder_test.rb +203 -0
  163. data/test/vagrant/action/env/set_test.rb +24 -0
  164. data/test/vagrant/action/environment_test.rb +27 -0
  165. data/test/vagrant/action/general/package_test.rb +268 -0
  166. data/test/vagrant/action/general/validate_test.rb +31 -0
  167. data/test/vagrant/action/vm/boot_test.rb +66 -0
  168. data/test/vagrant/action/vm/check_box_test.rb +56 -0
  169. data/test/vagrant/action/vm/check_guest_additions_test.rb +9 -0
  170. data/test/vagrant/action/vm/clean_machine_folder_test.rb +84 -0
  171. data/test/vagrant/action/vm/clear_forwarded_ports_test.rb +72 -0
  172. data/test/vagrant/action/vm/clear_nfs_exports_test.rb +22 -0
  173. data/test/vagrant/action/vm/clear_shared_folders_test.rb +49 -0
  174. data/test/vagrant/action/vm/customize_test.rb +30 -0
  175. data/test/vagrant/action/vm/destroy_test.rb +25 -0
  176. data/test/vagrant/action/vm/destroy_unused_network_interfaces_test.rb +49 -0
  177. data/test/vagrant/action/vm/discard_state_test.rb +45 -0
  178. data/test/vagrant/action/vm/export_test.rb +107 -0
  179. data/test/vagrant/action/vm/forward_ports_helpers_test.rb +70 -0
  180. data/test/vagrant/action/vm/forward_ports_test.rb +194 -0
  181. data/test/vagrant/action/vm/halt_test.rb +79 -0
  182. data/test/vagrant/action/vm/host_name_test.rb +36 -0
  183. data/test/vagrant/action/vm/import_test.rb +66 -0
  184. data/test/vagrant/action/vm/match_mac_address_test.rb +36 -0
  185. data/test/vagrant/action/vm/network_test.rb +286 -0
  186. data/test/vagrant/action/vm/nfs_helpers_test.rb +26 -0
  187. data/test/vagrant/action/vm/nfs_test.rb +260 -0
  188. data/test/vagrant/action/vm/package_test.rb +25 -0
  189. data/test/vagrant/action/vm/package_vagrantfile_test.rb +46 -0
  190. data/test/vagrant/action/vm/provision_test.rb +90 -0
  191. data/test/vagrant/action/vm/resume_test.rb +35 -0
  192. data/test/vagrant/action/vm/share_folders_test.rb +139 -0
  193. data/test/vagrant/action/vm/suspend_test.rb +35 -0
  194. data/test/vagrant/action/warden_test.rb +119 -0
  195. data/test/vagrant/action_test.rb +89 -0
  196. data/test/vagrant/box_collection_test.rb +45 -0
  197. data/test/vagrant/box_test.rb +74 -0
  198. data/test/vagrant/cli_test.rb +35 -0
  199. data/test/vagrant/command/base_test.rb +23 -0
  200. data/test/vagrant/command/group_base_test.rb +15 -0
  201. data/test/vagrant/command/helpers_test.rb +88 -0
  202. data/test/vagrant/command/package_test.rb +27 -0
  203. data/test/vagrant/config/base_test.rb +52 -0
  204. data/test/vagrant/config/error_recorder_test.rb +18 -0
  205. data/test/vagrant/config/ssh_test.rb +12 -0
  206. data/test/vagrant/config/vagrant_test.rb +35 -0
  207. data/test/vagrant/config/vm/provisioner_test.rb +92 -0
  208. data/test/vagrant/config/vm_test.rb +86 -0
  209. data/test/vagrant/config_test.rb +162 -0
  210. data/test/vagrant/data_store_test.rb +77 -0
  211. data/test/vagrant/downloaders/base_test.rb +28 -0
  212. data/test/vagrant/downloaders/file_test.rb +48 -0
  213. data/test/vagrant/downloaders/http_test.rb +80 -0
  214. data/test/vagrant/environment_test.rb +508 -0
  215. data/test/vagrant/errors_test.rb +42 -0
  216. data/test/vagrant/hosts/base_test.rb +46 -0
  217. data/test/vagrant/hosts/bsd_test.rb +53 -0
  218. data/test/vagrant/hosts/linux_test.rb +54 -0
  219. data/test/vagrant/plugin_test.rb +9 -0
  220. data/test/vagrant/provisioners/base_test.rb +63 -0
  221. data/test/vagrant/provisioners/chef_server_test.rb +188 -0
  222. data/test/vagrant/provisioners/chef_solo_test.rb +219 -0
  223. data/test/vagrant/provisioners/chef_test.rb +179 -0
  224. data/test/vagrant/provisioners/puppet_server_test.rb +68 -0
  225. data/test/vagrant/provisioners/puppet_test.rb +182 -0
  226. data/test/vagrant/provisioners/shell_test.rb +68 -0
  227. data/test/vagrant/ssh/session_test.rb +40 -0
  228. data/test/vagrant/ssh_test.rb +342 -0
  229. data/test/vagrant/systems/base_test.rb +18 -0
  230. data/test/vagrant/systems/linux_test.rb +114 -0
  231. data/test/vagrant/ui_test.rb +29 -0
  232. data/test/vagrant/util/busy_test.rb +106 -0
  233. data/test/vagrant/util/hash_with_indifferent_access_test.rb +39 -0
  234. data/test/vagrant/util/plain_logger_test.rb +17 -0
  235. data/test/vagrant/util/platform_test.rb +18 -0
  236. data/test/vagrant/util/resource_logger_test.rb +78 -0
  237. data/test/vagrant/util/retryable_test.rb +50 -0
  238. data/test/vagrant/util/stacked_proc_runner_test.rb +43 -0
  239. data/test/vagrant/util/template_renderer_test.rb +145 -0
  240. data/test/vagrant/vm_test.rb +291 -0
  241. data/vagrant.gemspec +36 -0
  242. metadata +514 -0
@@ -0,0 +1,134 @@
1
+ require File.join(File.dirname(__FILE__), 'forward_ports_helpers')
2
+
3
+ module Vagrant
4
+ class Action
5
+ module VM
6
+ class ForwardPorts
7
+ include ForwardPortsHelpers
8
+
9
+ def initialize(app,env)
10
+ @app = app
11
+ @env = env
12
+
13
+ threshold_check
14
+ external_collision_check
15
+ end
16
+
17
+ #--------------------------------------------------------------
18
+ # Prepare Helpers - These functions are not involved in actually
19
+ # executing the action
20
+ #--------------------------------------------------------------
21
+
22
+ # This method checks for any forwarded ports on the host below
23
+ # 1024, which causes the forwarded ports to fail.
24
+ def threshold_check
25
+ @env.env.config.vm.forwarded_ports.each do |name, options|
26
+ raise Errors::ForwardPortBelowThreshold if options[:hostport] <= 1024
27
+ end
28
+ end
29
+
30
+ # This method checks for any port collisions with any VMs
31
+ # which are already created (by Vagrant or otherwise).
32
+ # report the collisions detected or will attempt to fix them
33
+ # automatically if the port is configured to do so.
34
+ def external_collision_check
35
+ existing = used_ports
36
+ @env.env.config.vm.forwarded_ports.each do |name, options|
37
+ if existing.include?(options[:hostport].to_i)
38
+ handle_collision(name, options, existing)
39
+ end
40
+ end
41
+ end
42
+
43
+ # Handles any collisions. This method will either attempt to
44
+ # fix the collision automatically or will raise an error if
45
+ # auto fixing is disabled.
46
+ def handle_collision(name, options, existing_ports)
47
+ if !options[:auto]
48
+ # Auto fixing is disabled for this port forward, so we
49
+ # must throw an error so the user can fix it.
50
+ raise Errors::ForwardPortCollision, :name => name,
51
+ :host_port => options[:hostport].to_s,
52
+ :guest_port => options[:guestport].to_s
53
+ end
54
+
55
+ # Get the auto port range and get rid of the used ports and
56
+ # ports which are being used in other forwards so we're just
57
+ # left with available ports.
58
+ range = @env.env.config.vm.auto_port_range.to_a
59
+ range -= @env.env.config.vm.forwarded_ports.collect { |n, o| o[:hostport].to_i }
60
+ range -= existing_ports
61
+
62
+ if range.empty?
63
+ raise Errors::ForwardPortAutolistEmpty, :vm_name => @env["vm"].name,
64
+ :name => name,
65
+ :host_port => options[:hostport].to_s,
66
+ :guest_port => options[:guestport].to_s
67
+ end
68
+
69
+ # Set the port up to be the first one and add that port to
70
+ # the used list.
71
+ options[:hostport] = range.shift
72
+ existing_ports << options[:hostport]
73
+
74
+ # Notify the user
75
+ @env.ui.info(I18n.t("vagrant.actions.vm.forward_ports.fixed_collision",
76
+ :name => name,
77
+ :new_port => options[:hostport]))
78
+ end
79
+
80
+ #--------------------------------------------------------------
81
+ # Execution
82
+ #--------------------------------------------------------------
83
+ def call(env)
84
+ @env = env
85
+
86
+ forward_ports
87
+
88
+ @app.call(env)
89
+ end
90
+
91
+ def forward_ports
92
+ @env.ui.info I18n.t("vagrant.actions.vm.forward_ports.forwarding")
93
+
94
+ @env.env.config.vm.forwarded_ports.each do |name, options|
95
+ adapter = options[:adapter]
96
+ message_attributes = {
97
+ :name => name,
98
+ :guest_port => options[:guestport],
99
+ :host_port => options[:hostport],
100
+ :adapter => adapter + 1
101
+ }
102
+
103
+ # Assuming the only reason to establish port forwarding is because the VM is using Virtualbox NAT networking.
104
+ # Host-only or Bridged networking don't require port-forwarding and establishing forwarded ports on these
105
+ # attachment types has uncertain behaviour.
106
+ if @env["vm"].vm.network_adapters[adapter].attachment_type == :nat
107
+ @env.ui.info(I18n.t("vagrant.actions.vm.forward_ports.forwarding_entry", message_attributes))
108
+ forward_port(name, options)
109
+ else
110
+ @env.ui.info(I18n.t("vagrant.actions.vm.forward_ports.non_nat", message_attributes))
111
+ end
112
+ end
113
+
114
+ @env["vm"].vm.save
115
+ @env["vm"].reload!
116
+ end
117
+
118
+ #--------------------------------------------------------------
119
+ # General Helpers
120
+ #--------------------------------------------------------------
121
+
122
+ # Forwards a port.
123
+ def forward_port(name, options)
124
+ port = VirtualBox::NATForwardedPort.new
125
+ port.name = name
126
+ port.guestport = options[:guestport]
127
+ port.hostport = options[:hostport]
128
+ port.protocol = options[:protocol] || :tcp
129
+ @env["vm"].vm.network_adapters[options[:adapter]].nat_driver.forwarded_ports << port
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,28 @@
1
+ module Vagrant
2
+ class Action
3
+ module VM
4
+ # Helper methods for forwarding ports. Requires that the environment
5
+ # is set to the `@env` instance variable.
6
+ module ForwardPortsHelpers
7
+ # Returns an array of used ports. This method is implemented
8
+ # differently depending on the VirtualBox version, but the
9
+ # behavior is the same.
10
+ #
11
+ # @return [Array<String>]
12
+ def used_ports
13
+ result = VirtualBox::VM.all.collect do |vm|
14
+ if vm.running? && vm.uuid != @env["vm"].uuid
15
+ vm.network_adapters.collect do |na|
16
+ na.nat_driver.forwarded_ports.collect do |fp|
17
+ fp.hostport.to_i
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ result.flatten.uniq
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,29 @@
1
+ module Vagrant
2
+ class Action
3
+ module VM
4
+ class Halt
5
+ def initialize(app, env, options=nil)
6
+ @app = app
7
+ env.merge!(options || {})
8
+ end
9
+
10
+ def call(env)
11
+ if env["vm"].created? && env["vm"].vm.running?
12
+ env["vm"].system.halt if !env["force"]
13
+
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
+ end
18
+
19
+ # Sleep for a second to verify that the VM properly
20
+ # cleans itself up
21
+ sleep 1 if !env["vagrant.test"]
22
+ end
23
+
24
+ @app.call(env)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,21 @@
1
+ module Vagrant
2
+ class Action
3
+ module VM
4
+ class HostName
5
+ def initialize(app, env)
6
+ @app = app
7
+ end
8
+
9
+ def call(env)
10
+ @app.call(env)
11
+
12
+ host_name = env["config"].vm.host_name
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)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,35 @@
1
+ module Vagrant
2
+ class Action
3
+ module VM
4
+ class Import
5
+ def initialize(app, env)
6
+ @app = app
7
+ end
8
+
9
+ def call(env)
10
+ env.ui.info I18n.t("vagrant.actions.vm.import.importing", :name => env.env.box.name)
11
+
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.report_progress(progress.percent, 100, false)
15
+ end
16
+
17
+ # Flag as erroneous and return if import failed
18
+ raise Errors::VMImportFailure if !env["vm"].vm
19
+
20
+ # Import completed successfully. Continue the chain
21
+ @app.call(env)
22
+ end
23
+
24
+ def recover(env)
25
+ if env["vm"].created?
26
+ return if env["vagrant.error"].is_a?(Errors::VagrantError)
27
+
28
+ # Interrupted, destroy the VM
29
+ env["actions"].run(:destroy)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,21 @@
1
+ module Vagrant
2
+ class Action
3
+ module VM
4
+ class MatchMACAddress
5
+ def initialize(app, env)
6
+ @app = app
7
+ end
8
+
9
+ def call(env)
10
+ raise Errors::VMBaseMacNotSpecified if !env.env.config.vm.base_mac
11
+
12
+ env.ui.info I18n.t("vagrant.actions.vm.match_mac.matching")
13
+ env["vm"].vm.network_adapters.first.mac_address = env.env.config.vm.base_mac
14
+ env["vm"].vm.save
15
+
16
+ @app.call(env)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,139 @@
1
+ module Vagrant
2
+ class Action
3
+ module VM
4
+ # Networking middleware for Vagrant. This enables host only
5
+ # networking on VMs if configured as such.
6
+ class Network
7
+ def initialize(app, env)
8
+ @app = app
9
+ @env = env
10
+
11
+ if enable_network? && Util::Platform.windows? && Util::Platform.bit64?
12
+ raise Errors::NetworkNotImplemented
13
+ end
14
+
15
+ env["config"].vm.network_options.compact.each do |network_options|
16
+ raise Errors::NetworkCollision if !verify_no_bridge_collision(network_options)
17
+ end
18
+ end
19
+
20
+ def call(env)
21
+ @env = env
22
+ assign_network if enable_network?
23
+
24
+ @app.call(env)
25
+
26
+ if enable_network?
27
+ @env.ui.info I18n.t("vagrant.actions.vm.network.enabling")
28
+ @env.env.config.vm.network_options.compact.each do |network_options|
29
+ @env["vm"].system.prepare_host_only_network(network_options)
30
+ @env["vm"].system.enable_host_only_network(network_options)
31
+ end
32
+ end
33
+ end
34
+
35
+ # Verifies that there is no collision with a bridged network interface
36
+ # for the given network options.
37
+ def verify_no_bridge_collision(net_options)
38
+ interfaces = VirtualBox::Global.global.host.network_interfaces
39
+ interfaces.each do |ni|
40
+ next if ni.interface_type == :host_only
41
+
42
+ result = if net_options[:name]
43
+ true if net_options[:name] == ni.name
44
+ else
45
+ true if matching_network?(ni, net_options)
46
+ end
47
+
48
+ return false if result
49
+ end
50
+
51
+ true
52
+ end
53
+
54
+ def enable_network?
55
+ !@env.env.config.vm.network_options.compact.empty?
56
+ end
57
+
58
+ # Enables and assigns the host only network to the proper
59
+ # adapter on the VM, and saves the adapter.
60
+ def assign_network
61
+ @env.ui.info I18n.t("vagrant.actions.vm.network.preparing")
62
+
63
+ @env.env.config.vm.network_options.compact.each do |network_options|
64
+ adapter = @env["vm"].vm.network_adapters[network_options[:adapter]]
65
+ adapter.enabled = true
66
+ adapter.attachment_type = :host_only
67
+ adapter.host_interface = network_name(network_options)
68
+ adapter.mac_address = network_options[:mac].gsub(':', '') if network_options[:mac]
69
+ adapter.save
70
+ end
71
+ end
72
+
73
+ # Returns the name of the proper host only network, or creates
74
+ # it if it does not exist. Vagrant determines if the host only
75
+ # network exists by comparing the netmask and the IP.
76
+ def network_name(net_options)
77
+ # First try to find a matching network
78
+ interfaces = VirtualBox::Global.global.host.network_interfaces
79
+ interfaces.each do |ni|
80
+ # Ignore non-host only interfaces which may also match,
81
+ # since they're not valid options.
82
+ next if ni.interface_type != :host_only
83
+
84
+ if net_options[:name]
85
+ return ni.name if net_options[:name] == ni.name
86
+ else
87
+ return ni.name if matching_network?(ni, net_options)
88
+ end
89
+ end
90
+
91
+ raise Errors::NetworkNotFound, :name => net_options[:name] if net_options[:name]
92
+
93
+ # One doesn't exist, create it.
94
+ @env.ui.info I18n.t("vagrant.actions.vm.network.creating")
95
+
96
+ ni = interfaces.create
97
+ ni.enable_static(network_ip(net_options[:ip], net_options[:netmask]),
98
+ net_options[:netmask])
99
+ ni.name
100
+ end
101
+
102
+ # Tests if a network matches the given options by applying the
103
+ # netmask to the IP of the network and also to the IP of the
104
+ # virtual machine and see if they match.
105
+ def matching_network?(interface, net_options)
106
+ interface.network_mask == net_options[:netmask] &&
107
+ apply_netmask(interface.ip_address, interface.network_mask) ==
108
+ apply_netmask(net_options[:ip], net_options[:netmask])
109
+ end
110
+
111
+ # Applies a netmask to an IP and returns the corresponding
112
+ # parts.
113
+ def apply_netmask(ip, netmask)
114
+ ip = split_ip(ip)
115
+ netmask = split_ip(netmask)
116
+
117
+ ip.map do |part|
118
+ part & netmask.shift
119
+ end
120
+ end
121
+
122
+ # Splits an IP and converts each portion into an int.
123
+ def split_ip(ip)
124
+ ip.split(".").map do |i|
125
+ i.to_i
126
+ end
127
+ end
128
+
129
+ # Returns a "network IP" which is a "good choice" for the IP
130
+ # for the actual network based on the netmask.
131
+ def network_ip(ip, netmask)
132
+ parts = apply_netmask(ip, netmask)
133
+ parts[3] += 1;
134
+ parts.join(".")
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,159 @@
1
+ require File.expand_path("../nfs_helpers", __FILE__)
2
+
3
+ module Vagrant
4
+ class Action
5
+ module VM
6
+ # Enables NFS based shared folders. `nfsd` must already be installed
7
+ # on the host machine, and NFS client must already be installed on
8
+ # the guest machine.
9
+ #
10
+ # This is a two part process:
11
+ #
12
+ # 1. Adds an entry to `/etc/exports` on the host machine using
13
+ # the host class to export the proper folder to the proper
14
+ # machine.
15
+ # 2. After boot, runs `mount` on the guest to mount the shared
16
+ # folder.
17
+ #
18
+ class NFS
19
+ include NFSHelpers
20
+
21
+ def initialize(app,env)
22
+ @app = app
23
+ @env = env
24
+
25
+ verify_settings if nfs_enabled?
26
+ end
27
+
28
+ def call(env)
29
+ @env = env
30
+
31
+ extract_folders
32
+
33
+ if !folders.empty?
34
+ prepare_folders
35
+ clear_nfs_exports(env)
36
+ export_folders
37
+ end
38
+
39
+ @app.call(env)
40
+
41
+ mount_folders if !folders.empty?
42
+ end
43
+
44
+ def recover(env)
45
+ clear_nfs_exports(env) if env["vm"].created?
46
+ end
47
+
48
+ # Returns the folders which are to be synced via NFS.
49
+ def folders
50
+ @folders ||= {}
51
+ end
52
+
53
+ # Removes the NFS enabled shared folders from the configuration,
54
+ # so they will no longer be mounted by the actual shared folder
55
+ # task.
56
+ def extract_folders
57
+ # Load the NFS enabled shared folders
58
+ @folders = @env["config"].vm.shared_folders.inject({}) do |acc, data|
59
+ key, opts = data
60
+
61
+ if opts[:nfs]
62
+ # Duplicate the options, set the hostpath, and set disabled on the original
63
+ # options so the ShareFolders middleware doesn't try to mount it.
64
+ acc[key] = opts.dup
65
+ acc[key][:hostpath] = File.expand_path(opts[:hostpath], @env.env.root_path)
66
+ opts[:disabled] = true
67
+ end
68
+
69
+ acc
70
+ end
71
+ end
72
+
73
+ # Prepares the settings for the NFS folders, such as setting the
74
+ # options on the NFS folders.
75
+ def prepare_folders
76
+ @folders = @folders.inject({}) do |acc, data|
77
+ key, opts = data
78
+ opts[:nfs] = {} if !opts.is_a?(Hash)
79
+ opts[:map_uid] = prepare_permission(:uid, opts)
80
+ opts[:map_gid] = prepare_permission(:gid, opts)
81
+
82
+ acc[key] = opts
83
+ acc
84
+ end
85
+ end
86
+
87
+ # Prepares the UID/GID settings for a single folder.
88
+ def prepare_permission(perm, opts)
89
+ key = "map_#{perm}".to_sym
90
+ return nil if opts.has_key?(key) && opts[key].nil?
91
+
92
+ # The options on the hash get priority, then the default
93
+ # values
94
+ value = opts.has_key?(key) ? opts[key] : @env["config"].nfs.send(key)
95
+ return value if value != :auto
96
+
97
+ # Get UID/GID from folder if we've made it this far
98
+ # (value == :auto)
99
+ stat = File.stat(opts[:hostpath])
100
+ return stat.send(perm)
101
+ end
102
+
103
+ # Uses the host class to export the folders via NFS. This typically
104
+ # involves adding a line to `/etc/exports` for this VM, but it is
105
+ # up to the host class to define the specific behavior.
106
+ def export_folders
107
+ @env.ui.info I18n.t("vagrant.actions.vm.nfs.exporting")
108
+
109
+ @env["host"].nfs_export(guest_ip, folders)
110
+ end
111
+
112
+ # Uses the system class to mount the NFS folders.
113
+ def mount_folders
114
+ @env.ui.info I18n.t("vagrant.actions.vm.nfs.mounting")
115
+
116
+ # Only mount the folders which have a guest path specified
117
+ am_folders = folders.select { |name, folder| folder[:guestpath] }
118
+ @env["vm"].system.mount_nfs(host_ip, Hash[am_folders])
119
+ end
120
+
121
+ # Returns the IP address of the first host only network adapter
122
+ #
123
+ # @return [String]
124
+ def host_ip
125
+ interface = @env["vm"].vm.network_adapters.find do |adapter|
126
+ adapter.host_interface_object
127
+ end
128
+
129
+ return nil if !interface
130
+ interface.host_interface_object.ip_address
131
+ end
132
+
133
+ # Returns the IP address of the guest by looking at the first
134
+ # enabled host only network.
135
+ #
136
+ # @return [String]
137
+ def guest_ip
138
+ @env["config"].vm.network_options[1][:ip]
139
+ end
140
+
141
+ # Checks if there are any NFS enabled shared folders.
142
+ def nfs_enabled?
143
+ @env["config"].vm.shared_folders.each do |key, opts|
144
+ return true if opts[:nfs]
145
+ end
146
+
147
+ false
148
+ end
149
+
150
+ # Verifies that the host is set and supports NFS.
151
+ def verify_settings
152
+ raise Errors::NFSHostRequired if @env["host"].nil?
153
+ raise Errors::NFSNotSupported if !@env["host"].nfs?
154
+ raise Errors::NFSNoHostNetwork if @env["config"].vm.network_options.empty?
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end