vagrant 0.5.4 → 0.6.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 (234) hide show
  1. data/.gitignore +1 -0
  2. data/.yardopts +1 -0
  3. data/CHANGELOG.md +56 -0
  4. data/Gemfile +14 -3
  5. data/Gemfile.lock +38 -11
  6. data/README.md +1 -1
  7. data/bin/vagrant +20 -5
  8. data/config/default.rb +6 -8
  9. data/lib/vagrant.rb +40 -13
  10. data/lib/vagrant/action.rb +56 -16
  11. data/lib/vagrant/action/box/destroy.rb +3 -1
  12. data/lib/vagrant/action/box/download.rb +8 -13
  13. data/lib/vagrant/action/box/unpackage.rb +8 -11
  14. data/lib/vagrant/action/box/verify.rb +3 -3
  15. data/lib/vagrant/action/builder.rb +3 -30
  16. data/lib/vagrant/action/builtin.rb +6 -1
  17. data/lib/vagrant/action/environment.rb +14 -62
  18. data/lib/vagrant/action/general/package.rb +29 -22
  19. data/lib/vagrant/action/vm/boot.rb +5 -12
  20. data/lib/vagrant/action/vm/check_box.rb +4 -4
  21. data/lib/vagrant/action/vm/check_guest_additions.rb +4 -6
  22. data/lib/vagrant/action/vm/clear_forwarded_ports.rb +2 -2
  23. data/lib/vagrant/action/vm/clear_nfs_exports.rb +1 -1
  24. data/lib/vagrant/action/vm/clear_shared_folders.rb +1 -1
  25. data/lib/vagrant/action/vm/customize.rb +1 -1
  26. data/lib/vagrant/action/vm/destroy.rb +1 -2
  27. data/lib/vagrant/action/vm/destroy_unused_network_interfaces.rb +1 -1
  28. data/lib/vagrant/action/vm/disable_networks.rb +11 -9
  29. data/lib/vagrant/action/vm/discard_state.rb +2 -2
  30. data/lib/vagrant/action/vm/export.rb +10 -11
  31. data/lib/vagrant/action/vm/forward_ports.rb +21 -9
  32. data/lib/vagrant/action/vm/halt.rb +3 -8
  33. data/lib/vagrant/action/vm/import.rb +16 -14
  34. data/lib/vagrant/action/vm/match_mac_address.rb +1 -1
  35. data/lib/vagrant/action/vm/network.rb +9 -16
  36. data/lib/vagrant/action/vm/nfs.rb +14 -18
  37. data/lib/vagrant/action/vm/provision.rb +5 -5
  38. data/lib/vagrant/action/vm/resume.rb +1 -1
  39. data/lib/vagrant/action/vm/share_folders.rb +6 -44
  40. data/lib/vagrant/action/vm/suspend.rb +1 -1
  41. data/lib/vagrant/action/warden.rb +74 -0
  42. data/lib/vagrant/box.rb +18 -82
  43. data/lib/vagrant/box_collection.rb +47 -0
  44. data/lib/vagrant/cli.rb +55 -0
  45. data/lib/vagrant/command/base.rb +106 -0
  46. data/lib/vagrant/command/box.rb +33 -0
  47. data/lib/vagrant/command/destroy.rb +17 -0
  48. data/lib/vagrant/command/group_base.rb +99 -0
  49. data/lib/vagrant/command/halt.rb +18 -0
  50. data/lib/vagrant/command/helpers.rb +33 -0
  51. data/lib/vagrant/command/init.rb +14 -0
  52. data/lib/vagrant/command/named_base.rb +14 -0
  53. data/lib/vagrant/command/package.rb +41 -0
  54. data/lib/vagrant/command/provision.rb +17 -0
  55. data/lib/vagrant/command/reload.rb +17 -0
  56. data/lib/vagrant/command/resume.rb +17 -0
  57. data/lib/vagrant/command/ssh.rb +41 -0
  58. data/lib/vagrant/command/ssh_config.rb +21 -0
  59. data/lib/vagrant/command/status.rb +23 -0
  60. data/lib/vagrant/command/suspend.rb +17 -0
  61. data/lib/vagrant/command/up.rb +20 -0
  62. data/lib/vagrant/command/upgrade_to_060.rb +45 -0
  63. data/lib/vagrant/command/version.rb +13 -0
  64. data/lib/vagrant/config.rb +107 -189
  65. data/lib/vagrant/config/base.rb +67 -0
  66. data/lib/vagrant/config/error_recorder.rb +19 -0
  67. data/lib/vagrant/config/nfs.rb +10 -0
  68. data/lib/vagrant/config/package.rb +9 -0
  69. data/lib/vagrant/config/ssh.rb +28 -0
  70. data/lib/vagrant/config/vagrant.rb +21 -0
  71. data/lib/vagrant/config/vm.rb +111 -0
  72. data/lib/vagrant/data_store.rb +68 -0
  73. data/lib/vagrant/downloaders/file.rb +3 -3
  74. data/lib/vagrant/downloaders/http.rb +5 -5
  75. data/lib/vagrant/environment.rb +246 -243
  76. data/lib/vagrant/errors.rb +306 -0
  77. data/lib/vagrant/hosts/base.rb +1 -1
  78. data/lib/vagrant/hosts/bsd.rb +3 -9
  79. data/lib/vagrant/hosts/linux.rb +3 -9
  80. data/lib/vagrant/plugin.rb +50 -0
  81. data/lib/vagrant/provisioners/base.rb +0 -6
  82. data/lib/vagrant/provisioners/chef.rb +63 -58
  83. data/lib/vagrant/provisioners/chef_server.rb +9 -11
  84. data/lib/vagrant/provisioners/chef_solo.rb +2 -2
  85. data/lib/vagrant/ssh.rb +34 -37
  86. data/lib/vagrant/systems/base.rb +0 -13
  87. data/lib/vagrant/systems/linux.rb +10 -33
  88. data/lib/vagrant/systems/solaris.rb +59 -0
  89. data/lib/vagrant/test_helpers.rb +109 -0
  90. data/lib/vagrant/ui.rb +65 -0
  91. data/lib/vagrant/util.rb +9 -19
  92. data/lib/vagrant/util/glob_loader.rb +19 -17
  93. data/lib/vagrant/util/hash_with_indifferent_access.rb +63 -0
  94. data/lib/vagrant/util/plain_logger.rb +2 -0
  95. data/lib/vagrant/util/platform.rb +2 -0
  96. data/lib/vagrant/util/resource_logger.rb +5 -70
  97. data/lib/vagrant/util/retryable.rb +25 -0
  98. data/lib/vagrant/util/template_renderer.rb +1 -1
  99. data/lib/vagrant/version.rb +1 -1
  100. data/lib/vagrant/vm.rb +27 -13
  101. data/templates/commands/init/Vagrantfile.erb +13 -0
  102. data/templates/config/validation_failed.erb +7 -0
  103. data/templates/locales/en.yml +402 -0
  104. data/templates/package_Vagrantfile.erb +1 -1
  105. data/test/locales/en.yml +8 -0
  106. data/test/test_helper.rb +19 -103
  107. data/test/vagrant/action/box/destroy_test.rb +7 -19
  108. data/test/vagrant/action/box/download_test.rb +9 -25
  109. data/test/vagrant/action/box/package_test.rb +2 -2
  110. data/test/vagrant/action/box/unpackage_test.rb +8 -34
  111. data/test/vagrant/action/box/verify_test.rb +10 -19
  112. data/test/vagrant/action/builder_test.rb +0 -15
  113. data/test/vagrant/action/env/set_test.rb +1 -1
  114. data/test/vagrant/action/environment_test.rb +8 -26
  115. data/test/vagrant/action/general/package_test.rb +53 -53
  116. data/test/vagrant/action/vm/boot_test.rb +5 -22
  117. data/test/vagrant/action/vm/check_box_test.rb +35 -25
  118. data/test/vagrant/action/vm/clean_machine_folder_test.rb +1 -1
  119. data/test/vagrant/action/vm/clear_forwarded_ports_test.rb +1 -1
  120. data/test/vagrant/action/vm/clear_nfs_exports_test.rb +1 -1
  121. data/test/vagrant/action/vm/clear_shared_folders_test.rb +1 -1
  122. data/test/vagrant/action/vm/customize_test.rb +2 -1
  123. data/test/vagrant/action/vm/destroy_test.rb +1 -2
  124. data/test/vagrant/action/vm/destroy_unused_network_interfaces_test.rb +1 -1
  125. data/test/vagrant/action/vm/disable_networks_test.rb +10 -1
  126. data/test/vagrant/action/vm/discard_state_test.rb +10 -1
  127. data/test/vagrant/action/vm/export_test.rb +9 -37
  128. data/test/vagrant/action/vm/forward_ports_helpers_test.rb +2 -2
  129. data/test/vagrant/action/vm/forward_ports_test.rb +19 -16
  130. data/test/vagrant/action/vm/halt_test.rb +11 -1
  131. data/test/vagrant/action/vm/import_test.rb +37 -21
  132. data/test/vagrant/action/vm/match_mac_address_test.rb +1 -1
  133. data/test/vagrant/action/vm/network_test.rb +8 -7
  134. data/test/vagrant/action/vm/nfs_helpers_test.rb +6 -3
  135. data/test/vagrant/action/vm/nfs_test.rb +20 -45
  136. data/test/vagrant/action/vm/package_test.rb +1 -1
  137. data/test/vagrant/action/vm/package_vagrantfile_test.rb +1 -1
  138. data/test/vagrant/action/vm/provision_test.rb +10 -17
  139. data/test/vagrant/action/vm/resume_test.rb +1 -1
  140. data/test/vagrant/action/vm/share_folders_test.rb +25 -106
  141. data/test/vagrant/action/vm/suspend_test.rb +1 -1
  142. data/test/vagrant/action/warden_test.rb +105 -0
  143. data/test/vagrant/action_test.rb +5 -27
  144. data/test/vagrant/box_collection_test.rb +44 -0
  145. data/test/vagrant/box_test.rb +5 -105
  146. data/test/vagrant/cli_test.rb +35 -0
  147. data/test/vagrant/command/base_test.rb +23 -0
  148. data/test/vagrant/command/group_base_test.rb +15 -0
  149. data/test/vagrant/command/helpers_test.rb +88 -0
  150. data/test/vagrant/config/base_test.rb +52 -0
  151. data/test/vagrant/config/error_recorder_test.rb +18 -0
  152. data/test/vagrant/config/ssh_test.rb +12 -0
  153. data/test/vagrant/config/vagrant_test.rb +11 -0
  154. data/test/vagrant/config/vm_test.rb +70 -0
  155. data/test/vagrant/config_test.rb +113 -206
  156. data/test/vagrant/data_store_test.rb +68 -0
  157. data/test/vagrant/downloaders/base_test.rb +1 -1
  158. data/test/vagrant/downloaders/file_test.rb +4 -3
  159. data/test/vagrant/downloaders/http_test.rb +14 -4
  160. data/test/vagrant/environment_test.rb +290 -590
  161. data/test/vagrant/errors_test.rb +42 -0
  162. data/test/vagrant/hosts/base_test.rb +1 -1
  163. data/test/vagrant/hosts/bsd_test.rb +3 -6
  164. data/test/vagrant/hosts/linux_test.rb +3 -5
  165. data/test/vagrant/plugin_test.rb +9 -0
  166. data/test/vagrant/provisioners/base_test.rb +1 -1
  167. data/test/vagrant/provisioners/chef_server_test.rb +31 -35
  168. data/test/vagrant/provisioners/chef_solo_test.rb +1 -1
  169. data/test/vagrant/provisioners/chef_test.rb +7 -7
  170. data/test/vagrant/ssh_session_test.rb +3 -10
  171. data/test/vagrant/ssh_test.rb +25 -33
  172. data/test/vagrant/systems/linux_test.rb +6 -71
  173. data/test/vagrant/ui_test.rb +29 -0
  174. data/test/vagrant/util/hash_with_indifferent_access_test.rb +39 -0
  175. data/test/vagrant/util/resource_logger_test.rb +14 -81
  176. data/test/vagrant/util/retryable_test.rb +38 -0
  177. data/test/vagrant/util/template_renderer_test.rb +4 -4
  178. data/test/vagrant/vm_test.rb +47 -26
  179. data/vagrant.gemspec +14 -12
  180. metadata +142 -108
  181. data/bin/.gitignore +0 -0
  182. data/lib/vagrant/action/action_exception.rb +0 -16
  183. data/lib/vagrant/action/env/error_halt.rb +0 -16
  184. data/lib/vagrant/action/exception_catcher.rb +0 -14
  185. data/lib/vagrant/action/vm/persist.rb +0 -22
  186. data/lib/vagrant/active_list.rb +0 -83
  187. data/lib/vagrant/command.rb +0 -27
  188. data/lib/vagrant/commands/base.rb +0 -181
  189. data/lib/vagrant/commands/box.rb +0 -16
  190. data/lib/vagrant/commands/box/add.rb +0 -30
  191. data/lib/vagrant/commands/box/list.rb +0 -30
  192. data/lib/vagrant/commands/box/remove.rb +0 -30
  193. data/lib/vagrant/commands/box/repackage.rb +0 -35
  194. data/lib/vagrant/commands/destroy.rb +0 -37
  195. data/lib/vagrant/commands/halt.rb +0 -43
  196. data/lib/vagrant/commands/init.rb +0 -36
  197. data/lib/vagrant/commands/package.rb +0 -81
  198. data/lib/vagrant/commands/provision.rb +0 -31
  199. data/lib/vagrant/commands/reload.rb +0 -36
  200. data/lib/vagrant/commands/resume.rb +0 -35
  201. data/lib/vagrant/commands/ssh.rb +0 -78
  202. data/lib/vagrant/commands/ssh_config.rb +0 -45
  203. data/lib/vagrant/commands/status.rb +0 -125
  204. data/lib/vagrant/commands/suspend.rb +0 -36
  205. data/lib/vagrant/commands/up.rb +0 -44
  206. data/lib/vagrant/exceptions/uncallable_action.rb +0 -17
  207. data/lib/vagrant/util/translator.rb +0 -35
  208. data/templates/strings.yml +0 -341
  209. data/templates/unison/crontab_entry.erb +0 -1
  210. data/templates/unison/script.erb +0 -71
  211. data/test/vagrant/action/env/error_halt_test.rb +0 -21
  212. data/test/vagrant/action/exception_catcher_test.rb +0 -30
  213. data/test/vagrant/action/vm/persist_test.rb +0 -50
  214. data/test/vagrant/active_list_test.rb +0 -173
  215. data/test/vagrant/command_test.rb +0 -53
  216. data/test/vagrant/commands/base_test.rb +0 -139
  217. data/test/vagrant/commands/box/add_test.rb +0 -34
  218. data/test/vagrant/commands/box/list_test.rb +0 -32
  219. data/test/vagrant/commands/box/remove_test.rb +0 -41
  220. data/test/vagrant/commands/box/repackage_test.rb +0 -52
  221. data/test/vagrant/commands/destroy_test.rb +0 -44
  222. data/test/vagrant/commands/halt_test.rb +0 -50
  223. data/test/vagrant/commands/init_test.rb +0 -71
  224. data/test/vagrant/commands/package_test.rb +0 -97
  225. data/test/vagrant/commands/provision_test.rb +0 -60
  226. data/test/vagrant/commands/reload_test.rb +0 -47
  227. data/test/vagrant/commands/resume_test.rb +0 -44
  228. data/test/vagrant/commands/ssh_config_test.rb +0 -77
  229. data/test/vagrant/commands/ssh_test.rb +0 -129
  230. data/test/vagrant/commands/status_test.rb +0 -40
  231. data/test/vagrant/commands/suspend_test.rb +0 -44
  232. data/test/vagrant/commands/up_test.rb +0 -49
  233. data/test/vagrant/util/translator_test.rb +0 -61
  234. data/test/vagrant/util_test.rb +0 -27
