rvagrant 0.8.7.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 (251) hide show
  1. data/.gitignore +25 -0
  2. data/.yardopts +1 -0
  3. data/CHANGELOG.md +386 -0
  4. data/Gemfile +21 -0
  5. data/LICENSE +21 -0
  6. data/README.md +61 -0
  7. data/Rakefile +11 -0
  8. data/bin/vagrant +28 -0
  9. data/config/default.rb +38 -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 +44 -0
  18. data/lib/vagrant/action.rb +138 -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 +108 -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 +113 -0
  32. data/lib/vagrant/action/general/validate.rb +19 -0
  33. data/lib/vagrant/action/vm.rb +34 -0
  34. data/lib/vagrant/action/vm/boot.rb +48 -0
  35. data/lib/vagrant/action/vm/check_accessible.rb +23 -0
  36. data/lib/vagrant/action/vm/check_box.rb +28 -0
  37. data/lib/vagrant/action/vm/check_guest_additions.rb +35 -0
  38. data/lib/vagrant/action/vm/clean_machine_folder.rb +43 -0
  39. data/lib/vagrant/action/vm/clear_forwarded_ports.rb +26 -0
  40. data/lib/vagrant/action/vm/clear_nfs_exports.rb +20 -0
  41. data/lib/vagrant/action/vm/clear_shared_folders.rb +27 -0
  42. data/lib/vagrant/action/vm/customize.rb +26 -0
  43. data/lib/vagrant/action/vm/destroy.rb +19 -0
  44. data/lib/vagrant/action/vm/destroy_unused_network_interfaces.rb +30 -0
  45. data/lib/vagrant/action/vm/discard_state.rb +22 -0
  46. data/lib/vagrant/action/vm/export.rb +52 -0
  47. data/lib/vagrant/action/vm/forward_ports.rb +133 -0
  48. data/lib/vagrant/action/vm/forward_ports_helpers.rb +28 -0
  49. data/lib/vagrant/action/vm/halt.rb +29 -0
  50. data/lib/vagrant/action/vm/host_name.rb +21 -0
  51. data/lib/vagrant/action/vm/import.rb +40 -0
  52. data/lib/vagrant/action/vm/match_mac_address.rb +26 -0
  53. data/lib/vagrant/action/vm/modify.rb +37 -0
  54. data/lib/vagrant/action/vm/network.rb +146 -0
  55. data/lib/vagrant/action/vm/nfs.rb +160 -0
  56. data/lib/vagrant/action/vm/nfs_helpers.rb +11 -0
  57. data/lib/vagrant/action/vm/package.rb +23 -0
  58. data/lib/vagrant/action/vm/package_vagrantfile.rb +33 -0
  59. data/lib/vagrant/action/vm/provision.rb +34 -0
  60. data/lib/vagrant/action/vm/provisioner_cleanup.rb +26 -0
  61. data/lib/vagrant/action/vm/resume.rb +20 -0
  62. data/lib/vagrant/action/vm/share_folders.rb +78 -0
  63. data/lib/vagrant/action/vm/suspend.rb +20 -0
  64. data/lib/vagrant/action/warden.rb +85 -0
  65. data/lib/vagrant/box.rb +90 -0
  66. data/lib/vagrant/box_collection.rb +53 -0
  67. data/lib/vagrant/cli.rb +55 -0
  68. data/lib/vagrant/command.rb +25 -0
  69. data/lib/vagrant/command/base.rb +106 -0
  70. data/lib/vagrant/command/box.rb +33 -0
  71. data/lib/vagrant/command/destroy.rb +17 -0
  72. data/lib/vagrant/command/group_base.rb +107 -0
  73. data/lib/vagrant/command/halt.rb +18 -0
  74. data/lib/vagrant/command/helpers.rb +33 -0
  75. data/lib/vagrant/command/init.rb +14 -0
  76. data/lib/vagrant/command/named_base.rb +14 -0
  77. data/lib/vagrant/command/package.rb +41 -0
  78. data/lib/vagrant/command/provision.rb +23 -0
  79. data/lib/vagrant/command/reload.rb +17 -0
  80. data/lib/vagrant/command/resume.rb +17 -0
  81. data/lib/vagrant/command/ssh.rb +49 -0
  82. data/lib/vagrant/command/ssh_config.rb +29 -0
  83. data/lib/vagrant/command/status.rb +31 -0
  84. data/lib/vagrant/command/suspend.rb +17 -0
  85. data/lib/vagrant/command/up.rb +19 -0
  86. data/lib/vagrant/command/upgrade_to_060.rb +45 -0
  87. data/lib/vagrant/command/version.rb +13 -0
  88. data/lib/vagrant/config.rb +123 -0
  89. data/lib/vagrant/config/base.rb +85 -0
  90. data/lib/vagrant/config/error_recorder.rb +19 -0
  91. data/lib/vagrant/config/nfs.rb +10 -0
  92. data/lib/vagrant/config/package.rb +9 -0
  93. data/lib/vagrant/config/ssh.rb +38 -0
  94. data/lib/vagrant/config/top.rb +61 -0
  95. data/lib/vagrant/config/vagrant.rb +17 -0
  96. data/lib/vagrant/config/vm.rb +148 -0
  97. data/lib/vagrant/config/vm/provisioner.rb +56 -0
  98. data/lib/vagrant/config/vm/sub_vm.rb +17 -0
  99. data/lib/vagrant/data_store.rb +70 -0
  100. data/lib/vagrant/downloaders.rb +7 -0
  101. data/lib/vagrant/downloaders/base.rb +23 -0
  102. data/lib/vagrant/downloaders/file.rb +22 -0
  103. data/lib/vagrant/downloaders/http.rb +70 -0
  104. data/lib/vagrant/environment.rb +516 -0
  105. data/lib/vagrant/errors.rb +352 -0
  106. data/lib/vagrant/hosts.rb +9 -0
  107. data/lib/vagrant/hosts/arch.rb +27 -0
  108. data/lib/vagrant/hosts/base.rb +76 -0
  109. data/lib/vagrant/hosts/bsd.rb +58 -0
  110. data/lib/vagrant/hosts/fedora.rb +11 -0
  111. data/lib/vagrant/hosts/linux.rb +69 -0
  112. data/lib/vagrant/plugin.rb +79 -0
  113. data/lib/vagrant/provisioners.rb +9 -0
  114. data/lib/vagrant/provisioners/base.rb +67 -0
  115. data/lib/vagrant/provisioners/chef.rb +155 -0
  116. data/lib/vagrant/provisioners/chef_client.rb +120 -0
  117. data/lib/vagrant/provisioners/chef_solo.rb +135 -0
  118. data/lib/vagrant/provisioners/puppet.rb +137 -0
  119. data/lib/vagrant/provisioners/puppet_server.rb +55 -0
  120. data/lib/vagrant/provisioners/shell.rb +96 -0
  121. data/lib/vagrant/ssh.rb +224 -0
  122. data/lib/vagrant/ssh/session.rb +136 -0
  123. data/lib/vagrant/systems.rb +13 -0
  124. data/lib/vagrant/systems/arch.rb +34 -0
  125. data/lib/vagrant/systems/base.rb +87 -0
  126. data/lib/vagrant/systems/debian.rb +36 -0
  127. data/lib/vagrant/systems/freebsd.rb +84 -0
  128. data/lib/vagrant/systems/gentoo.rb +27 -0
  129. data/lib/vagrant/systems/linux.rb +82 -0
  130. data/lib/vagrant/systems/linux/config.rb +21 -0
  131. data/lib/vagrant/systems/linux/error.rb +9 -0
  132. data/lib/vagrant/systems/redhat.rb +48 -0
  133. data/lib/vagrant/systems/solaris.rb +67 -0
  134. data/lib/vagrant/systems/suse.rb +9 -0
  135. data/lib/vagrant/systems/ubuntu.rb +17 -0
  136. data/lib/vagrant/test_helpers.rb +128 -0
  137. data/lib/vagrant/ui.rb +81 -0
  138. data/lib/vagrant/util.rb +13 -0
  139. data/lib/vagrant/util/busy.rb +59 -0
  140. data/lib/vagrant/util/counter.rb +24 -0
  141. data/lib/vagrant/util/hash_with_indifferent_access.rb +63 -0
  142. data/lib/vagrant/util/platform.rb +57 -0
  143. data/lib/vagrant/util/retryable.rb +25 -0
  144. data/lib/vagrant/util/safe_exec.rb +35 -0
  145. data/lib/vagrant/util/stacked_proc_runner.rb +35 -0
  146. data/lib/vagrant/util/template_renderer.rb +83 -0
  147. data/lib/vagrant/version.rb +6 -0
  148. data/lib/vagrant/vm.rb +181 -0
  149. data/templates/chef_server_client.erb +32 -0
  150. data/templates/chef_solo_solo.erb +23 -0
  151. data/templates/commands/init/Vagrantfile.erb +86 -0
  152. data/templates/config/validation_failed.erb +7 -0
  153. data/templates/locales/en.yml +556 -0
  154. data/templates/network_entry_arch.erb +9 -0
  155. data/templates/network_entry_debian.erb +8 -0
  156. data/templates/network_entry_gentoo.erb +5 -0
  157. data/templates/network_entry_redhat.erb +9 -0
  158. data/templates/nfs/exports.erb +5 -0
  159. data/templates/nfs/exports_linux.erb +5 -0
  160. data/templates/package_Vagrantfile.erb +11 -0
  161. data/templates/ssh_config.erb +15 -0
  162. data/test/unit/locales/en.yml +8 -0
  163. data/test/unit/test_helper.rb +28 -0
  164. data/test/unit/vagrant/action/box/destroy_test.rb +18 -0
  165. data/test/unit/vagrant/action/box/download_test.rb +125 -0
  166. data/test/unit/vagrant/action/box/package_test.rb +25 -0
  167. data/test/unit/vagrant/action/box/unpackage_test.rb +84 -0
  168. data/test/unit/vagrant/action/box/verify_test.rb +30 -0
  169. data/test/unit/vagrant/action/builder_test.rb +207 -0
  170. data/test/unit/vagrant/action/env/set_test.rb +24 -0
  171. data/test/unit/vagrant/action/environment_test.rb +27 -0
  172. data/test/unit/vagrant/action/general/package_test.rb +268 -0
  173. data/test/unit/vagrant/action/general/validate_test.rb +31 -0
  174. data/test/unit/vagrant/action/vm/boot_test.rb +66 -0
  175. data/test/unit/vagrant/action/vm/check_accessible_test.rb +61 -0
  176. data/test/unit/vagrant/action/vm/check_box_test.rb +56 -0
  177. data/test/unit/vagrant/action/vm/check_guest_additions_test.rb +9 -0
  178. data/test/unit/vagrant/action/vm/clean_machine_folder_test.rb +84 -0
  179. data/test/unit/vagrant/action/vm/clear_forwarded_ports_test.rb +52 -0
  180. data/test/unit/vagrant/action/vm/clear_nfs_exports_test.rb +22 -0
  181. data/test/unit/vagrant/action/vm/clear_shared_folders_test.rb +40 -0
  182. data/test/unit/vagrant/action/vm/customize_test.rb +37 -0
  183. data/test/unit/vagrant/action/vm/destroy_test.rb +25 -0
  184. data/test/unit/vagrant/action/vm/destroy_unused_network_interfaces_test.rb +49 -0
  185. data/test/unit/vagrant/action/vm/discard_state_test.rb +45 -0
  186. data/test/unit/vagrant/action/vm/export_test.rb +107 -0
  187. data/test/unit/vagrant/action/vm/forward_ports_helpers_test.rb +77 -0
  188. data/test/unit/vagrant/action/vm/forward_ports_test.rb +213 -0
  189. data/test/unit/vagrant/action/vm/halt_test.rb +79 -0
  190. data/test/unit/vagrant/action/vm/host_name_test.rb +36 -0
  191. data/test/unit/vagrant/action/vm/import_test.rb +66 -0
  192. data/test/unit/vagrant/action/vm/match_mac_address_test.rb +40 -0
  193. data/test/unit/vagrant/action/vm/modify_test.rb +38 -0
  194. data/test/unit/vagrant/action/vm/network_test.rb +286 -0
  195. data/test/unit/vagrant/action/vm/nfs_helpers_test.rb +26 -0
  196. data/test/unit/vagrant/action/vm/nfs_test.rb +260 -0
  197. data/test/unit/vagrant/action/vm/package_test.rb +25 -0
  198. data/test/unit/vagrant/action/vm/package_vagrantfile_test.rb +46 -0
  199. data/test/unit/vagrant/action/vm/provision_test.rb +65 -0
  200. data/test/unit/vagrant/action/vm/provisioner_cleanup_test.rb +56 -0
  201. data/test/unit/vagrant/action/vm/resume_test.rb +35 -0
  202. data/test/unit/vagrant/action/vm/share_folders_test.rb +144 -0
  203. data/test/unit/vagrant/action/vm/suspend_test.rb +35 -0
  204. data/test/unit/vagrant/action/warden_test.rb +125 -0
  205. data/test/unit/vagrant/action_test.rb +89 -0
  206. data/test/unit/vagrant/box_collection_test.rb +45 -0
  207. data/test/unit/vagrant/box_test.rb +74 -0
  208. data/test/unit/vagrant/cli_test.rb +35 -0
  209. data/test/unit/vagrant/command/base_test.rb +23 -0
  210. data/test/unit/vagrant/command/group_base_test.rb +15 -0
  211. data/test/unit/vagrant/command/helpers_test.rb +88 -0
  212. data/test/unit/vagrant/command/package_test.rb +27 -0
  213. data/test/unit/vagrant/config/base_test.rb +52 -0
  214. data/test/unit/vagrant/config/error_recorder_test.rb +18 -0
  215. data/test/unit/vagrant/config/ssh_test.rb +12 -0
  216. data/test/unit/vagrant/config/vagrant_test.rb +35 -0
  217. data/test/unit/vagrant/config/vm/provisioner_test.rb +92 -0
  218. data/test/unit/vagrant/config/vm_test.rb +56 -0
  219. data/test/unit/vagrant/config_test.rb +162 -0
  220. data/test/unit/vagrant/data_store_test.rb +77 -0
  221. data/test/unit/vagrant/downloaders/base_test.rb +28 -0
  222. data/test/unit/vagrant/downloaders/file_test.rb +48 -0
  223. data/test/unit/vagrant/downloaders/http_test.rb +82 -0
  224. data/test/unit/vagrant/environment_test.rb +598 -0
  225. data/test/unit/vagrant/errors_test.rb +42 -0
  226. data/test/unit/vagrant/hosts/base_test.rb +46 -0
  227. data/test/unit/vagrant/hosts/bsd_test.rb +53 -0
  228. data/test/unit/vagrant/hosts/linux_test.rb +54 -0
  229. data/test/unit/vagrant/plugin_test.rb +9 -0
  230. data/test/unit/vagrant/provisioners/base_test.rb +63 -0
  231. data/test/unit/vagrant/provisioners/chef_client_test.rb +190 -0
  232. data/test/unit/vagrant/provisioners/chef_solo_test.rb +114 -0
  233. data/test/unit/vagrant/provisioners/chef_test.rb +202 -0
  234. data/test/unit/vagrant/provisioners/puppet_server_test.rb +68 -0
  235. data/test/unit/vagrant/provisioners/puppet_test.rb +182 -0
  236. data/test/unit/vagrant/provisioners/shell_test.rb +79 -0
  237. data/test/unit/vagrant/ssh/session_test.rb +40 -0
  238. data/test/unit/vagrant/ssh_test.rb +307 -0
  239. data/test/unit/vagrant/systems/base_test.rb +18 -0
  240. data/test/unit/vagrant/systems/linux_test.rb +104 -0
  241. data/test/unit/vagrant/ui_test.rb +29 -0
  242. data/test/unit/vagrant/util/busy_test.rb +106 -0
  243. data/test/unit/vagrant/util/counter_test.rb +29 -0
  244. data/test/unit/vagrant/util/hash_with_indifferent_access_test.rb +39 -0
  245. data/test/unit/vagrant/util/platform_test.rb +18 -0
  246. data/test/unit/vagrant/util/retryable_test.rb +50 -0
  247. data/test/unit/vagrant/util/stacked_proc_runner_test.rb +43 -0
  248. data/test/unit/vagrant/util/template_renderer_test.rb +145 -0
  249. data/test/unit/vagrant/vm_test.rb +300 -0
  250. data/vagrant.gemspec +35 -0
  251. metadata +431 -0
