Laying the foundation for the new guest plugin
This commit is contained in:
parent
4ffc2c3b74
commit
52f3847b0a
|
@ -227,6 +227,10 @@ module Vagrant
|
|||
error_key(:port_collision_resume)
|
||||
end
|
||||
|
||||
class GuestNotDetected < VagrantError
|
||||
error_key(:guest_not_detected)
|
||||
end
|
||||
|
||||
class LocalDataDirectoryNotAccessible < VagrantError
|
||||
error_key(:local_data_dir_not_accessible)
|
||||
end
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
require "log4r"
|
||||
|
||||
module Vagrant
|
||||
# This class handles guest-OS specific interactions with a machine.
|
||||
# It is primarily responsible for detecting the proper guest OS
|
||||
# implementation and then delegating capabilities.
|
||||
#
|
||||
# Vagrant has many tasks which require specific guest OS knowledge.
|
||||
# These are implemented using a guest/capability system. Various plugins
|
||||
# register as "guests" which determine the underlying OS of the system.
|
||||
# Then, "guest capabilities" register themselves for a specific OS (one
|
||||
# or more), and these capabilities are called.
|
||||
#
|
||||
# Example capabilities might be "mount_virtualbox_shared_folder" or
|
||||
# "configure_networks".
|
||||
#
|
||||
# This system allows for maximum flexibility and pluginability for doing
|
||||
# guest OS specific operations.
|
||||
class Guest
|
||||
attr_reader :chain
|
||||
|
||||
def initialize(machine, guests)
|
||||
@logger = Log4r::Logger.new("vagrant::guest")
|
||||
@chain = []
|
||||
@guests = guests
|
||||
@machine = machine
|
||||
end
|
||||
|
||||
# This will detect the proper guest OS for the machine and set up
|
||||
# the class to actually execute capabilities.
|
||||
def detect!
|
||||
@logger.info("Detect guest for machine: #{@machine}")
|
||||
|
||||
# Get the mapping of guests with the most parents. We start searching
|
||||
# with the guests with the most parents first.
|
||||
parent_count = {}
|
||||
@guests.each do |name, parts|
|
||||
parent_count[name] = 0
|
||||
|
||||
parent = parts[1]
|
||||
while parent
|
||||
parent_count[name] += 1
|
||||
parent = @guests[parent]
|
||||
parent = parent[1] if parent
|
||||
end
|
||||
end
|
||||
|
||||
# Now swap around the mapping so that it is a mapping of
|
||||
# count to the actual list of guest names
|
||||
parent_count_to_guests = {}
|
||||
parent_count.each do |name, count|
|
||||
parent_count_to_guests[count] ||= []
|
||||
parent_count_to_guests[count] << name
|
||||
end
|
||||
|
||||
catch(:guest_os) do
|
||||
sorted_counts = parent_count_to_guests.keys.sort.reverse
|
||||
sorted_counts.each do |count|
|
||||
parent_count_to_guests[count].each do |name|
|
||||
@logger.debug("Trying: #{name}")
|
||||
guest_info = @guests[name]
|
||||
guest = guest_info[0].new
|
||||
|
||||
if guest.detect?(@machine)
|
||||
@logger.info("Detected: #{name}!")
|
||||
@chain << guest
|
||||
|
||||
# Build the proper chain of parents if there are any.
|
||||
# This allows us to do "inheritence" of capabilities later
|
||||
if guest_info[1]
|
||||
parent_info = @guests[guest_info[1]]
|
||||
while parent_info
|
||||
@chain << parent_info[0].new
|
||||
parent_info = @guests[parent_info[1]]
|
||||
end
|
||||
end
|
||||
|
||||
@logger.info("Full guest chain: #{@chain.inspect}")
|
||||
|
||||
# Exit the search
|
||||
throw :guest_os
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# We shouldn't reach this point. Ideally we would detect
|
||||
# all operating systems.
|
||||
raise Errors::GuestNotDetected if @chain.empty?
|
||||
end
|
||||
|
||||
# This returns whether the guest is ready to work. If this returns
|
||||
# `false`, then {#detect!} should be called in order to detect the
|
||||
# guest OS.
|
||||
#
|
||||
# @return [Boolean]
|
||||
def ready?
|
||||
!@chain.empty?
|
||||
end
|
||||
end
|
||||
end
|
|
@ -83,6 +83,7 @@ module Vagrant
|
|||
@config = config
|
||||
@data_dir = data_dir
|
||||
@env = env
|
||||
@guest = Guest.new(self)
|
||||
@name = name
|
||||
@provider_config = provider_config
|
||||
@provider_name = provider_name
|
||||
|
@ -169,32 +170,7 @@ module Vagrant
|
|||
# @return [Object]
|
||||
def guest
|
||||
raise Errors::MachineGuestNotReady if !communicate.ready?
|
||||
|
||||
# Load the initial guest.
|
||||
last_guest = config.vm.guest
|
||||
guest = load_guest(last_guest)
|
||||
|
||||
# Loop and distro dispatch while there are distros.
|
||||
while true
|
||||
distro = guest.distro_dispatch
|
||||
break if !distro
|
||||
|
||||
# This is just some really basic loop detection and avoiding for
|
||||
# guest classes. This is just here to help implementers a bit
|
||||
# avoid a situation that is fairly easy, since if you subclass
|
||||
# a parent which does `distro_dispatch`, you'll end up dispatching
|
||||
# forever.
|
||||
if distro == last_guest
|
||||
@logger.warn("Distro dispatch loop in '#{distro}'. Exiting loop.")
|
||||
break
|
||||
end
|
||||
|
||||
last_guest = distro
|
||||
guest = load_guest(distro)
|
||||
end
|
||||
|
||||
# Return the result
|
||||
guest
|
||||
@guest
|
||||
end
|
||||
|
||||
# This sets the unique ID associated with this machine. This will
|
||||
|
|
|
@ -16,6 +16,11 @@ module Vagrant
|
|||
# @return [Hash<Symbol, Registry>]
|
||||
attr_reader :configs
|
||||
|
||||
# This contains all the guests and their parents.
|
||||
#
|
||||
# @return [Registry<Symbol, Array<Class, Symbol>>]
|
||||
attr_reader :guests
|
||||
|
||||
# This contains all the provider plugins by name, and returns
|
||||
# the provider class and options.
|
||||
#
|
||||
|
@ -27,6 +32,7 @@ module Vagrant
|
|||
@action_hooks = Hash.new { |h, k| h[k] = [] }
|
||||
|
||||
@configs = Hash.new { |h, k| h[k] = Registry.new }
|
||||
@guests = Registry.new
|
||||
@providers = Registry.new
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,35 +1,21 @@
|
|||
module Vagrant
|
||||
module Plugin
|
||||
module V2
|
||||
# The base class for a guest. A guest represents an installed system
|
||||
# within a machine that Vagrant manages. There are some portions of
|
||||
# Vagrant which are OS-specific such as mountaing shared folders and
|
||||
# halting the machine, and this abstraction allows the implementation
|
||||
# for these to be seperate from the core of Vagrant.
|
||||
# A base class for a guest OS. A guest OS is responsible for detecting
|
||||
# that the guest operating system running within the machine. The guest
|
||||
# can then be extended with various "guest capabilities" which are their
|
||||
# own form of plugin.
|
||||
#
|
||||
# The guest class itself is only responsible for detecting itself,
|
||||
# and may provide helpers for the capabilties.
|
||||
class Guest
|
||||
class BaseError < Errors::VagrantError
|
||||
error_namespace("vagrant.guest.base")
|
||||
end
|
||||
|
||||
include Vagrant::Util
|
||||
|
||||
# The VM which this system is tied to.
|
||||
attr_reader :vm
|
||||
|
||||
# Initializes the system. Any subclasses MUST make sure this
|
||||
# method is called on the parent. Therefore, if a subclass overrides
|
||||
# `initialize`, then you must call `super`.
|
||||
def initialize(vm)
|
||||
@vm = vm
|
||||
end
|
||||
|
||||
# This method is automatically called when the system is available (when
|
||||
# Vagrant can successfully SSH into the machine) to give the system a chance
|
||||
# to determine the distro and return a distro-specific system.
|
||||
# This method is called when the machine is booted and has communication
|
||||
# capabilities in order to detect whether this guest operating system
|
||||
# is running within the machine.
|
||||
#
|
||||
# If this method returns nil, then this instance is assumed to be
|
||||
# the most specific guest implementation.
|
||||
def distro_dispatch
|
||||
# @return [Boolean]
|
||||
def guest?(machine)
|
||||
false
|
||||
end
|
||||
|
||||
# Halt the machine. This method should gracefully shut down the
|
||||
|
|
|
@ -67,7 +67,7 @@ module Vagrant
|
|||
def guests
|
||||
Registry.new.tap do |result|
|
||||
@registered.each do |plugin|
|
||||
result.merge!(plugin.guest)
|
||||
result.merge!(plugin.components.guests)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -124,7 +124,6 @@ module Vagrant
|
|||
# without breaking anything in future versions of Vagrant.
|
||||
#
|
||||
# @param [String] name Configuration key.
|
||||
# XXX: Document options hash
|
||||
def self.config(name, scope=nil, &block)
|
||||
scope ||= :top
|
||||
components.configs[scope].register(name.to_sym, &block)
|
||||
|
@ -135,14 +134,14 @@ module Vagrant
|
|||
# the given key.
|
||||
#
|
||||
# @param [String] name Name of the guest.
|
||||
def self.guest(name=UNSET_VALUE, &block)
|
||||
data[:guests] ||= Registry.new
|
||||
# @param [String] parent Name of the parent guest (if any)
|
||||
def self.guest(name=UNSET_VALUE, parent=nil, &block)
|
||||
components.guests.register(name.to_sym) do
|
||||
parent = parent.to_sym if parent
|
||||
|
||||
# Register a new guest class only if a name was given
|
||||
data[:guests].register(name.to_sym, &block) if name != UNSET_VALUE
|
||||
|
||||
# Return the registry
|
||||
data[:guests]
|
||||
[block.call, parent]
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
# Defines an additionally available host implementation with
|
||||
|
|
|
@ -12,6 +12,10 @@ module VagrantPlugins
|
|||
# Make the TemplateRenderer top-level
|
||||
include Vagrant::Util
|
||||
|
||||
def detect?(machine)
|
||||
machine.communicate.test("cat /etc/arch-release")
|
||||
end
|
||||
|
||||
def change_host_name(name)
|
||||
# Only do this if the hostname is not already set
|
||||
if !vm.communicate.test("sudo hostname | grep '#{name}'")
|
||||
|
|
|
@ -6,7 +6,7 @@ module VagrantPlugins
|
|||
name "Arch guest"
|
||||
description "Arch guest support."
|
||||
|
||||
guest("arch") do
|
||||
guest("arch", "linux") do
|
||||
require File.expand_path("../guest", __FILE__)
|
||||
Guest
|
||||
end
|
||||
|
|
|
@ -12,6 +12,10 @@ module VagrantPlugins
|
|||
# Make the TemplateRenderer top-level
|
||||
include Vagrant::Util
|
||||
|
||||
def detect?(machine)
|
||||
machine.communicate.test("cat /proc/version | grep 'Debian'")
|
||||
end
|
||||
|
||||
def configure_networks(networks)
|
||||
# First, remove any previous network modifications
|
||||
# from the interface file.
|
||||
|
|
|
@ -6,7 +6,7 @@ module VagrantPlugins
|
|||
name "Debian guest"
|
||||
description "Debian guest support."
|
||||
|
||||
guest("debian") do
|
||||
guest("debian", "linux") do
|
||||
require File.expand_path("../guest", __FILE__)
|
||||
Guest
|
||||
end
|
||||
|
|
|
@ -12,6 +12,10 @@ module VagrantPlugins
|
|||
# Make the TemplateRenderer top-level
|
||||
include Vagrant::Util
|
||||
|
||||
def detect?(machine)
|
||||
machine.communicate.test("grep 'Fedora release 1[678]' /etc/redhat-release")
|
||||
end
|
||||
|
||||
def configure_networks(networks)
|
||||
# Accumulate the configurations to add to the interfaces file as well
|
||||
# as what interfaces we're actually configuring since we use that later.
|
||||
|
|
|
@ -6,7 +6,7 @@ module VagrantPlugins
|
|||
name "Fedora guest"
|
||||
description "Fedora guest support."
|
||||
|
||||
guest("fedora") do
|
||||
guest("fedora", "linux") do
|
||||
require File.expand_path("../guest", __FILE__)
|
||||
Guest
|
||||
end
|
||||
|
|
|
@ -11,6 +11,11 @@ module VagrantPlugins
|
|||
error_namespace("vagrant.guest.freebsd")
|
||||
end
|
||||
|
||||
def detect?(machine)
|
||||
# TODO: FreeBSD detection
|
||||
false
|
||||
end
|
||||
|
||||
def halt
|
||||
begin
|
||||
vm.communicate.sudo("shutdown -p now")
|
||||
|
|
|
@ -11,6 +11,10 @@ module VagrantPlugins
|
|||
# Make the TemplateRenderer top-level
|
||||
include Vagrant::Util
|
||||
|
||||
def detect?(machine)
|
||||
machine.communicate.test("cat /etc/gentoo-release")
|
||||
end
|
||||
|
||||
def configure_networks(networks)
|
||||
# Remove any previous host only network additions to the interface file
|
||||
vm.communicate.sudo("sed -e '/^#VAGRANT-BEGIN/,/^#VAGRANT-END/ d' /etc/conf.d/net > /tmp/vagrant-network-interfaces")
|
||||
|
|
|
@ -6,7 +6,7 @@ module VagrantPlugins
|
|||
name "Gentoo guest"
|
||||
description "Gentoo guest support."
|
||||
|
||||
guest("gentoo") do
|
||||
guest("gentoo", "linux") do
|
||||
require File.expand_path("../guest", __FILE__)
|
||||
Guest
|
||||
end
|
||||
|
|
|
@ -18,6 +18,11 @@ module VagrantPlugins
|
|||
@logger = Log4r::Logger.new("vagrant::guest::linux")
|
||||
end
|
||||
|
||||
def detect?(machine)
|
||||
# TODO: Linux detection
|
||||
false
|
||||
end
|
||||
|
||||
def distro_dispatch
|
||||
@vm.communicate.tap do |comm|
|
||||
if comm.test("cat /etc/debian_version")
|
||||
|
|
|
@ -5,6 +5,11 @@ require Vagrant.source_root.join("plugins/guests/linux/guest")
|
|||
module VagrantPlugins
|
||||
module GuestOpenBSD
|
||||
class Guest < VagrantPlugins::GuestLinux::Guest
|
||||
def detect?(machine)
|
||||
# TODO: OpenBSD detection
|
||||
false
|
||||
end
|
||||
|
||||
def halt
|
||||
vm.communicate.sudo("shutdown -p -h now")
|
||||
end
|
||||
|
|
|
@ -6,7 +6,7 @@ module VagrantPlugins
|
|||
name "OpenBSD guest"
|
||||
description "OpenBSD guest support."
|
||||
|
||||
guest("openbsd") do
|
||||
guest("openbsd", "linux") do
|
||||
require File.expand_path("../guest", __FILE__)
|
||||
Guest
|
||||
end
|
||||
|
|
|
@ -5,6 +5,10 @@ require Vagrant.source_root.join("plugins/guests/redhat/guest")
|
|||
module VagrantPlugins
|
||||
module GuestPld
|
||||
class Guest < VagrantPlugins::GuestRedHat::Guest
|
||||
def detect?(machine)
|
||||
machine.communicate.test("cat /etc/pld-release")
|
||||
end
|
||||
|
||||
def network_scripts_dir
|
||||
'/etc/sysconfig/interfaces/'
|
||||
end
|
||||
|
|
|
@ -6,7 +6,7 @@ module VagrantPlugins
|
|||
name "PLD Linux guest"
|
||||
description "PLD Linux guest support."
|
||||
|
||||
guest("pld") do
|
||||
guest("pld", "redhat") do
|
||||
require File.expand_path("../guest", __FILE__)
|
||||
Guest
|
||||
end
|
||||
|
|
|
@ -12,6 +12,10 @@ module VagrantPlugins
|
|||
# Make the TemplateRenderer top-level
|
||||
include Vagrant::Util
|
||||
|
||||
def detect?(machine)
|
||||
machine.communicate.test("cat /etc/redhat-release")
|
||||
end
|
||||
|
||||
def configure_networks(networks)
|
||||
# Accumulate the configurations to add to the interfaces file as
|
||||
# well as what interfaces we're actually configuring since we use that
|
||||
|
|
|
@ -6,7 +6,7 @@ module VagrantPlugins
|
|||
name "RedHat guest"
|
||||
description "RedHat guest support."
|
||||
|
||||
guest("redhat") do
|
||||
guest("redhat", "linux") do
|
||||
require File.expand_path("../guest", __FILE__)
|
||||
Guest
|
||||
end
|
||||
|
|
|
@ -11,6 +11,10 @@ module VagrantPlugins
|
|||
error_namespace("vagrant.guest.solaris")
|
||||
end
|
||||
|
||||
def detect?(machine)
|
||||
machine.communicate.test("grep 'Solaris' /etc/release")
|
||||
end
|
||||
|
||||
def configure_networks(networks)
|
||||
networks.each do |network|
|
||||
device = "#{vm.config.solaris.device}#{network[:interface]}"
|
||||
|
|
|
@ -5,6 +5,10 @@ require Vagrant.source_root.join("plugins/guests/redhat/guest")
|
|||
module VagrantPlugins
|
||||
module GuestSuse
|
||||
class Guest < VagrantPlugins::GuestRedHat::Guest
|
||||
def detect?(machine)
|
||||
machine.communicate.test("cat /etc/SuSE-release")
|
||||
end
|
||||
|
||||
def network_scripts_dir
|
||||
'/etc/sysconfig/network/'
|
||||
end
|
||||
|
|
|
@ -6,7 +6,7 @@ module VagrantPlugins
|
|||
name "SUSE guest"
|
||||
description "SUSE guest support."
|
||||
|
||||
guest("suse") do
|
||||
guest("suse", "redhat") do
|
||||
require File.expand_path("../guest", __FILE__)
|
||||
Guest
|
||||
end
|
||||
|
|
|
@ -5,6 +5,10 @@ require Vagrant.source_root.join("plugins/guests/debian/guest")
|
|||
module VagrantPlugins
|
||||
module GuestUbuntu
|
||||
class Guest < VagrantPlugins::GuestDebian::Guest
|
||||
def detect?(machine)
|
||||
machine.communicate.test("cat /proc/version | grep 'Ubuntu'")
|
||||
end
|
||||
|
||||
def mount_shared_folder(name, guestpath, options)
|
||||
# Mount it like normal
|
||||
super
|
||||
|
|
|
@ -6,7 +6,7 @@ module VagrantPlugins
|
|||
name "Ubuntu guest"
|
||||
description "Ubuntu guest support."
|
||||
|
||||
guest("ubuntu") do
|
||||
guest("ubuntu", "debian") do
|
||||
require File.expand_path("../guest", __FILE__)
|
||||
Guest
|
||||
end
|
||||
|
|
|
@ -173,18 +173,12 @@ 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:
|
||||
invalid_class: |-
|
||||
The specified guest class does not inherit from a proper guest
|
||||
component class. The guest class must inherit from this.
|
||||
|
||||
The specified guest class was: %{guest}
|
||||
unknown_type: |-
|
||||
The specified guest type is unknown: %{guest}. Please change this
|
||||
to a proper value.
|
||||
unspecified: |-
|
||||
A VM guest type must be specified! This is done via the `config.vm.guest`
|
||||
configuration value. Please read the documentation online for more information.
|
||||
guest_not_detected: |-
|
||||
The guest operating system of the machine could not be detected!
|
||||
Vagrant requires this knowledge to perform specific tasks such
|
||||
as mounting shared folders and configuring networks. Please add
|
||||
the ability to detect this guest operating system to Vagrant
|
||||
by creating a plugin or reporting a bug.
|
||||
home_dir_not_accessible: |-
|
||||
The home directory you specified is not accessible. The home
|
||||
directory that Vagrant uses must be both readable and writable.
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
require "pathname"
|
||||
|
||||
require File.expand_path("../../base", __FILE__)
|
||||
|
||||
describe Vagrant::Guest do
|
||||
include_context "unit"
|
||||
|
||||
let(:guests) { {} }
|
||||
let(:machine) { double("machine") }
|
||||
|
||||
subject { described_class.new(machine, guests) }
|
||||
|
||||
# This registers a guest with the class.
|
||||
#
|
||||
# @param [Symbol] name Name of the guest
|
||||
# @param [Symbol] parent Name of the parent
|
||||
# @param [Boolean] detect Whether or not to detect properly
|
||||
def register_guest(name, parent, detect)
|
||||
guest = Class.new(Vagrant.plugin("2", "guest")) do
|
||||
define_method(:name) do
|
||||
name
|
||||
end
|
||||
|
||||
define_method(:detect?) do |m|
|
||||
detect
|
||||
end
|
||||
end
|
||||
|
||||
guests[name] = [guest, parent]
|
||||
end
|
||||
|
||||
describe "#detect!" do
|
||||
it "detects the first match" do
|
||||
register_guest(:foo, nil, false)
|
||||
register_guest(:bar, nil, true)
|
||||
register_guest(:baz, nil, false)
|
||||
|
||||
subject.detect!
|
||||
subject.chain.length.should == 1
|
||||
subject.chain[0].name.should == :bar
|
||||
end
|
||||
|
||||
it "detects those with the most parents first" do
|
||||
register_guest(:foo, nil, true)
|
||||
register_guest(:bar, :foo, true)
|
||||
register_guest(:baz, :bar, true)
|
||||
register_guest(:foo2, nil, true)
|
||||
register_guest(:bar2, :foo2, true)
|
||||
|
||||
subject.detect!
|
||||
subject.chain.length.should == 3
|
||||
subject.chain.map(&:name).should == [:baz, :bar, :foo]
|
||||
end
|
||||
|
||||
it "raises an exception if no guest can be detected" do
|
||||
expect { subject.detect! }.
|
||||
to raise_error(Vagrant::Errors::GuestNotDetected)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#ready?" do
|
||||
before(:each) do
|
||||
register_guest(:foo, nil, true)
|
||||
end
|
||||
|
||||
it "should not be ready by default" do
|
||||
subject.ready?.should_not be
|
||||
end
|
||||
|
||||
it "should be ready after detecting" do
|
||||
subject.detect!
|
||||
subject.ready?.should be
|
||||
end
|
||||
end
|
||||
end
|
|
@ -197,6 +197,7 @@ describe Vagrant::Machine do
|
|||
let(:communicator) do
|
||||
result = double("communicator")
|
||||
result.stub(:ready?).and_return(true)
|
||||
result.stub(:test).and_return(false)
|
||||
result
|
||||
end
|
||||
|
||||
|
@ -212,63 +213,19 @@ describe Vagrant::Machine do
|
|||
end
|
||||
|
||||
it "should return the configured guest" do
|
||||
test_guest = Class.new(Vagrant.plugin("2", :guest))
|
||||
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
|
||||
|
||||
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("2", :guest)) do
|
||||
def distro_dispatch
|
||||
:child
|
||||
end
|
||||
end
|
||||
|
||||
guest_child = Class.new(Vagrant.plugin("2", :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
|
||||
|
||||
it "should protect against loops in the distro dispatch" do
|
||||
# Create the classes and dispatch the parent into the child
|
||||
guest_parent = Class.new(Vagrant.plugin("2", :guest)) do
|
||||
def distro_dispatch
|
||||
:parent
|
||||
end
|
||||
end
|
||||
|
||||
# Register the classes
|
||||
register_plugin do |p|
|
||||
p.guest(:parent) { guest_parent }
|
||||
end
|
||||
|
||||
# Test that the result is the child
|
||||
config.vm.guest = :parent
|
||||
instance.guest.should be_kind_of(guest_parent)
|
||||
end
|
||||
end
|
||||
|
||||
describe "setting the ID" do
|
||||
|
|
Loading…
Reference in New Issue