@@ -0,0 +1,41 @@
1
+ module Vagrant
2
+ module Command
3
+ class SSHCommand < NamedBase
4
+ class_option :execute, :type => :string, :default => false, :aliases => "-e"
5
+ register "ssh", "SSH into the currently running Vagrant environment."
6
+
7
+ def execute
8
+ if options[:execute]
9
+ ssh_execute
10
+ else
11
+ ssh_connect
12
+ end
13
+ end
14
+
15
+ protected
16
+
17
+ def ssh_execute
18
+ ssh_vm.ssh.execute do |ssh|
19
+ ssh_vm.env.ui.info I18n.t("vagrant.commands.ssh.execute", :command => options[:execute])
20
+ ssh.exec!(options[:execute]) do |channel, type, data|
21
+ ssh_vm.env.ui.info "#{data}"
22
+ end
23
+ end
24
+ end
25
+
26
+ def ssh_connect
27
+ raise VMNotCreatedError.new if !ssh_vm.created?
28
+ ssh_vm.ssh.connect
29
+ end
30
+
31
+ def ssh_vm
32
+ @ssh_vm ||= begin
33
+ vm = self.name.nil? && env.multivm? ? env.primary_vm : nil
34
+ raise MultiVMTargetRequired.new(:command => "ssh") if !vm && target_vms.length > 1
35
+ vm = target_vms.first if !vm
36
+ vm
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,21 @@
1
+ module Vagrant
2
+ module Command
3
+ class SSHConfigCommand < NamedBase
4
+ class_option :host, :type => :string, :default => nil, :aliases => "-h"
5
+ register "ssh_config", "outputs .ssh/config valid syntax for connecting to this environment via ssh"
6
+
7
+ def execute
8
+ raise MultiVMTargetRequired.new(:command => "ssh_config") if target_vms.length > 1
9
+ vm = target_vms.first
10
+ raise VMNotCreatedError.new if !vm.created?
11
+
12
+ env.ui.info(Util::TemplateRenderer.render("ssh_config", {
13
+ :host_key => options[:host] || "vagrant",
14
+ :ssh_user => vm.env.config.ssh.username,
15
+ :ssh_port => vm.ssh.port,
16
+ :private_key_path => vm.env.config.ssh.private_key_path
17
+ }), :prefix => false)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,23 @@
1
+ module Vagrant
2
+ module Command
3
+ class StatusCommand < Base
4
+ argument :name, :type => :string, :optional => true
5
+ register "status", "Shows the status of the current Vagrant environment."
6
+
7
+ def route
8
+ state = nil
9
+ results = env.vms.collect do |name, vm|
10
+ state ||= vm.created? ? vm.vm.state.to_s : "not_created"
11
+ "#{name.to_s.ljust(25)}#{state.gsub("_", " ")}"
12
+ end
13
+
14
+ state = env.vms.length == 1 ? state : "listing"
15
+
16
+ env.ui.info(I18n.t("vagrant.commands.status.output",
17
+ :states => results.join("\n"),
18
+ :message => I18n.t("vagrant.commands.status.#{state}")),
19
+ :prefix => false)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,17 @@
1
+ module Vagrant
2
+ module Command
3
+ class SuspendCommand < NamedBase
4
+ register "suspend", "Suspend a running Vagrant environment."
5
+
6
+ def execute
7
+ target_vms.each do |vm|
8
+ if vm.created?
9
+ vm.suspend
10
+ else
11
+ vm.env.ui.info I18n.t("vagrant.commands.common.vm_not_created")
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ module Vagrant
2
+ module Command
3
+ class UpCommand < NamedBase
4
+ class_option :provision, :type => :boolean, :default => true
5
+ register "up", "Creates the Vagrant environment"
6
+
7
+ def execute
8
+ # TODO: Make the options[:provision] actually mean something
9
+ target_vms.each do |vm|
10
+ if vm.created?
11
+ vm.env.ui.info I18n.t("vagrant.commands.up.vm_created")
12
+ vm.start
13
+ else
14
+ vm.up
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,45 @@
1
+ require 'fileutils'
2
+
3
+ module Vagrant
4
+ module Command
5
+ class UpgradeTo060Command < Base
6
+ register "upgrade_to_060", "Upgrade pre-0.6.0 environment to 0.6.0", :hide => true
7
+
8
+ def execute
9
+ @env.ui.warn I18n.t("vagrant.commands.upgrade_to_060.info"), :prefix => false
10
+ @env.ui.warn "", :prefix => false
11
+ if !@env.ui.yes? I18n.t("vagrant.commands.upgrade_to_060.ask"), :prefix => false, :color => :yellow
12
+ @env.ui.info I18n.t("vagrant.commands.upgrade_to_060.quit"), :prefix => false
13
+ return
14
+ end
15
+
16
+ local_data = @env.local_data
17
+ if !local_data.empty?
18
+ if local_data[:active]
19
+ @env.ui.confirm I18n.t("vagrant.commands.upgrade_to_060.already_done"), :prefix => false
20
+ return
21
+ end
22
+
23
+ # Backup the previous file
24
+ @env.ui.info I18n.t("vagrant.commands.upgrade_to_060.backing_up"), :prefix => false
25
+ FileUtils.cp(local_data.file_path, "#{local_data.file_path}.bak-#{Time.now.to_i}")
26
+
27
+ # Gather the previously set virtual machines into a single
28
+ # active hash
29
+ active = local_data.inject({}) do |acc, data|
30
+ key, uuid = data
31
+ acc[key.to_sym] = uuid
32
+ acc
33
+ end
34
+
35
+ # Set the active hash to the active list and save it
36
+ local_data.clear
37
+ local_data[:active] = active
38
+ local_data.commit
39
+ end
40
+
41
+ @env.ui.confirm I18n.t("vagrant.commands.upgrade_to_060.complete"), :prefix => false
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,13 @@
1
+ module Vagrant
2
+ module Command
3
+ class VersionCommand < Base
4
+ register "version", "Prints the Vagrant version information", :alias => %w(-v --version)
5
+
6
+ def version
7
+ env.ui.info(I18n.t("vagrant.commands.version.output",
8
+ :version => Vagrant::VERSION),
9
+ :prefix => false)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,14 +1,42 @@
1
- module Vagrant
2
- def self.config
3
- Config.config
4
- end
1
+ require 'vagrant/config/base'
2
+ require 'vagrant/config/error_recorder'
5
3
 