@@ -0,0 +1,37 @@
1
+ module Vagrant
2
+ class Action
3
+ module VM
4
+ # This class allows other actions on the virtual machine object
5
+ # to be consolidated under a single write lock. This vastly speeds
6
+ # up modification of virtual machines. This should be used whereever
7
+ # possible when dealing with virtual machine modifications.
8
+ class Modify
9
+ include Util::StackedProcRunner
10
+
11
+ def initialize(app, env)
12
+ @app = app
13
+
14
+ # Initialize the proc_stack, which should already be empty
15
+ # but just making sure here.
16
+ proc_stack.clear
17
+
18
+ # Create the lambda in the environment which is to be called
19
+ # to add new procs to the modification sequence.
20
+ env["vm.modify"] = lambda do |*procs|
21
+ procs.each { |p| push_proc(&p) }
22
+ end
23
+ end
24
+
25
+ def call(env)
26
+ # Run the procs we have saved up, save the machine, and reload
27
+ # to verify we get the new settings
28
+ run_procs!(env["vm"].vm)
29
+ env["vm"].vm.save
30
+ env["vm"].reload!
31
+
32
+ @app.call(env)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,146 @@
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
+
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)
33
+ end
34
+
35
+ # Then enable the networks...
36
+ options.each do |network_options|
37
+ @env["vm"].system.enable_host_only_network(network_options)
38
+ end
39
+ end
40
+ end
41
+
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
48
+
49
+ result = if net_options[:name]
50
+ true if net_options[:name] == ni.name
51
+ else
52
+ true if matching_network?(ni, net_options)
53
+ end
54
+
55
+ return false if result
56
+ end
57
+
58
+ true
59
+ end
60
+
61
+ def enable_network?
62
+ !@env.env.config.vm.network_options.compact.empty?
63
+ end
64
+
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
77
+ end
78
+ end
79
+
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
93
+ else
94
+ return ni.name if matching_network?(ni, net_options)
95
+ end
96
+ end
97
+
98
+ raise Errors::NetworkNotFound, :name => net_options[:name] if net_options[:name]
99
+
100
+ # One doesn't exist, create it.
101
+ @env.ui.info I18n.t("vagrant.actions.vm.network.creating")
102
+
103
+ ni = interfaces.create
104
+ ni.enable_static(network_ip(net_options[:ip], net_options[:netmask]),
105
+ net_options[:netmask])
106
+ ni.name
107
+ end
108
+
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])
116
+ end
117
+
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)
123
+
124
+ ip.map do |part|
125
+ part & netmask.shift
126
+ end
127
+ end
128
+
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
133
+ end
134
+ end
135
+
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(".")
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,160 @@
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
+ am_folders = Hash[*am_folders.flatten] if am_folders.is_a?(Array)
119
+ @env["vm"].system.mount_nfs(host_ip, Hash[am_folders])
120
+ end
121
+
122
+ # Returns the IP address of the first host only network adapter
123
+ #
124
+ # @return [String]
125
+ def host_ip
126
+ interface = @env["vm"].vm.network_adapters.find do |adapter|
127
+ adapter.host_interface_object
128
+ end
129
+
130
+ return nil if !interface
131
+ interface.host_interface_object.ip_address
132
+ end
133
+
134
+ # Returns the IP address of the guest by looking at the first
135
+ # enabled host only network.
136
+ #
137
+ # @return [String]
138
+ def guest_ip
139
+ @env["config"].vm.network_options[1][:ip]
140
+ end
141
+
142
+ # Checks if there are any NFS enabled shared folders.
143
+ def nfs_enabled?
144
+ @env["config"].vm.shared_folders.each do |key, opts|
145
+ return true if opts[:nfs]
146
+ end
147
+
148
+ false
149
+ end
150
+
151
+ # Verifies that the host is set and supports NFS.
152
+ def verify_settings
153
+ raise Errors::NFSHostRequired if @env["host"].nil?
154
+ raise Errors::NFSNotSupported if !@env["host"].nfs?
155
+ raise Errors::NFSNoHostNetwork if @env["config"].vm.network_options.empty?
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end
@@ -0,0 +1,11 @@
1
+ module Vagrant
2
+ class Action
3
+ module VM
4
+ module NFSHelpers
5
+ def clear_nfs_exports(env)
6
+ env["host"].nfs_cleanup if env["host"]
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,23 @@
1
+ require 'vagrant/action/general/package'
2
+
3
+ module Vagrant
4
+ class Action
5
+ module VM
6
+ # A subclass of {General::Package} which simply makes sure that
7
+ # the package directory is set to the directory which the VM
8
+ # was exported to.
9
+ class Package < General::Package
10
+ # Doing this so that we can test that the parent is properly
11
+ # called in the unit tests.
12
+ alias_method :general_call, :call
13
+ def call(env)
14
+ # Just match up a couple environmental variables so that
15
+ # the superclass will do the right thing. Then, call the
16
+ # superclass
17
+ env["package.directory"] = env["export.temp_dir"]
18
+ general_call(env)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,33 @@
1
+ module Vagrant
2
+ class Action
3
+ module VM
4
+ # Puts a generated Vagrantfile into the package directory so that
5
+ # it can be included in the package.
6
+ class PackageVagrantfile
7
+ include Util
8
+
9
+ def initialize(app, env)
10
+ @app = app
11
+ @env = env
12
+ end
13
+
14
+ def call(env)
15
+ @env = env
16
+ create_vagrantfile
17
+ @app.call(env)
18
+ end
19
+
20
+ # This method creates the auto-generated Vagrantfile at the root of the
21
+ # box. This Vagrantfile contains the MAC address so that the user doesn't
22
+ # have to worry about it.
23
+ def create_vagrantfile
24
+ File.open(File.join(@env["export.temp_dir"], "Vagrantfile"), "w") do |f|
25
+ f.write(TemplateRenderer.render("package_Vagrantfile", {
26
+ :base_mac => @env["vm"].vm.network_adapters.first.mac_address
27
+ }))
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,34 @@
1
+ module Vagrant
2
+ class Action
3
+ module VM
4
+ class Provision
5
+ def initialize(app, env)
6
+ @app = app
7
+ @env = env
8
+ @env["provision.enabled"] = true if !@env.has_key?("provision.enabled")
9
+ end
10
+
11
+ def call(env)
12
+ # Instantiate and prepare the provisioners. Preparation must happen here
13
+ # so that shared folders and such can properly take effect.
14
+ provisioners = enabled_provisioners
15
+ provisioners.map { |p| p.prepare }
16
+
17
+ @app.call(env)
18
+
19
+ # Take prepared provisioners and run the provisioning
20
+ provisioners.each do |instance|
21
+ @env.ui.info I18n.t("vagrant.actions.vm.provision.beginning", :provisioner => instance.class)
22
+ instance.provision!
23
+ end
24
+ end
25
+
26
+ def enabled_provisioners
27
+ @env["config"].vm.provisioners.map do |provisioner|
28
+ provisioner.provisioner.new(@env, provisioner.config)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end