Provider plugins can provide arbitrary options

This commit is contained in:
Mitchell Hashimoto 2013-03-21 17:57:31 -07:00
parent c46f1562a6
commit 2e50a238fc
8 changed files with 54 additions and 39 deletions

View File

@ -287,11 +287,15 @@ module Vagrant
raise Errors::MachineNotFound, :name => name, :provider => provider raise Errors::MachineNotFound, :name => name, :provider => provider
end end
provider_cls = Vagrant.plugin("2").manager.providers[provider] provider_plugin = Vagrant.plugin("2").manager.providers[provider]
if !provider_cls if !provider_plugin
raise Errors::ProviderNotFound, :machine => name, :provider => provider raise Errors::ProviderNotFound, :machine => name, :provider => provider
end end
# Extra the provider class and options from the plugin data
provider_cls = provider_plugin[0]
provider_options = provider_plugin[1]
# Build the machine configuration. This requires two passes: The first pass # Build the machine configuration. This requires two passes: The first pass
# loads in the machine sub-configuration. Since this can potentially # loads in the machine sub-configuration. Since this can potentially
# define a new box to base the machine from, we then make a second pass # define a new box to base the machine from, we then make a second pass
@ -356,7 +360,7 @@ module Vagrant
# Create the machine and cache it for future calls. This will also # Create the machine and cache it for future calls. This will also
# return the machine from this method. # return the machine from this method.
@machines[cache_key] = Machine.new(name, provider, provider_cls, provider_config, @machines[cache_key] = Machine.new(name, provider, provider_cls, provider_config,
config, machine_data_path, box, self) provider_options, config, machine_data_path, box, self)
end end
# This returns a list of the configured machines for this environment. # This returns a list of the configured machines for this environment.

View File

@ -52,6 +52,11 @@ module Vagrant
# @return [Symbol] # @return [Symbol]
attr_reader :provider_name attr_reader :provider_name
# The options given to the provider when registering the plugin.
#
# @return [Hash]
attr_reader :provider_options
# Initialize a new machine. # Initialize a new machine.
# #
# @param [String] name Name of the virtual machine. # @param [String] name Name of the virtual machine.
@ -59,13 +64,15 @@ module Vagrant
# currently expected to be a V1 `provider` plugin. # currently expected to be a V1 `provider` plugin.
# @param [Object] provider_config The provider-specific configuration for # @param [Object] provider_config The provider-specific configuration for
# this machine. # this machine.
# @param [Hash] provider_options The provider-specific options from the
# plugin definition.
# @param [Object] config The configuration for this machine. # @param [Object] config The configuration for this machine.
# @param [Pathname] data_dir The directory where machine-specific data # @param [Pathname] data_dir The directory where machine-specific data
# can be stored. This directory is ensured to exist. # can be stored. This directory is ensured to exist.
# @param [Box] box The box that is backing this virtual machine. # @param [Box] box The box that is backing this virtual machine.
# @param [Environment] env The environment that this machine is a # @param [Environment] env The environment that this machine is a
# part of. # part of.
def initialize(name, provider_name, provider_cls, provider_config, config, data_dir, box, env, base=false) def initialize(name, provider_name, provider_cls, provider_config, provider_options, config, data_dir, box, env, base=false)
@logger = Log4r::Logger.new("vagrant::machine") @logger = Log4r::Logger.new("vagrant::machine")
@logger.info("Initializing machine: #{name}") @logger.info("Initializing machine: #{name}")
@logger.info(" - Provider: #{provider_cls}") @logger.info(" - Provider: #{provider_cls}")
@ -79,6 +86,7 @@ module Vagrant
@name = name @name = name
@provider_config = provider_config @provider_config = provider_config
@provider_name = provider_name @provider_name = provider_name
@provider_options = provider_options
# Read the ID, which is usually in local storage # Read the ID, which is usually in local storage
@id = nil @id = nil

View File

@ -16,12 +16,18 @@ module Vagrant
# @return [Hash<Symbol, Registry>] # @return [Hash<Symbol, Registry>]
attr_reader :configs attr_reader :configs
# This contains all the provider plugins by name, and returns
# the provider class and options.
#
# @return [Hash<Symbol, Registry>]
attr_reader :providers
def initialize def initialize
# The action hooks hash defaults to [] # The action hooks hash defaults to []
@action_hooks = Hash.new { |h, k| h[k] = [] } @action_hooks = Hash.new { |h, k| h[k] = [] }
# Create the configs hash which defaults to a registry
@configs = Hash.new { |h, k| h[k] = Registry.new } @configs = Hash.new { |h, k| h[k] = Registry.new }
@providers = Registry.new
end end
end end
end end

View File