4
+ module Vagrant
5
+ # The config class is responsible for loading Vagrant configurations, which
6
+ # are usually found in Vagrantfiles but may also be procs. The loading is done
7
+ # by specifying a queue of files or procs that are for configuration, and then
8
+ # executing them. The config loader will run each item in the queue, so that
9
+ # configuration from later items overwrite that from earlier items. This is how
10
+ # Vagrant "scoping" of Vagranfiles is implemented.
11
+ #
12
+ # If you're looking to create your own configuration classes, see {Base}.
13
+ #
14
+ # # Loading Configuration Files
15
+ #
16
+ # If you are in fact looking to load configuration files, then this is the
17
+ # class you are looking for. Loading configuration is quite easy. The following
18
+ # example assumes `env` is already a loaded instance of {Environment}:
19
+ #
20
+ # config = Vagrant::Config.new(env)
21
+ # config.queue << "/path/to/some/Vagrantfile"
22
+ # result = config.load!
23
+ #
24
+ # p "Your box is: #{result.vm.box}"
25
+ #
6
26
  class Config
7
27
  extend Util::StackedProcRunner
8
28
 
9
29
  @@config = nil
10
30
 
31
+ attr_reader :queue
32
+
11
33
  class << self
34
+ # Resets the current loaded config object to the specified environment.
35
+ # This clears the proc stack and initializes a new {Top} for loading.
36
+ # This method shouldn't be called directly, instead use an instance of this
37
+ # class for config loading.
38
+ #
39
+ # @param [Environment] env
12
40
  def reset!(env=nil)
