diff --git a/lib/vagrant/machine.rb b/lib/vagrant/machine.rb index 0b12580b1..8d6e93761 100644 --- a/lib/vagrant/machine.rb +++ b/lib/vagrant/machine.rb @@ -83,7 +83,10 @@ module Vagrant @config = config @data_dir = data_dir @env = env - @guest = Guest.new(self) + @guest = Guest.new( + self, + Vagrant.plugin("2").manager.guests, + Vagrant.plugin("2").manager.guest_capabilities) @name = name @provider_config = provider_config @provider_name = provider_name @@ -170,6 +173,7 @@ module Vagrant # @return [Object] def guest raise Errors::MachineGuestNotReady if !communicate.ready? + @guest.detect! if !@guest.ready? @guest end diff --git a/lib/vagrant/plugin/v2/components.rb b/lib/vagrant/plugin/v2/components.rb index 636f7ae6c..6b585d071 100644 --- a/lib/vagrant/plugin/v2/components.rb +++ b/lib/vagrant/plugin/v2/components.rb @@ -21,6 +21,11 @@ module Vagrant # @return [Registry>] attr_reader :guests + # This contains all the registered guest capabilities. + # + # @return [Hash] + attr_reader :guest_capabilities + # This contains all the provider plugins by name, and returns # the provider class and options. # @@ -33,6 +38,7 @@ module Vagrant @configs = Hash.new { |h, k| h[k] = Registry.new } @guests = Registry.new + @guest_capabilities = Hash.new { |h, k| h[k] = Registry.new } @providers = Registry.new end end diff --git a/lib/vagrant/plugin/v2/manager.rb b/lib/vagrant/plugin/v2/manager.rb index 887bd5c0e..b6e79e427 100644 --- a/lib/vagrant/plugin/v2/manager.rb +++ b/lib/vagrant/plugin/v2/manager.rb @@ -72,6 +72,21 @@ module Vagrant end end + # This returns all the registered guest capabilities. + # + # @return [Hash] + def guest_capabilities + results = Hash.new { |h, k| h[k] = Registry.new } + + @registered.each do |plugin| + plugin.components.guest_capabilities.each do |guest, caps| + results[guest].merge!(caps) + end + end + + results + end + # This returns all registered host classes. # # @return [Hash] diff --git a/lib/vagrant/plugin/v2/plugin.rb b/lib/vagrant/plugin/v2/plugin.rb index 0480631fc..e66da1b8b 100644 --- a/lib/vagrant/plugin/v2/plugin.rb +++ b/lib/vagrant/plugin/v2/plugin.rb @@ -144,6 +144,18 @@ module Vagrant nil end + # Defines a capability for the given guest. 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] guest The name of the guest + # @param [String] cap The name of the capability + def self.guest_capability(guest, cap, &block) + components.guest_capabilities[guest.to_sym].register(cap.to_sym, &block) + nil + end + # Defines an additionally available host implementation with # the given key. # diff --git a/test/unit/vagrant/machine_test.rb b/test/unit/vagrant/machine_test.rb index 74cdb51c1..287b49447 100644 --- a/test/unit/vagrant/machine_test.rb +++ b/test/unit/vagrant/machine_test.rb @@ -202,6 +202,16 @@ describe Vagrant::Machine do end before(:each) do + test_guest = Class.new(Vagrant.plugin("2", :guest)) do + def detect?(machine) + true + end + end + + register_plugin do |p| + p.guest(:test) { test_guest } + end + instance.stub(:communicate).and_return(communicator) end @@ -213,18 +223,10 @@ describe Vagrant::Machine do end it "should return the configured guest" do - test_guest = Class.new(Vagrant.plugin("2", :guest)) do - def detect?(machine) - true - end - end - - register_plugin do |p| - p.guest(:test) { test_guest } - end - result = instance.guest - result.should be_kind_of(test_guest) + result.should be_kind_of(Vagrant::Guest) + result.ready?.should be + result.chain[0][0].should == :test end end diff --git a/test/unit/vagrant/plugin/v2/manager_test.rb b/test/unit/vagrant/plugin/v2/manager_test.rb index 7ed9d751e..d669a05f1 100644 --- a/test/unit/vagrant/plugin/v2/manager_test.rb +++ b/test/unit/vagrant/plugin/v2/manager_test.rb @@ -92,15 +92,15 @@ describe Vagrant::Plugin::V2::Manager do end pB = plugin do |p| - p.guest("bar") { "baz" } + p.guest("bar", "foo") { "baz" } end instance.register(pA) instance.register(pB) instance.guests.to_hash.length.should == 2 - instance.guests[:foo].should == "bar" - instance.guests[:bar].should == "baz" + instance.guests[:foo].should == ["bar", nil] + instance.guests[:bar].should == ["baz", :foo] end it "should enumerate registered host classes" do diff --git a/test/unit/vagrant/plugin/v2/plugin_test.rb b/test/unit/vagrant/plugin/v2/plugin_test.rb index 7e0b88d84..c00a8d9ca 100644 --- a/test/unit/vagrant/plugin/v2/plugin_test.rb +++ b/test/unit/vagrant/plugin/v2/plugin_test.rb @@ -154,7 +154,7 @@ describe Vagrant::Plugin::V2::Plugin do guest("foo") { "bar" } end - plugin.guest[:foo].should == "bar" + plugin.components.guests[:foo].should == ["bar", nil] end it "should lazily register guest classes" do