Merge pull request #2896 from mitchellh/f-provider-caps

Provider Capabilities
This commit is contained in:
Mitchell Hashimoto 2014-01-26 14:37:15 -08:00
commit 6cd79d67da
8 changed files with 116 additions and 4 deletions

View File

@ -114,6 +114,7 @@ module Vagrant
# Initializes the provider last so that it has access to all the
# state we setup on this machine.
@provider = provider_cls.new(self)
@provider._initialize(@provider_name, self)
end
# This calls an action on the provider. The provider may or may not

View File

@ -49,6 +49,11 @@ module Vagrant
# @return [Hash<Symbol, Registry>]
attr_reader :providers
# This contains all the registered provider capabilities.
#
# @return [Hash<Symbol, Registry>]
attr_reader :provider_capabilities
# This contains all the synced folder implementations by name.
#
# @return [Registry<Symbol, Array<Class, Integer>>]
@ -65,6 +70,7 @@ module Vagrant
@hosts = Registry.new
@host_capabilities = Hash.new { |h, k| h[k] = Registry.new }
@providers = Registry.new
@provider_capabilities = Hash.new { |h, k| h[k] = Registry.new }
@synced_folders = Registry.new
end
end

View File

@ -113,7 +113,6 @@ module Vagrant
results
end
# This returns all registered providers.
#
# @return [Hash]
@ -125,6 +124,21 @@ module Vagrant
end
end
# This returns all the registered provider capabilities.
#
# @return [Hash]
def provider_capabilities
results = Hash.new { |h, k| h[k] = Registry.new }
@registered.each do |plugin|
plugin.components.provider_capabilities.each do |provider, caps|
results[provider].merge!(caps)
end
end
results
end
# This returns all the config classes for the various providers.
#
# @return [Hash]

View File

@ -193,6 +193,18 @@ module Vagrant
nil
end
# Defines a capability for the given provider. The block should return
# a class/module that has a method with the capability name, ready
# to be executed. This means that if it is an instance method,
# the block should return an instance of the class.
#
# @param [String] provider The name of the provider
# @param [String] cap The name of the capability
def self.provider_capability(provider, cap, &block)
components.provider_capabilities[provider.to_sym].register(cap.to_sym, &block)
nil
end
# Registers additional provisioners to be available.
#
# @param [String] name Name of the provisioner.

View File

@ -1,3 +1,5 @@
require "vagrant/capability_host"
module Vagrant
module Plugin
module V2
@ -5,6 +7,8 @@ module Vagrant
# is responsible for creating compute resources to match the needs
# of a Vagrant-configured system.
class Provider
include CapabilityHost
# Initialize the provider to represent the given machine.
#
# @param [Vagrant::Machine] machine The machine that this provider
@ -63,6 +67,18 @@ module Vagrant
def state
nil
end
# This is an internal initialize function that should never be
# overridden. It is used to initialize some common internal state
# that is used in a provider.
def _initialize(name, machine)
initialize_capabilities!(
name.to_sym,
{ name.to_sym => [Class.new, nil] },
Vagrant.plugin("2").manager.provider_capabilities,
machine,
)
end
end
end
end

View File

@ -7,7 +7,11 @@ describe Vagrant::Machine do
include_context "unit"
let(:name) { "foo" }
let(:provider) { double("provider") }
let(:provider) do
double("provider").tap do |obj|
obj.stub(:_initialize => nil)
end
end
let(:provider_cls) do
obj = double("provider_cls")
obj.stub(:new => provider)
@ -48,9 +52,14 @@ describe Vagrant::Machine do
#
# @yield [machine] Yields the machine that the provider initialization
# method received so you can run additional tests on it.
def provider_init_test
def provider_init_test(instance=nil)
received_machine = nil
if !instance
instance = double("instance")
instance.stub(:_initialize => nil)
end
provider_cls = double("provider_cls")
provider_cls.should_receive(:new) do |machine|
# Store this for later so we can verify that it is the
@ -62,7 +71,8 @@ describe Vagrant::Machine do
# Yield our machine if we want to do additional tests
yield machine if block_given?
end
true
end.and_return(instance)
# Initialize a new machine and verify that we properly receive
# the machine we expect.
@ -117,6 +127,17 @@ describe Vagrant::Machine do
machine.provider.should be_nil
end
end
it "should initialize the capabilities" do
instance = double("instance")
instance.should_receive(:_initialize).with do |p, m|
expect(p).to eq(provider_name)
expect(m.name).to eq(name)
true
end
provider_init_test(instance)
end
end
end

View File

@ -281,6 +281,16 @@ describe Vagrant::Plugin::V2::Plugin do
end
end
describe "provider capabilities" do
it "should register host capabilities" do
plugin = Class.new(described_class) do
provider_capability("foo", "bar") { "baz" }
end
plugin.components.provider_capabilities[:foo][:bar].should == "baz"
end
end
describe "provisioners" do
it "should register provisioner classes" do
plugin = Class.new(described_class) do

View File

@ -1,9 +1,13 @@
require File.expand_path("../../../../base", __FILE__)
describe Vagrant::Plugin::V2::Provider do
include_context "unit"
let(:machine) { Object.new }
let(:instance) { described_class.new(machine) }
subject { instance }
it "should return nil by default for actions" do
instance.action(:whatever).should be_nil
end
@ -15,4 +19,32 @@ describe Vagrant::Plugin::V2::Provider do
it "should return nil by default for state" do
instance.state.should be_nil
end
context "capabilities" do
before do
register_plugin("2") do |p|
p.provider_capability("bar", "foo") {}
p.provider_capability("foo", "bar") do
Class.new do
def self.bar(machine)
raise "bar #{machine.id}"
end
end
end
end
machine.stub(id: "YEAH")
instance._initialize("foo", machine)
end
it "can execute capabilities" do
expect(subject.capability?(:foo)).to be_false
expect(subject.capability?(:bar)).to be_true
expect { subject.capability(:bar) }.
to raise_error("bar YEAH")
end
end
end