13
41
  @@config = nil
14
42
  proc_stack.clear
@@ -17,216 +45,94 @@ module Vagrant
17
45
  config(env)
18
46
  end
19
47
 
20
- def configures(key, klass)
21
- config.class.configures(key, klass)
22
- end
23
-
48
+ # Returns the current {Top} configuration object. While this is still
49
+ # here for implementation purposes, it shouldn't be called directly. Instead,
50
+ # use an instance of this class.
24
51
  def config(env=nil)
25
52
  @@config ||= Config::Top.new(env)
26
53
  end
27
54
 
55
+ # Adds the given proc/block to the stack of config procs which are all
56
+ # run later on a single config object. This is the main way to configure
57
+ # Vagrant, and is how all Vagrantfiles are formatted:
58
+ #
59
+ # Vagrant::Config.run do |config|
60
+ # # ...
61
+ # end
62
+ #
28
63
  def run(&block)
29
64
  push_proc(&block)
30
65
  end
31
66
 
67
+ # Executes all the config procs onto the currently loaded {Top} object,
68
+ # and returns the final configured object. This also validates the
69
+ # configuration by calling {Top#validate!} on every configuration
70
+ # class.
32
71
  def execute!(config_object=nil)
33
72
  config_object ||= config
34
73
 
35
74
  run_procs!(config_object)
