Guest#capability to execute capabilities

This commit is contained in:
Mitchell Hashimoto 2013-04-03 22:19:20 -07:00
parent 06a9968ec4
commit cf3c1b73d2
4 changed files with 91 additions and 6 deletions

View File

@ -227,6 +227,14 @@ module Vagrant
error_key(:port_collision_resume)
end
class GuestCapabilityInvalid < VagrantError
error_key(:guest_capability_invalid)
end
class GuestCapabilityNotFound < VagrantError
error_key(:guest_capability_not_found)
end
class GuestNotDetected < VagrantError
error_key(:guest_not_detected)
end

View File

@ -104,12 +104,30 @@ module Vagrant
#
# @return [Boolean]
def capability?(cap_name)
@chain.each do |guest_name, guest|
caps = @capabilities[guest_name]
return true if caps && caps.has_key?(cap_name)
!capability_module(cap_name).nil?
end
# Executes the capability with the given name, optionally passing
# more arguments onwards to the capability.
def capability(cap_name)
@logger.info("Execute capability: #{cap_name} (#{@chain[0][0]})")
cap_mod = capability_module(cap_name)
if !cap_mod
raise Errors::GuestCapabilityNotFound,
:cap => cap_name.to_s,
:guest => @chain[0][0].to_s
end
false
cap_method = nil
begin
cap_method = cap_mod.method(cap_name)
rescue NameError
raise Errors::GuestCapabilityInvalid,
:cap => cap_name.to_s,
:guest => @chain[0][0].to_s
end
cap_method.call
end
# This returns whether the guest is ready to work. If this returns
@ -120,5 +138,20 @@ module Vagrant
def ready?
!@chain.empty?
end
protected
# Returns the registered module for a capability with the given name.
#
# @param [Symbol] cap_name
# @return [Module]
def capability_module(cap_name)
@chain.each do |guest_name, guest|
caps = @capabilities[guest_name]
return caps[cap_name] if caps && caps.has_key?(cap_name)
end
nil
end
end
end

View File

@ -173,6 +173,17 @@ en:
of the official installers or another gem is wrongly attempting to
use Vagrant internals directly. Please properly install Vagrant to
fix this. If this error persists, please contact support.
guest_capability_invalid: |-
The registered guest capability '%{cap}' for the
detected guest OS '%{guest}' is invalid. The capability does
not implement the proper method. This is a bug with Vagrant or the
plugin that implements this capability. Please report a bug.
guest_capability_not_found: |-
Vagrant attempted to execute the capability '%{cap}'
on the detect guest OS '%{guest}', but the guest doesn't
support that capability. This capability is required for your
configuration of Vagrant. Please either reconfigure Vagrant to
avoid this capability or fix the issue by creating the capability.
guest_not_detected: |-
The guest operating system of the machine could not be detected!
Vagrant requires this knowledge to perform specific tasks such

View File

@ -12,9 +12,14 @@ describe Vagrant::Guest do
subject { described_class.new(machine, guests, capabilities) }
# This registers a capability with a specific guest
def register_capability(guest, capability)
def register_capability(guest, capability, options=nil)
options ||= {}
cap = Class.new do
define_method(capability) do
if !options[:corrupt]
define_method(capability) do
raise "cap: #{capability}"
end
end
end
@ -41,6 +46,34 @@ describe Vagrant::Guest do
guests[name] = [guest, parent]
end
describe "#capability" do
before :each do
register_guest(:foo, nil, true)
register_guest(:bar, :foo, true)
subject.detect!
end
it "executes the capability" do
register_capability(:bar, :test)
expect { subject.capability(:test) }.
to raise_error(RuntimeError, "cap: test")
end
it "raises an exception if the capability doesn't exist" do
expect { subject.capability(:what_is_this_i_dont_even) }.
to raise_error(Vagrant::Errors::GuestCapabilityNotFound)
end
it "raises an exception if the method doesn't exist on the module" do
register_capability(:bar, :test_is_corrupt, corrupt: true)
expect { subject.capability(:test_is_corrupt) }.
to raise_error(Vagrant::Errors::GuestCapabilityInvalid)
end
end
describe "#capability?" do
before :each do
register_guest(:foo, nil, true)