From 296878cff5639888c6cda76b5f5debdcd117046b Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 12 Aug 2012 19:03:22 -0700 Subject: [PATCH] Add basic loop detection for distro_dispatch --- lib/vagrant/machine.rb | 16 ++++++++++++++-- test/unit/vagrant/machine_test.rb | 18 ++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/lib/vagrant/machine.rb b/lib/vagrant/machine.rb index f2c74fd57..ea448a6ad 100644 --- a/lib/vagrant/machine.rb +++ b/lib/vagrant/machine.rb @@ -132,14 +132,26 @@ module Vagrant raise Errors::MachineGuestNotReady if !communicate.ready? # 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. while true distro = guest.distro_dispatch break if !distro - guest = load_guest(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 diff --git a/test/unit/vagrant/machine_test.rb b/test/unit/vagrant/machine_test.rb index 7cc7eb03f..d32fed62d 100644 --- a/test/unit/vagrant/machine_test.rb +++ b/test/unit/vagrant/machine_test.rb @@ -249,6 +249,24 @@ describe Vagrant::Machine do 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("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 describe "setting the ID" do