36
- config_object.loaded!
75
+ config_object.validate!
37
76
  config_object
38
77
  end
39
78
  end
40
- end
41
-
42
- class Config
43
- class Base
44
- attr_accessor :env
45
79
 
46
- def [](key)
47
- send(key)
48
- end
49
-
50
- def to_json(*a)
51
- instance_variables_hash.to_json(*a)
52
- end
53
-
54
- def instance_variables_hash
55
- instance_variables.inject({}) do |acc, iv|
56
- acc[iv.to_s[1..-1].to_sym] = instance_variable_get(iv) unless iv.to_sym == :@env
57
- acc
58
- end
59
- end
80
+ # Initialize a {Config} object for the given {Environment}.
81
+ #
82
+ # @param [Environment] env Environment which config object will be part
83
+ # of.
84
+ def initialize(env)
85
+ @env = env
86
+ @queue = []
60
87
  end
61
88
 
62
- class SSHConfig < Base
63
- attr_accessor :username
64
- attr_accessor :host
65
- attr_accessor :port
66
- attr_accessor :forwarded_port_key
67
- attr_accessor :max_tries
68
- attr_accessor :timeout
69
- attr_accessor :private_key_path
70
- attr_accessor :forward_agent
71
-
72
- # The attribute(s) below do nothing. They are just kept here to
73
- # prevent syntax errors for backwards compat.
74
- attr_accessor :password
75
-
76
- def private_key_path
77
- File.expand_path(@private_key_path, env.root_path)
78
- end
79
- end
80
-
81
- class UnisonConfig < Base
82
- attr_accessor :folder_suffix
83
- attr_accessor :script
84
- attr_accessor :options
85
- attr_accessor :crontab_entry_file
86
- attr_accessor :log_file
87
- end
88
-
89
- class NFSConfig < Base
90
- attr_accessor :map_uid
91
- attr_accessor :map_gid
92
- end
93
-
94
- class VMConfig < Base
95
- include Util::StackedProcRunner
96
-
97
- attr_accessor :auto_port_range
98
- attr_accessor :box
99
- attr_accessor :box_url
100
- attr_accessor :box_ovf
101
- attr_accessor :base_mac
102
- attr_accessor :boot_mode
103
- attr_reader :forwarded_ports
104
- attr_reader :shared_folders
105
- attr_reader :network_options
106
- attr_accessor :hd_location
107
- attr_accessor :disk_image_format
108
- attr_accessor :provisioner
109
- attr_accessor :shared_folder_uid
110
- attr_accessor :shared_folder_gid
111
- attr_accessor :system
112
-
113
- # Represents a SubVM. This class is only used here in the VMs
114
- # hash.
115
- class SubVM
116
- include Util::StackedProcRunner
117
-
118
- def options
119
- @options ||= {}
89
+ # Loads the queue of files/procs, executes them in the proper
90
+ # sequence, and returns the resulting configuration object.
91
+ def load!
92
+ self.class.reset!(@env)
93
+
94
+ queue.flatten.each do |item|
95
+ if item.is_a?(String) && File.exist?(item)
96
+ begin
97
+ load item
98
+ rescue SyntaxError => e
99
+ # Report syntax errors in a nice way for Vagrantfiles
100
+ raise Errors::VagrantfileSyntaxError.new(:file => e.message)
101
+ end
102
+ elsif item.is_a?(Proc)
103
+ self.class.run(&item)
120
104
  end
