diff --git a/lib/vagrant.rb b/lib/vagrant.rb index 122a5b5e8..2fcb880dd 100644 --- a/lib/vagrant.rb +++ b/lib/vagrant.rb @@ -60,6 +60,14 @@ module Vagrant def self.guests @guests ||= Registry.new end + + # Global registry of provisioners. + # + # This registry is used to look up the provisioners provided for + # `config.vm.provision`. + def self.provisioners + @provisioners ||= Registry.new + end end # # Default I18n to load the en locale @@ -83,6 +91,13 @@ Vagrant.guests.register(:solaris) { Vagrant::Systems::Solaris } Vagrant.guests.register(:suse) { Vagrant::Systems::Suse } Vagrant.guests.register(:ubuntu) { Vagrant::Systems::Ubuntu } +# Register the built-in provisioners +Vagrant.provisioners.register(:chef_solo) { Vagrant::Provisioners::ChefSolo } +Vagrant.provisioners.register(:chef_client) { Vagrant::Provisioners::ChefClient } +Vagrant.provisioners.register(:puppet) { Vagrant::Provisioners::Puppet } +Vagrant.provisioners.register(:puppet_server) { Vagrant::Provisioners::PuppetServer } +Vagrant.provisioners.register(:shell) { Vagrant::Provisioners::Shell } + # Load the things which must be loaded before anything else. require 'vagrant/command' require 'vagrant/provisioners' diff --git a/lib/vagrant/config/vm.rb b/lib/vagrant/config/vm.rb index 6e72a8c5b..573b80a66 100644 --- a/lib/vagrant/config/vm.rb +++ b/lib/vagrant/config/vm.rb @@ -63,7 +63,7 @@ module Vagrant end def provision(name, options=nil, &block) - @provisioners << Provisioner.new(top, name, options, &block) + @provisioners << Provisioner.new(name, options, &block) end def customize(&block) diff --git a/lib/vagrant/config/vm/provisioner.rb b/lib/vagrant/config/vm/provisioner.rb index 7176c9e12..eb996208b 100644 --- a/lib/vagrant/config/vm/provisioner.rb +++ b/lib/vagrant/config/vm/provisioner.rb @@ -3,35 +3,25 @@ module Vagrant class VMConfig < Base # Represents a single configured provisioner for a VM. class Provisioner - attr_reader :top attr_reader :shortcut attr_reader :provisioner attr_reader :config - def initialize(top, shortcut, options=nil, &block) - @top = top + def initialize(shortcut, options=nil, &block) @shortcut = shortcut @provisioner = shortcut - @provisioner = Provisioners::Base.registered[shortcut] if shortcut.is_a?(Symbol) + @provisioner = Vagrant.provisioners.get(shortcut) if shortcut.is_a?(Symbol) @config = nil - configure(options, &block) + configure(options, &block) if @provisioner end # Configures the provisioner if it can (if it is valid). def configure(options=nil, &block) - # We don't want ancestors to be searched. This is the default in 1.8, - # but not in 1.9, hence this hackery. - const_args = ["Config"] - const_args << false if RUBY_VERSION >= "1.9" + config_class = @provisioner.config_class + return if !config_class - # We assume that every provisioner has a `Config` class beneath - # it for configuring. - return if !@provisioner || !@provisioner.const_defined?(*const_args) - - # Instantiate the config class and configure it - @config = @provisioner.const_get(*const_args).new - @config.top = top + @config = config_class.new @config.set_options(options) if options block.call(@config) if block end diff --git a/lib/vagrant/provisioners/base.rb b/lib/vagrant/provisioners/base.rb index 23a04975b..a896c2427 100644 --- a/lib/vagrant/provisioners/base.rb +++ b/lib/vagrant/provisioners/base.rb @@ -1,9 +1,10 @@ module Vagrant module Provisioners # The base class for a "provisioner." A provisioner is responsible for - # provisioning a Vagrant system. This has been abstracted out to provide - # support for multiple solutions such as Chef Solo, Chef Client, and - # Puppet. + # provisioning a Vagrant system. + # + # This has been abstracted out so it is easy to provide support for + # multiple solutions. class Base include Vagrant::Util @@ -15,24 +16,15 @@ module Vagrant # the `Config` class which is part of the provisioner. attr_reader :config - # Registers a provisioner with a given shortcut. This allows that provisioner - # to be referenced with the shortcut. - # - # @param [Symbol] shortcut - def self.register(shortcut) - registered[shortcut] = self - end - - # Returns the provisioner associated with the given shortcut. - def self.registered - @@registered ||= {} - end - def initialize(env, config) @env = env @config = config end + # This method is expected to return a class that is used for configuration + # for the provisioner. + def self.config_class; end + # This is the method called to "prepare" the provisioner. This is called # before any actions are run by the action runner (see {Vagrant::Actions::Runner}). # This can be used to setup shared folders, forward ports, etc. Whatever is diff --git a/lib/vagrant/provisioners/chef_client.rb b/lib/vagrant/provisioners/chef_client.rb index 35ccdc71a..3c2630f95 100644 --- a/lib/vagrant/provisioners/chef_client.rb +++ b/lib/vagrant/provisioners/chef_client.rb @@ -5,8 +5,6 @@ module Vagrant # This class implements provisioning via chef-client, allowing provisioning # with a chef server. class ChefClient < Chef - register :chef_client - class Config < Chef::Config attr_accessor :chef_server_url attr_accessor :validation_key_path @@ -38,6 +36,10 @@ module Vagrant end end + def self.config_class + Config + end + def prepare raise ChefError, :server_validation_key_required if config.validation_key_path.nil? raise ChefError, :server_validation_key_doesnt_exist if !File.file?(validation_key_path) diff --git a/lib/vagrant/provisioners/chef_solo.rb b/lib/vagrant/provisioners/chef_solo.rb index 26b343c2f..54ec7241e 100644 --- a/lib/vagrant/provisioners/chef_solo.rb +++ b/lib/vagrant/provisioners/chef_solo.rb @@ -2,8 +2,6 @@ module Vagrant module Provisioners # This class implements provisioning via chef-solo. class ChefSolo < Chef - register :chef_solo - extend Util::Counter include Util::Counter @@ -35,6 +33,10 @@ module Vagrant attr_reader :role_folders attr_reader :data_bags_folders + def self.config_class + Config + end + def prepare @cookbook_folders = expanded_folders(config.cookbooks_path, "cookbooks") @role_folders = expanded_folders(config.roles_path, "roles") diff --git a/lib/vagrant/provisioners/puppet.rb b/lib/vagrant/provisioners/puppet.rb index 15cc3f2f3..dc48c74f2 100644 --- a/lib/vagrant/provisioners/puppet.rb +++ b/lib/vagrant/provisioners/puppet.rb @@ -5,8 +5,6 @@ module Vagrant end class Puppet < Base - register :puppet - class Config < Vagrant::Config::Base attr_accessor :manifest_file attr_accessor :manifests_path @@ -69,6 +67,10 @@ module Vagrant end end + def self.config_class + Config + end + def prepare set_module_paths share_manifests diff --git a/lib/vagrant/provisioners/puppet_server.rb b/lib/vagrant/provisioners/puppet_server.rb index 0d81f6db1..5dcf5b7c6 100644 --- a/lib/vagrant/provisioners/puppet_server.rb +++ b/lib/vagrant/provisioners/puppet_server.rb @@ -5,8 +5,6 @@ module Vagrant end class PuppetServer < Base - register :puppet_server - class Config < Vagrant::Config::Base attr_accessor :puppet_server attr_accessor :puppet_node @@ -19,6 +17,10 @@ module Vagrant end end + def self.config_class + Config + end + def provision! verify_binary("puppetd") run_puppetd_client diff --git a/lib/vagrant/provisioners/shell.rb b/lib/vagrant/provisioners/shell.rb index 08940bece..50d1e1569 100644 --- a/lib/vagrant/provisioners/shell.rb +++ b/lib/vagrant/provisioners/shell.rb @@ -1,8 +1,6 @@ module Vagrant module Provisioners class Shell < Base - register :shell - class Config < Vagrant::Config::Base attr_accessor :inline attr_accessor :path @@ -47,6 +45,10 @@ module Vagrant end end + def self.config_class + Config + end + # This method yields the path to a script to upload and execute # on the remote server. This method will properly clean up the # script file if needed. diff --git a/test/unit/vagrant_test.rb b/test/unit/vagrant_test.rb new file mode 100644 index 000000000..03824f94e --- /dev/null +++ b/test/unit/vagrant_test.rb @@ -0,0 +1,19 @@ +require File.expand_path("../base", __FILE__) + +describe Vagrant do + it "has the path to the source root" do + described_class.source_root.should == Pathname.new(File.expand_path("../../../", __FILE__)) + end + + it "has a registry for hosts" do + described_class.hosts.should be_a(Vagrant::Registry) + end + + it "has a registry for guests" do + described_class.guests.should be_a(Vagrant::Registry) + end + + it "has a registry for provisioners" do + described_class.provisioners.should be_a(Vagrant::Registry) + end +end