vagrant 0.7.0.beta → 0.7.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. data/.gitignore +2 -0
  2. data/CHANGELOG.md +26 -0
  3. data/Gemfile +0 -8
  4. data/config/default.rb +1 -2
  5. data/contrib/README.md +12 -0
  6. data/contrib/emacs/vagrant.el +8 -0
  7. data/contrib/vim/vagrantfile.vim +9 -0
  8. data/lib/vagrant.rb +14 -18
  9. data/lib/vagrant/action.rb +12 -0
  10. data/lib/vagrant/action/box.rb +11 -0
  11. data/lib/vagrant/action/box/download.rb +0 -1
  12. data/lib/vagrant/action/env.rb +7 -0
  13. data/lib/vagrant/action/general.rb +8 -0
  14. data/lib/vagrant/action/vm.rb +30 -0
  15. data/lib/vagrant/action/vm/boot.rb +3 -2
  16. data/lib/vagrant/action/vm/check_box.rb +1 -0
  17. data/lib/vagrant/action/vm/network.rb +1 -1
  18. data/lib/vagrant/action/vm/nfs.rb +3 -1
  19. data/lib/vagrant/action/vm/provision.rb +14 -25
  20. data/lib/vagrant/action/vm/share_folders.rb +11 -4
  21. data/lib/vagrant/command.rb +25 -0
  22. data/lib/vagrant/config.rb +78 -128
  23. data/lib/vagrant/config/base.rb +17 -3
  24. data/lib/vagrant/config/ssh.rb +1 -0
  25. data/lib/vagrant/config/top.rb +61 -0
  26. data/lib/vagrant/config/vagrant.rb +1 -6
  27. data/lib/vagrant/config/vm.rb +34 -20
  28. data/lib/vagrant/config/vm/provisioner.rb +56 -0
  29. data/lib/vagrant/config/vm/sub_vm.rb +17 -0
  30. data/lib/vagrant/downloaders.rb +7 -0
  31. data/lib/vagrant/downloaders/file.rb +1 -0
  32. data/lib/vagrant/downloaders/http.rb +9 -0
  33. data/lib/vagrant/environment.rb +25 -13
  34. data/lib/vagrant/errors.rb +0 -15
  35. data/lib/vagrant/hosts.rb +7 -0
  36. data/lib/vagrant/provisioners.rb +8 -0
  37. data/lib/vagrant/provisioners/base.rb +19 -1
  38. data/lib/vagrant/provisioners/chef.rb +31 -52
  39. data/lib/vagrant/provisioners/chef_server.rb +34 -10
  40. data/lib/vagrant/provisioners/chef_solo.rb +31 -9
  41. data/lib/vagrant/provisioners/puppet.rb +70 -60
  42. data/lib/vagrant/provisioners/puppet_server.rb +57 -0
  43. data/lib/vagrant/ssh.rb +3 -72
  44. data/lib/vagrant/ssh/session.rb +81 -0
  45. data/lib/vagrant/systems.rb +9 -0
  46. data/lib/vagrant/systems/base.rb +16 -1
  47. data/lib/vagrant/systems/debian.rb +26 -0
  48. data/lib/vagrant/systems/gentoo.rb +27 -0
  49. data/lib/vagrant/systems/linux.rb +14 -56
  50. data/lib/vagrant/systems/linux/config.rb +21 -0
  51. data/lib/vagrant/systems/linux/error.rb +9 -0
  52. data/lib/vagrant/systems/redhat.rb +31 -0
  53. data/lib/vagrant/test_helpers.rb +1 -1
  54. data/lib/vagrant/version.rb +1 -1
  55. data/lib/vagrant/vm.rb +25 -5
  56. data/templates/chef_solo_solo.erb +11 -3
  57. data/templates/locales/en.yml +65 -25
  58. data/templates/{network_entry.erb → network_entry_debian.erb} +0 -0
  59. data/templates/network_entry_gentoo.erb +7 -0
  60. data/templates/network_entry_redhat.erb +8 -0
  61. data/test/vagrant/action/vm/check_box_test.rb +1 -0
  62. data/test/vagrant/action/vm/nfs_test.rb +7 -1
  63. data/test/vagrant/action/vm/provision_test.rb +24 -79
  64. data/test/vagrant/action/vm/share_folders_test.rb +6 -1
  65. data/test/vagrant/command/helpers_test.rb +2 -2
  66. data/test/vagrant/config/base_test.rb +0 -6
  67. data/test/vagrant/config/vagrant_test.rb +0 -8
  68. data/test/vagrant/config/vm/provisioner_test.rb +92 -0
  69. data/test/vagrant/config/vm_test.rb +8 -0
  70. data/test/vagrant/config_test.rb +49 -89
  71. data/test/vagrant/downloaders/file_test.rb +18 -4
  72. data/test/vagrant/environment_test.rb +36 -12
  73. data/test/vagrant/provisioners/base_test.rb +28 -1
  74. data/test/vagrant/provisioners/chef_server_test.rb +50 -41
  75. data/test/vagrant/provisioners/chef_solo_test.rb +39 -16
  76. data/test/vagrant/provisioners/chef_test.rb +11 -81
  77. data/test/vagrant/provisioners/puppet_server_test.rb +69 -0
  78. data/test/vagrant/provisioners/puppet_test.rb +69 -54
  79. data/test/vagrant/{ssh_session_test.rb → ssh/session_test.rb} +0 -0
  80. data/test/vagrant/ssh_test.rb +12 -1
  81. data/test/vagrant/systems/base_test.rb +18 -0
  82. data/test/vagrant/systems/linux_test.rb +2 -2
  83. data/test/vagrant/vm_test.rb +33 -5
  84. data/vagrant.gemspec +6 -5
  85. metadata +42 -16
  86. data/lib/vagrant/util/glob_loader.rb +0 -24