121
105
  end
122
106
 
123
- def initialize
124
- @forwarded_ports = {}
125
- @shared_folders = {}
126
- @provisioner = nil
127
- @network_options = []
128
- end
129
-
130
- def forward_port(name, guestport, hostport, options=nil)
131
- options = {
132
- :guestport => guestport,
133
- :hostport => hostport,
134
- :protocol => "TCP",
135
- :adapter => 0,
136
- :auto => false
137
- }.merge(options || {})
138
-
139
- forwarded_ports[name] = options
140
- end
141
-
142
- def share_folder(name, guestpath, hostpath, opts=nil)
143
- @shared_folders[name] = {
144
- :guestpath => guestpath,
145
- :hostpath => hostpath
146
- }.merge(opts || {})
147
- end
148
-
149
- def network(ip, options=nil)
150
- options = {
151
- :ip => ip,
152
- :netmask => "255.255.255.0",
153
- :adapter => 1,
154
- :name => nil
155
- }.merge(options || {})
156
-
157
- @network_options[options[:adapter]] = options
158
- end
159
-
160
- def hd_location=(val)
161
- raise Exception.new("disk_storage must be set to a directory") unless File.directory?(val)
162
- @hd_location=val
163
- end
164
-
165
- def shared_folder_uid
166
- @shared_folder_uid || env.config.ssh.username
167
- end
168
-
169
- def shared_folder_gid
170
- @shared_folder_gid || env.config.ssh.username
171
- end
172
-
173
- def customize(&block)
174
- push_proc(&block)
175
- end
176
-
177
- def has_multi_vms?
178
- !defined_vms.empty?
179
- end
180
-
181
- def defined_vms
182
- @defined_vms ||= {}
183
- end
184
-
185
- def define(name, options=nil, &block)
186
- options ||= {}
187
- defined_vms[name.to_sym] ||= SubVM.new
188
- defined_vms[name.to_sym].options.merge!(options)
189
- defined_vms[name.to_sym].push_proc(&block)
190
- end
191
- end
192
-
193
- class PackageConfig < Base
194
- attr_accessor :name
195
- end
196
-
197
- class VagrantConfig < Base
198
- attr_accessor :dotfile_name
199
- attr_accessor :log_output
200
- attr_accessor :home
201
- attr_accessor :host
202
-
203
- def home
204
- @home ? File.expand_path(@home) : nil
205
- end
107
+ return self.class.execute!
206
108
  end