@ -89,7 +89,7 @@ module Vagrant
def providers def providers
Registry.new.tap do |result| Registry.new.tap do |result|
@registered.each do |plugin| @registered.each do |plugin|
result.merge!(plugin.provider) result.merge!(plugin.components.providers)
end end
end end
end end

View File

@ -162,14 +162,12 @@ module Vagrant
# Registers additional providers to be available. # Registers additional providers to be available.
# #
# @param [Symbol] name Name of the provider. # @param [Symbol] name Name of the provider.
def self.provider(name=UNSET_VALUE, &block) def self.provider(name=UNSET_VALUE, options=nil, &block)
data[:providers] ||= Registry.new components.providers.register(name.to_sym) do
[block.call, options || {}]
end
# Register a new provider class only if a name was given nil
data[:providers].register(name.to_sym, &block) if name != UNSET_VALUE
# Return the registry
data[:providers]
end end
# Registers additional provisioners to be available. # Registers additional provisioners to be available.

View File

@ -14,6 +14,7 @@ describe Vagrant::Machine do
end end
let(:provider_config) { Object.new } let(:provider_config) { Object.new }
let(:provider_name) { :test } let(:provider_name) { :test }
let(:provider_options) { {} }
let(:box) { Object.new } let(:box) { Object.new }
let(:config) { env.config_global } let(:config) { env.config_global }
let(:data_dir) { Pathname.new(Tempdir.new.path) } let(:data_dir) { Pathname.new(Tempdir.new.path) }
@ -30,10 +31,12 @@ describe Vagrant::Machine do
let(:instance) { new_instance } let(:instance) { new_instance }
subject { instance }
# Returns a new instance with the test data # Returns a new instance with the test data
def new_instance def new_instance
described_class.new(name, provider_name, provider_cls, provider_config, described_class.new(name, provider_name, provider_cls, provider_config,
config, data_dir, box, env) provider_options, config, data_dir, box, env)
end end
describe "initialization" do describe "initialization" do
@ -63,7 +66,7 @@ describe Vagrant::Machine do
# Initialize a new machine and verify that we properly receive # Initialize a new machine and verify that we properly receive
# the machine we expect. # the machine we expect.
instance = described_class.new(name, provider_name, provider_cls, provider_config, instance = described_class.new(name, provider_name, provider_cls, provider_config,
config, data_dir, box, env) provider_options, config, data_dir, box, env)
received_machine.should eql(instance) received_machine.should eql(instance)
end end
@ -117,25 +120,13 @@ describe Vagrant::Machine do
end end
describe "attributes" do describe "attributes" do
it "should provide access to the name" do its(:name) { should eq(name) }
instance.name.should == name its(:config) { should eql(config) }
end its(:box) { should eql(box) }
its(:env) { should eql(env) }
it "should provide access to the configuration" do its(:provider) { should eql(provider) }
instance.config.should eql(config) its(:provider_config) { should eql(provider_config) }
end its(:provider_options) { should eq(provider_options) }
it "should provide access to the box" do
instance.box.should eql(box)
end
it "should provide access to the environment" do
instance.env.should eql(env)
end
it "should provide access to the provider" do
instance.provider.should eql(provider)
end
end end
describe "actions" do describe "actions" do

View File

@ -126,15 +126,15 @@ describe Vagrant::Plugin::V2::Manager do
end end
pB = plugin do |p| pB = plugin do |p|
p.provider("bar") { "baz" } p.provider("bar", foo: "bar") { "baz" }
end end
instance.register(pA) instance.register(pA)
instance.register(pB) instance.register(pB)
instance.providers.to_hash.length.should == 2 instance.providers.to_hash.length.should == 2
instance.providers[:foo].should == "bar" instance.providers[:foo].should == ["bar", {}]
instance.providers[:bar].should == "baz" instance.providers[:bar].should == ["baz", { foo: "bar" }]
end end
it "provides the collection of registered provider configs" do it "provides the collection of registered provider configs" do

View File

@ -210,7 +210,15 @@ describe Vagrant::Plugin::V2::Plugin do
provider("foo") { "bar" } provider("foo") { "bar" }
end end
plugin.provider[:foo].should == "bar" plugin.components.providers[:foo].should == ["bar", {}]
end
it "should register provider classes with options" do
plugin = Class.new(described_class) do
provider("foo", foo: "yep") { "bar" }
end
plugin.components.providers[:foo].should == ["bar", { foo: "yep" }]
end end
it "should lazily register provider classes" do it "should lazily register provider classes" do
@ -227,7 +235,7 @@ describe Vagrant::Plugin::V2::Plugin do
# Now verify when we actually get the configuration key that # Now verify when we actually get the configuration key that
# a proper error is raised. # a proper error is raised.
expect { expect {
plugin.provider[:foo] plugin.components.providers[:foo]
}.to raise_error(StandardError) }.to raise_error(StandardError)
end end
end end