Properly resolve and load the guest class impl for Machines
This commit is contained in:
parent
28f341ec75
commit
f9752d78d8
|
@ -129,8 +129,21 @@ module Vagrant
|
|||
#
|
||||
# @return [Object]
|
||||
def guest
|
||||
raise Errors::MachineGuestNotReady if !communicator.ready?
|
||||
# XXX: Todo
|
||||
raise Errors::MachineGuestNotReady if !communicate.ready?
|
||||
|
||||
# Load the initial guest.
|
||||
guest = load_guest(config.vm.guest)
|
||||
|
||||
# Loop and distro dispatch while there are distros.
|
||||
while true
|
||||
distro = guest.distro_dispatch
|
||||
break if !distro
|
||||
|
||||
guest = load_guest(distro)
|
||||
end
|
||||
|
||||
# Return the result
|
||||
guest
|
||||
end
|
||||
|
||||
# This sets the unique ID associated with this machine. This will
|
||||
|
@ -230,5 +243,32 @@ module Vagrant
|
|||
def state
|
||||
@provider.state
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Given a guest name (such as `:windows`), this will load the associated
|
||||
# guest implementation and return an instance.
|
||||
#
|
||||
# @param [Symbol] guest The name of the guest implementation.
|
||||
# @return [Object]
|
||||
def load_guest(guest)
|
||||
@logger.info("Loading guest: #{guest}")
|
||||
|
||||
klass = nil
|
||||
Vagrant.plugin("1").registered.each do |plugin|
|
||||
if plugin.guest.has_key?(guest)
|
||||
klass = plugin.guest[guest]
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if klass.nil?
|
||||
raise Errors::VMGuestError,
|
||||
:_key => :unknown_type,
|
||||
:guest => guest.to_s
|
||||
end
|
||||
|
||||
return klass.new(self)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -27,9 +27,8 @@ module Vagrant
|
|||
# Vagrant can successfully SSH into the machine) to give the system a chance
|
||||
# to determine the distro and return a distro-specific system.
|
||||
#
|
||||
# **Warning:** If a return value which subclasses from {Base} is
|
||||
# returned, Vagrant will use it as the new system instance for the
|
||||
# class.
|
||||
# If this method returns nil, then this instance is assumed to be
|
||||
# the most specific guest implementation.
|
||||
def distro_dispatch
|
||||
end
|
||||
|
||||
|
|
|
@ -13,13 +13,13 @@ module VagrantPlugins
|
|||
# attempt a graceful shutdown
|
||||
if current_state == :running && !env["force"]
|
||||
env[:ui].info I18n.t("vagrant.actions.vm.halt.graceful")
|
||||
env[:vm].guest.halt
|
||||
env[:machine].guest.halt
|
||||
end
|
||||
|
||||
# If we're not powered off now, then force it
|
||||
if env[:vm].state != :poweroff
|
||||
if env[:machine].state != :poweroff
|
||||
env[:ui].info I18n.t("vagrant.actions.vm.halt.force")
|
||||
env[:vm].driver.halt
|
||||
env[:machine].driver.halt
|
||||
end
|
||||
|
||||
# Sleep for a second to verify that the VM properly
|
||||
|
|
|
@ -5,11 +5,23 @@ require "unit/support/isolated_environment"
|
|||
|
||||
shared_context "unit" do
|
||||
before(:each) do
|
||||
# State to store the list of registered plugins that we have to
|
||||
# unregister later.
|
||||
@_plugins = []
|
||||
|
||||
# Create a thing to store our temporary files so that they aren't
|
||||
# unlinked right away.
|
||||
@_temp_files = []
|
||||
end
|
||||
|
||||
after(:each) do
|
||||
# Unregister each of the plugins we have may have temporarily
|
||||
# registered for the duration of this test.
|
||||
@_plugins.each do |plugin|
|
||||
plugin.unregister!
|
||||
end
|
||||
end
|
||||
|
||||
# This creates an isolated environment so that Vagrant doesn't
|
||||
# muck around with your real system during unit tests.
|
||||
#
|
||||
|
@ -22,6 +34,20 @@ shared_context "unit" do
|
|||
env
|
||||
end
|
||||
|
||||
# This registers a Vagrant plugin for the duration of a single test.
|
||||
# This will yield a new plugin class that you can then call the
|
||||
# public plugin methods on.
|
||||
#
|
||||
# @yield [plugin] Yields the plugin class for you to call the public
|
||||
# API that you need to.
|
||||
def register_plugin
|
||||
plugin = Class.new(Vagrant.plugin("1"))
|
||||
plugin.name("Test Plugin #{plugin.inspect}")
|
||||
yield plugin if block_given?
|
||||
@_plugins << plugin
|
||||
plugin
|
||||
end
|
||||
|
||||
# This helper creates a temporary file and returns a Pathname
|
||||
# object pointed to it.
|
||||
#
|
||||
|
|
|
@ -199,7 +199,7 @@ describe Vagrant::Machine do
|
|||
end
|
||||
|
||||
before(:each) do
|
||||
instance.stub(:communicator).and_return(communicator)
|
||||
instance.stub(:communicate).and_return(communicator)
|
||||
end
|
||||
|
||||
it "should raise an exception if communication is not ready" do
|
||||
|
@ -208,6 +208,47 @@ describe Vagrant::Machine do
|
|||
expect { instance.guest }.
|
||||
to raise_error(Vagrant::Errors::MachineGuestNotReady)
|
||||
end
|
||||
|
||||
it "should return the configured guest" do
|
||||
test_guest = Class.new(Vagrant.plugin("1", :guest))
|
||||
|
||||
register_plugin do |p|
|
||||
p.guest(:test) { test_guest }
|
||||
end
|
||||
|
||||
config.vm.guest = :test
|
||||
|
||||
result = instance.guest
|
||||
result.should be_kind_of(test_guest)
|
||||
end
|
||||
|
||||
it "should raise an exception if it can't find the configured guest" do
|
||||
config.vm.guest = :bad
|
||||
|
||||
expect { instance.guest }.
|
||||
to raise_error(Vagrant::Errors::VMGuestError)
|
||||
end
|
||||
|
||||
it "should distro dispatch to the most specific guest" do
|
||||
# Create the classes and dispatch the parent into the child
|
||||
guest_parent = Class.new(Vagrant.plugin("1", :guest)) do
|
||||
def distro_dispatch
|
||||
:child
|
||||
end
|
||||
end
|
||||
|
||||
guest_child = Class.new(Vagrant.plugin("1", :guest))
|
||||
|
||||
# Register the classes
|
||||
register_plugin do |p|
|
||||
p.guest(:parent) { guest_parent }
|
||||
p.guest(:child) { guest_child }
|
||||
end
|
||||
|
||||
# Test that the result is the child
|
||||
config.vm.guest = :parent
|
||||
instance.guest.should be_kind_of(guest_child)
|
||||
end
|
||||
end
|
||||
|
||||
describe "setting the ID" do
|
||||
|
|
Loading…
Reference in New Issue