109
+ end
207
110
 
111
+ class Config
112
+ # This class is the "top" configure class, which handles registering
113
+ # other configuration classes as well as validation of all configured
114
+ # classes. This is the object which is returned by {Environment#config}
115
+ # and has accessors to all other configuration classes.
116
+ #
117
+ # If you're looking to create your own configuration class, see {Base}.
208
118
  class Top < Base
209
119
  @@configures = []
210
120
 
211
121
  class << self
122
+ # The list of registered configuration classes as well as the key
123
+ # they're registered under.
212
124
  def configures_list
213
125
  @@configures ||= []
214
126
  end
215
127
 
128
+ # Registers a configuration class with the given key. This method shouldn't
129
+ # be called. Instead, inherit from {Base} and call {Base.configures}.
216
130
  def configures(key, klass)
217
131
  configures_list << [key, klass]
218
132
  attr_reader key.to_sym
219
133
  end
220
134
  end
221
135
 
222
- # Setup default configures
223
- configures :package, PackageConfig
224
- configures :nfs, NFSConfig
225
- configures :ssh, SSHConfig
226
- configures :unison, UnisonConfig
227
- configures :vm, VMConfig
228
- configures :vagrant, VagrantConfig
229
-
230
136
  def initialize(env=nil)
231
137
  self.class.configures_list.each do |key, klass|
