Add basic loop detection for distro_dispatch

This commit is contained in:
Mitchell Hashimoto 2012-08-12 19:03:22 -07:00
parent 0eddda3552
commit 296878cff5
2 changed files with 32 additions and 2 deletions

View File

@ -132,13 +132,25 @@ module Vagrant
raise Errors::MachineGuestNotReady if !communicate.ready? raise Errors::MachineGuestNotReady if !communicate.ready?
# Load the initial guest. # Load the initial guest.
guest = load_guest(config.vm.guest) last_guest = config.vm.guest
guest = load_guest(last_guest)
# Loop and distro dispatch while there are distros. # Loop and distro dispatch while there are distros.
while true while true
distro = guest.distro_dispatch distro = guest.distro_dispatch
break if !distro 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) guest = load_guest(distro)
end end

View File

@ -249,6 +249,24 @@ describe Vagrant::Machine do
config.vm.guest = :parent config.vm.guest = :parent
instance.guest.should be_kind_of(guest_child) instance.guest.should be_kind_of(guest_child)
end 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("1", :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 end
describe "setting the ID" do describe "setting the ID" do