data/.gitignore CHANGED
@@ -11,3 +11,5 @@ _site/*
11
11
  doc/
12
12
  tags
13
13
  Gemfile.lock
14
+ .idea/*
15
+ *.iml
data/CHANGELOG.md CHANGED
@@ -1,3 +1,29 @@
1
+ ## 0.7.0.beta2 (January 13, 2010)
2
+
3
+ - Puppet server provisioner. [GH-262]
4
+ - Use numeric uid/gid in mounting shared folders to increase portability. [GH-252]
5
+ - HTTP downloading follows redirects. [GH-163]
6
+ - Downloaders have clearer output to note what they're doing.
7
+ - Shared folders with no guest path are not automounted. [GH-184]
8
+ - Boxes downloaded during `vagrant up` reload the Vagrantfile config, which
9
+ fixes a problem with box settings not being properly loaded. [GH-231]
10
+ - `config.ssh.forward_x11` to enable the ForwardX11 SSH option. [GH-255]
11
+ - Vagrant source now has a `contrib` directory where contributions of miscellaneous
12
+ addons for Vagrant will be added.
13
+ - Vagrantfiles are now loaded only once (instead of 4+ times) [GH-238]
14
+ - Ability to move home vagrant dir (~/.vagrant) by setting VAGRANT_HOME
15
+ environmental variable.
16
+ - Removed check and error for the "OSE" version of VirtualBox, since with
17
+ VirtualBox 4 this distinction no longer exists.
18
+ - Ability to specify proxy settings for chef. [GH-169]
19
+ - Helpful error message shown if NFS mounting fails. [GH-135]
20
+ - Gentoo guests now support host only networks. [GH-240]
21
+ - RedHat (CentOS included) guests now support host only networks. [GH-260]
22
+ - New Vagrantfile syntax for enabling and configuring provisioners. This
23
+ change is not backwards compatible. [GH-265]
24
+ - Provisioners are now RVM-friendly, meaning if you installed chef or puppet
25
+ with an RVM managed Ruby, Vagrant now finds then. [GH-254]
26
+
1
27
  ## 0.7.0.beta (December 24, 2010)
2
28
 
3
29
  - VirtualBox 4.0 support. Support for VirtualBox 3.2 is _dropped_, since
data/Gemfile CHANGED
@@ -16,12 +16,4 @@ group :test do
16
16
  # For documentation
17
17
  gem "yard", "~> 0.6.1"
18
18
  gem "bluecloth"
19
-
20
- platforms :mri_18 do
21
- gem "ruby-debug"
22
- end
23
-
24
- platforms :mri_19 do
25
- gem "ruby-debug19"
26
- end
27
19
  end
data/config/default.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  Vagrant::Config.run do |config|
2
2
  # default config goes here
3
3
  config.vagrant.dotfile_name = ".vagrant"
4
- config.vagrant.home = "~/.vagrant"
5
4
  config.vagrant.host = :detect
6
5
 
7
6
  config.ssh.username = "vagrant"
@@ -12,6 +11,7 @@ Vagrant::Config.run do |config|
12
11
  config.ssh.timeout = 30
13
12
  config.ssh.private_key_path = File.expand_path("keys/vagrant", Vagrant.source_root)
14
13
  config.ssh.forward_agent = false
14
+ config.ssh.forward_x11 = false
15
15
 
16
16
  config.vm.auto_port_range = (2200..2250)
17
17
  config.vm.box_ovf = "box.ovf"
@@ -19,7 +19,6 @@ Vagrant::Config.run do |config|
19
19
  config.vm.base_mac = nil
20
20
  config.vm.forward_port("ssh", 22, 2222, :auto => true)
21
21
  config.vm.disk_image_format = 'VMDK'
22
- config.vm.provisioner = nil
23
22
  config.vm.shared_folder_uid = nil
24
23
  config.vm.shared_folder_gid = nil
25
24
  config.vm.boot_mode = "vrdp"
data/contrib/README.md ADDED
@@ -0,0 +1,12 @@
1
+ # Vagrant Contrib
2
+
3
+ Miscellaneous contributions which assist people in using Vagrant will
4
+ make their way into this directory. An up-to-date list of short descriptions
5
+ for each item will be kept below.
6
+
7
+ ## List of Contrib Items
8
+
9
+ * `emacs` - Contains a file showing how to associate `Vagrantfile` with
10
+ Ruby syntax highlighting.
11
+ * `vim` - Contains a `.vim` file for enabling Ruby syntax highlighting
12
+ for `Vagrantfile`s.
@@ -0,0 +1,8 @@
1
+ ;;--------------------------------------------------------------------
2
+ ;; Teach emacs to syntax highlight Vagrantfile as Ruby.
3
+ ;;
4
+ ;; Installation: Copy the line below into your emacs configuration,
5
+ ;; or drop this file anywhere in your "~/.emacs.d" directory and be
6
+ ;; sure to "load" it.
7
+ ;;--------------------------------------------------------------------
8
+ (add-to-list 'auto-mode-alist '("Vagrantfile$" . ruby-mode))
@@ -0,0 +1,9 @@
1
+ " Teach vim to syntax highlight Vagrantfile as ruby
2
+ "
3
+ " Install: $HOME/.vim/plugin/vagrant.vim
4
+ " Author: Brandon Philips <brandon@ifup.org>
5
+
6
+ augroup vagrant
7
+ au!
8
+ au BufRead,BufNewFile Vagrantfile set filetype=ruby
9
+ augroup END
data/lib/vagrant.rb CHANGED
@@ -4,25 +4,21 @@ require 'i18n'
4
4
  require 'virtualbox'
5
5
 
6
6
  module Vagrant
7
- # TODO: Move more classes over to the autoload model. We'll
8
- # start small, but slowly move everything over.
9
-
7
+ autoload :Action, 'vagrant/action'
10
8
  autoload :Box, 'vagrant/box'
11
9
  autoload :BoxCollection, 'vagrant/box_collection'
12
10
  autoload :CLI, 'vagrant/cli'
13
11
  autoload :Config, 'vagrant/config'
14
12
  autoload :DataStore, 'vagrant/data_store'
13
+ autoload :Downloaders, 'vagrant/downloaders'
14
+ autoload :Environment, 'vagrant/environment'
15
15
  autoload :Errors, 'vagrant/errors'
16
+ autoload :Hosts, 'vagrant/hosts'
16
17
  autoload :Plugin, 'vagrant/plugin'
17
18
  autoload :TestHelpers, 'vagrant/test_helpers'
19
+ autoload :UI, 'vagrant/ui'
18
20
  autoload :Util, 'vagrant/util'
19
-
20
- module Command
21
- autoload :Base, 'vagrant/command/base'
22
- autoload :GroupBase, 'vagrant/command/group_base'
23
- autoload :Helpers, 'vagrant/command/helpers'
24
- autoload :NamedBase, 'vagrant/command/named_base'
25
- end
21
+ autoload :VM, 'vagrant/vm'
26
22
 
27
23
  # The source root is the path to the root directory of
28
24
  # the Vagrant gem.
@@ -34,13 +30,13 @@ end
34
30
  # Default I18n to load the en locale
35
31
  I18n.load_path << File.expand_path("templates/locales/en.yml", Vagrant.source_root)
36
32
 
37
- # Load them up. One day we'll convert this to autoloads. Today
38
- # is not that day. Low hanging fruit for anyone wishing to do it.
39
- libdir = File.expand_path("lib/vagrant", Vagrant.source_root)
40
- Vagrant::Util::GlobLoader.glob_require(libdir, %w{
41
- downloaders/base provisioners/base provisioners/chef systems/base
42
- hosts/base})
43
-
44
- # Initialize the built-in actions and load the plugins.
33
+ # Load the things which must be loaded before anything else. Note that
34
+ # I'm not sure why 'vagrant/ssh' must be loaded. But if I don't, I get
35
+ # a very scary "unsupported cipher" error from net-ssh for no apparent reason.
36
+ require 'vagrant/command'
37
+ require 'vagrant/provisioners'
38
+ require 'vagrant/systems'
39
+ require 'vagrant/ssh'
40
+ require 'vagrant/version'
45
41
  Vagrant::Action.builtin!
46
42
  Vagrant::Plugin.load!
@@ -1,3 +1,12 @@
1
+ require 'vagrant/action/builder'
2
+ require 'vagrant/action/builtin'
3
+
4
+ # The builtin middlewares
5
+ require 'vagrant/action/box'
6
+ require 'vagrant/action/env'
7
+ require 'vagrant/action/general'
8
+ require 'vagrant/action/vm'
9
+
1
10
  module Vagrant
2
11
  # Manages action running and registration. Every Vagrant environment
3
12
  # has an instance of {Action} to allow for running in the context of
@@ -44,6 +53,9 @@ module Vagrant
44
53
  # Where `:name` is the name of the registered action.
45
54
  #
46
55
  class Action
56
+ autoload :Environment, 'vagrant/action/environment'
57
+ autoload :Warden, 'vagrant/action/warden'
58
+
47
59
  include Util
48
60
  @@reported_interrupt = false
49
61
 
@@ -0,0 +1,11 @@
1
+ module Vagrant
2
+ class Action
3
+ module Box
4
+ autoload :Destroy, 'vagrant/action/box/destroy'
5
+ autoload :Download, 'vagrant/action/box/download'
6
+ autoload :Package, 'vagrant/action/box/package'
7
+ autoload :Unpackage, 'vagrant/action/box/unpackage'
8
+ autoload :Verify, 'vagrant/action/box/verify'
9
+ end
10
+ end
11
+ end
@@ -64,7 +64,6 @@ module Vagrant
64
64
  end
65
65
 
66
66
  def download_to(f)
67
- @env.ui.info I18n.t("vagrant.actions.box.download.copying")
68
67
  @downloader.download!(@env["box"].uri, f)
69
68
  end
70
69
  end
@@ -0,0 +1,7 @@
1
+ module Vagrant
2
+ class Action
3
+ module Env
4
+ autoload :Set, 'vagrant/action/env/set'
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ module Vagrant
2
+ class Action
3
+ module General
4
+ autoload :Package, 'vagrant/action/general/package'
5
+ autoload :Validate, 'vagrant/action/general/validate'
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,30 @@
1
+ module Vagrant
2
+ class Action
3
+ module VM
4
+ autoload :Boot, 'vagrant/action/vm/boot'
5
+ autoload :CheckBox, 'vagrant/action/vm/check_box'
6
+ autoload :CheckGuestAdditions, 'vagrant/action/vm/check_guest_additions'
7
+ autoload :CleanMachineFolder, 'vagrant/action/vm/clean_machine_folder'
8
+ autoload :ClearForwardedPorts, 'vagrant/action/vm/clear_forwarded_ports'
9
+ autoload :ClearNFSExports, 'vagrant/action/vm/clear_nfs_exports'
10
+ autoload :ClearSharedFolders, 'vagrant/action/vm/clear_shared_folders'
11
+ autoload :Customize, 'vagrant/action/vm/customize'
12
+ autoload :Destroy, 'vagrant/action/vm/destroy'
13
+ autoload :DestroyUnusedNetworkInterfaces, 'vagrant/action/vm/destroy_unused_network_interfaces'
14
+ autoload :DiscardState, 'vagrant/action/vm/discard_state'
15
+ autoload :Export, 'vagrant/action/vm/export'
16
+ autoload :ForwardPorts, 'vagrant/action/vm/forward_ports'
17
+ autoload :Halt, 'vagrant/action/vm/halt'
18
+ autoload :Import, 'vagrant/action/vm/import'
19
+ autoload :MatchMACAddress, 'vagrant/action/vm/match_mac_address'
20
+ autoload :Network, 'vagrant/action/vm/network'
21
+ autoload :NFS, 'vagrant/action/vm/nfs'
22
+ autoload :Package, 'vagrant/action/vm/package'
23
+ autoload :PackageVagrantfile, 'vagrant/action/vm/package_vagrantfile'
24
+ autoload :Provision, 'vagrant/action/vm/provision'
25
+ autoload :Resume, 'vagrant/action/vm/resume'
26
+ autoload :ShareFolders, 'vagrant/action/vm/share_folders'
27
+ autoload :Suspend, 'vagrant/action/vm/suspend'
28
+ end
29
+ end
30
+ end
@@ -13,6 +13,7 @@ module Vagrant
13
13
  # Start up the VM and wait for it to boot.
14
14
  boot
15
15
  raise Errors::VMFailedToBoot if !wait_for_boot
16
+
16
17
  @app.call(env)
17
18
  end
18
19
 
@@ -24,7 +25,7 @@ module Vagrant
24
25
  def wait_for_boot
25
26
  @env.ui.info I18n.t("vagrant.actions.vm.boot.waiting")
26
27
 
27
- @env.env.config.ssh.max_tries.to_i.times do |i|
28
+ @env["config"].ssh.max_tries.to_i.times do |i|
28
29
  if @env["vm"].ssh.up?
29
30
  @env.ui.info I18n.t("vagrant.actions.vm.boot.ready")
30
31
  return true
@@ -34,7 +35,7 @@ module Vagrant
34
35
  # get shown
35
36
  return true if @env.interrupted?
36
37
 
37
- sleep 5 if !@env["vagrant.test"]
38
+ sleep 2 if !@env["vagrant.test"]
38
39
  end
39
40
 
40
41
  @env.ui.error I18n.t("vagrant.actions.vm.boot.failed")
@@ -17,6 +17,7 @@ module Vagrant
17
17
  env.ui.info I18n.t("vagrant.actions.vm.check_box.not_found", :name => box_name)
18
18
  Vagrant::Box.add(env.env, box_name, box_url)
19
19
  env["boxes"].reload!
20
+ env.env.reload_config!
20
21
  end
21
22
 
22
23
  @app.call(env)
@@ -25,8 +25,8 @@ module Vagrant
25
25
 
26
26
  if enable_network?
27
27
  @env.ui.info I18n.t("vagrant.actions.vm.network.enabling")
28
- @env["vm"].system.prepare_host_only_network
29
28
  @env.env.config.vm.network_options.compact.each do |network_options|
29
+ @env["vm"].system.prepare_host_only_network(network_options)
30
30
  @env["vm"].system.enable_host_only_network(network_options)
31
31
  end
32
32
  end
@@ -113,7 +113,9 @@ module Vagrant
113
113
  def mount_folders
114
114
  @env.ui.info I18n.t("vagrant.actions.vm.nfs.mounting")
115
115
 
116
- @env["vm"].system.mount_nfs(host_ip, folders)
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])
117
119
  end
118
120
 
119
121
  # Returns the IP address of the first host only network adapter
@@ -2,49 +2,38 @@ module Vagrant
2
2
  class Action
3
3
  module VM
4
4
  class Provision
5
+ attr_reader :provisioners
6
+
5
7
  def initialize(app, env)
6
8
  @app = app
7
9
  @env = env
8
10
  @env["provision.enabled"] = true if !@env.has_key?("provision.enabled")
11
+ @provisioners = []
9
12
 
10
- load_provisioner if provisioning_enabled?
13
+ load_provisioners if provisioning_enabled?
11
14
  end
12
15
 
13
16
  def call(env)
14
17
  @app.call(env)
15
18
 
16
- if provisioning_enabled?
17
- @env.ui.info I18n.t("vagrant.actions.vm.provision.beginning")
18
- @provisioner.provision!
19
+ @provisioners.each do |instance|
20
+ @env.ui.info I18n.t("vagrant.actions.vm.provision.beginning", :provisioner => instance.class)
21
+ instance.provision!
19
22
  end
20
23
  end
21
24
 
22
25
  def provisioning_enabled?
23
- !@env["config"].vm.provisioner.nil? && @env["provision.enabled"]
26
+ !@env["config"].vm.provisioners.empty? && @env["provision.enabled"]
24
27
  end
25
28
 
26
- def load_provisioner
27
- provisioner = @env["config"].vm.provisioner
28
-
29
- if provisioner.is_a?(Class)
30
- @provisioner = provisioner.new(@env)
31
- raise Errors::ProvisionInvalidClass if !@provisioner.is_a?(Provisioners::Base)
32
- elsif provisioner.is_a?(Symbol)
33
- # We have a few hard coded provisioners for built-ins
34
- mapping = {
35
- :chef_solo => Provisioners::ChefSolo,
36
- :chef_server => Provisioners::ChefServer,
37
- :puppet => Provisioners::Puppet
38
- }
29
+ def load_provisioners
30
+ @env["config"].vm.provisioners.each do |provisioner|
31
+ @env.ui.info I18n.t("vagrant.actions.vm.provision.enabled", :provisioner => provisioner.shortcut)
39
32
 
40
- provisioner_klass = mapping[provisioner]
41
- raise Errors::ProvisionUnknownType, :provisioner => provisioner.to_s if provisioner_klass.nil?
42
- @provisioner = provisioner_klass.new(@env)
33
+ instance = provisioner.provisioner.new(@env, provisioner.config)
34
+ instance.prepare
35
+ @provisioners << instance
43
36
  end
44
-
45
- @env.ui.info I18n.t("vagrant.actions.vm.provision.enabled", :provisioner => @provisioner.class.to_s)
46
- @provisioner.prepare
47
- @provisioner
48
37
  end
49
38
  end
50
39
  end
@@ -50,10 +50,17 @@ module Vagrant
50
50
 
51
51
  @env["vm"].ssh.execute do |ssh|
52
52
  shared_folders.each do |name, data|
53
- @env.ui.info(I18n.t("vagrant.actions.vm.share_folders.mounting_entry",
54
- :name => name,
55
- :guest_path => data[:guestpath]))
56
- @env["vm"].system.mount_shared_folder(ssh, name, data[:guestpath])
53
+ if data[:guestpath]
54
+ # Guest path specified, so mount the folder to specified point
55
+ @env.ui.info(I18n.t("vagrant.actions.vm.share_folders.mounting_entry",
56
+ :name => name,
57
+ :guest_path => data[:guestpath]))
58
+ @env["vm"].system.mount_shared_folder(ssh, name, data[:guestpath])
59
+ else
60
+ # If no guest path is specified, then automounting is disabled
61
+ @env.ui.info(I18n.t("vagrant.actions.vm.share_folders.nomount_entry",
62
+ :name => name))
63
+ end
57
64
  end
58
65
  end
59
66
  end
@@ -0,0 +1,25 @@
1
+ module Vagrant
2
+ module Command
3
+ autoload :Base, 'vagrant/command/base'
4
+ autoload :GroupBase, 'vagrant/command/group_base'
5
+ autoload :Helpers, 'vagrant/command/helpers'
6
+ autoload :NamedBase, 'vagrant/command/named_base'
7
+ end
8
+ end
9
+
10
+ # The built-in commands must always be loaded
11
+ require 'vagrant/command/box'
12
+ require 'vagrant/command/destroy'
13
+ require 'vagrant/command/halt'
14
+ require 'vagrant/command/init'
15
+ require 'vagrant/command/package'
16
+ require 'vagrant/command/provision'
17
+ require 'vagrant/command/reload'
18
+ require 'vagrant/command/resume'
19
+ require 'vagrant/command/ssh'
20
+ require 'vagrant/command/ssh_config'
21
+ require 'vagrant/command/status'
22
+ require 'vagrant/command/suspend'
23
+ require 'vagrant/command/up'
24
+ require 'vagrant/command/upgrade_to_060'
25
+ require 'vagrant/command/version'
@@ -1,5 +1,13 @@
1
1
  require 'vagrant/config/base'
2
2
  require 'vagrant/config/error_recorder'
3
+ require 'vagrant/config/top'
4
+
5
+ # The built-in configuration classes
6
+ require 'vagrant/config/vagrant'
7
+ require 'vagrant/config/ssh'
8
+ require 'vagrant/config/nfs'
9
+ require 'vagrant/config/vm'
10
+ require 'vagrant/config/package'
3
11
 
4
12
  module Vagrant
5
13
  # The config class is responsible for loading Vagrant configurations, which
@@ -17,157 +25,99 @@ module Vagrant
17
25
  # class you are looking for. Loading configuration is quite easy. The following
18
26
  # example assumes `env` is already a loaded instance of {Environment}:
19
27
  #
20
- # config = Vagrant::Config.new(env)
21
- # config.queue << "/path/to/some/Vagrantfile"
22
- # result = config.load!
28
+ # config = Vagrant::Config.new
29
+ # config.set(:first, "/path/to/some/Vagrantfile")
30
+ # config.set(:second, "/path/to/another/Vagrantfile")
31
+ # config.load_order = [:first, :second]
32
+ # result = config.load(env)
23
33
  #
24
34
  # p "Your box is: #{result.vm.box}"
25
35
  #
36
+ # The load order determines what order the config files specified are loaded.
37
+ # If a key is not mentioned (for example if above the load order was set to
38
+ # `[:first]`, therefore `:second` was not mentioned), then that config file
39
+ # won't be loaded.
26
40
  class Config
27
- extend Util::StackedProcRunner
28
-
29
- @@config = nil
30
-
31
- attr_reader :queue
32
-
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
40
- def reset!(env=nil)
41
- @@config = nil
42
- proc_stack.clear
41
+ # An array of symbols specifying the load order for the procs.
42
+ attr_accessor :load_order
43
+ attr_reader :procs
43
44
 
44
- # Reset the configuration to the specified environment
45
- config(env)
46
- end
47
-
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.
51
- def config(env=nil)
52
- @@config ||= Config::Top.new(env)
53
- end
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
- #
63
- def run(&block)
64
- push_proc(&block)
65
- end
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.
71
- def execute!
72
- config_object ||= config
73
- run_procs!(config_object)
74
- config_object
75
- end
45
+ # This is the method which is called by all Vagrantfiles to configure Vagrant.
46
+ # This method expects a block which accepts a single argument representing
47
+ # an instance of the {Config::Top} class.
48
+ #
49
+ # Note that the block is not run immediately. Instead, it's proc is stored
50
+ # away for execution later.
51
+ def self.run(&block)
52
+ # Store it for later
53
+ @last_procs ||= []
54
+ @last_procs << block
76
55
  end
77
56
 
78
- # Initialize a {Config} object for the given {Environment}.
57
+ # Returns the last proc which was activated for the class via {run}. This
58
+ # also sets the last proc to `nil` so that calling this method multiple times
59
+ # will not return duplicates.
79
60
  #
80
- # @param [Environment] env Environment which config object will be part
81
- # of.
82
- def initialize(env)
83
- @env = env
84
- @queue = []
61
+ # @return [Proc]
62
+ def self.last_proc
63
+ value = @last_procs
64
+ @last_procs = nil
65
+ value
85
66
  end
86
67
 
87
- # Loads the queue of files/procs, executes them in the proper
88
- # sequence, and returns the resulting configuration object.
89
- def load!
90
- self.class.reset!(@env)
68
+ def initialize(parent=nil)
69
+ @procs = {}
70
+ @load_order = []
91
71
 
92
- queue.flatten.each do |item|
93
- if item.is_a?(String) && File.exist?(item)
94
- begin
95
- load item
96
- rescue SyntaxError => e
97
- # Report syntax errors in a nice way for Vagrantfiles
98
- raise Errors::VagrantfileSyntaxError, :file => e.message
99
- end
100
- elsif item.is_a?(Proc)
101
- self.class.run(&item)
102
- end
72
+ if parent
73
+ # Shallow copy the procs and load order from parent if given
74
+ @procs = parent.procs.dup
75
+ @load_order = parent.load_order.dup
103
76
  end
77
+ end
104
78
 
105
- return self.class.execute!
79
+ # Adds a Vagrantfile to be loaded to the queue of config procs. Note
80
+ # that this causes the Vagrantfile file to be loaded at this point,
81
+ # and it will never be loaded again.
82
+ def set(key, path)
83
+ return if @procs.has_key?(key)
84
+ @procs[key] = [path].flatten.map(&method(:proc_for)).flatten
106
85
  end
107
- end
108
86
 
109
- class Config
110
- # This class is the "top" configure class, which handles registering
111
- # other configuration classes as well as validation of all configured
112
- # classes. This is the object which is returned by {Environment#config}
113
- # and has accessors to all other configuration classes.
87
+ # Loads the added procs using the set `load_order` attribute and returns
88
+ # the {Config::Top} object result. The configuration is loaded for the
89
+ # given {Environment} object.
114
90
  #
115
- # If you're looking to create your own configuration class, see {Base}.
116
- class Top < Base
117
- @@configures = {} if !defined?(@@configures)
118
-
119
- class << self
120
- # The list of registered configuration classes as well as the key
121
- # they're registered under.
122
- def configures_list
123
- @@configures ||= {}
124
- end
125
-
126
- # Registers a configuration class with the given key. This method shouldn't
127
- # be called. Instead, inherit from {Base} and call {Base.configures}.
128
- def configures(key, klass)
129
- configures_list[key] = klass
130
- attr_reader key.to_sym
91
+ # @param [Environment] env
92
+ def load(env)
93
+ config = Top.new(env)
94
+
95
+ # Only run the procs specified in the load order, in the order
96
+ # specified.
97
+ load_order.each do |key|
98
+ if @procs[key]
99
+ @procs[key].each do |proc|
100
+ proc.call(config) if proc
101
+ end
131
102
  end
132
103
  end
133
104
 
134
- def initialize(env=nil)
135
- self.class.configures_list.each do |key, klass|
136
- config = klass.new
137
- config.env = env
138
- config.top = self
139
- instance_variable_set("@#{key}".to_sym, config)
140
- end
105
+ config
106
+ end
141
107
 
142
- @env = env
143
- end
108
+ protected
144
109
 
145
- # Validates the configuration classes of this instance and raises an
146
- # exception if they are invalid. If you are implementing a custom configuration
147
- # class, the method you want to implement is {Base#validate}. This is
148
- # the method that checks all the validation, not one which defines
149
- # validation rules.
150
- def validate!
151
- # Validate each of the configured classes and store the results into
152
- # a hash.
153
- errors = self.class.configures_list.inject({}) do |container, data|
154
- key, _ = data
155
- recorder = ErrorRecorder.new
156
- send(key.to_sym).validate(recorder)
157
- container[key.to_sym] = recorder if !recorder.errors.empty?
158
- container
159
- end
110
+ def proc_for(path)
111
+ return nil if !path
112
+ return path if path.is_a?(Proc)
160
113
 
161
- return if errors.empty?
162
- raise Errors::ConfigValidationFailed, :messages => Util::TemplateRenderer.render("config/validation_failed", :errors => errors)
114
+ begin
115
+ Kernel.load path if File.exist?(path)
116
+ return self.class.last_proc
117
+ rescue SyntaxError => e
118
+ # Report syntax errors in a nice way for Vagrantfiles
119
+ raise Errors::VagrantfileSyntaxError, :file => e.message
163
120
  end
164
121
  end
165
122
  end
166
123
  end
167
-
168
- # The built-in configuration classes
169
- require 'vagrant/config/vagrant'
170
- require 'vagrant/config/ssh'
171
- require 'vagrant/config/nfs'
172
- require 'vagrant/config/vm'
173
- require 'vagrant/config/package'