232
138
  config = klass.new
@@ -234,23 +140,35 @@ module Vagrant
234
140
  instance_variable_set("@#{key}".to_sym, config)
235
141
  end
236
142
 
237
- @loaded = false
238
143
  @env = env
239
144
  end
240
145
 
241
- def loaded?
242
- @loaded
243
- end
244
-
245
- def loaded!
246
- @loaded = true
247
- end
146
+ # Validates the configuration classes of this instance and raises an
147
+ # exception if they are invalid. If you are implementing a custom configuration
148
+ # class, the method you want to implement is {Base#validate}. This is
149
+ # the method that checks all the validation, not one which defines
150
+ # validation rules.
151
+ def validate!
152
+ # Validate each of the configured classes and store the results into
153
+ # a hash.
154
+ errors = self.class.configures_list.inject({}) do |container, data|
155
+ key, _ = data
156
+ recorder = ErrorRecorder.new
157
+ send(key.to_sym).validate(recorder)
158
+ container[key.to_sym] = recorder if !recorder.errors.empty?
159
+ container
160
+ end
248
161
 
249
- # Deep clones the entire configuration tree using the marshalling
250
- # trick. All subclasses must be able to marshal properly.
251
- def deep_clone
252
- Marshal.load(Marshal.dump(self))
162
+ return if errors.empty?
163
+ raise Errors::ConfigValidationFailed.new(:messages => Util::TemplateRenderer.render("config/validation_failed", :errors => errors))
253
164
  end
254
165
  end
255
166
  end
256
167
  end
168
+
169
+ # The built-in configuration classes
170
+ require 'vagrant/config/vagrant'
171
+ require 'vagrant/config/ssh'
172
+ require 'vagrant/config/nfs'
173
+ require 'vagrant/config/vm'
174
+ require 'vagrant/config/package'