Systems can now respond to `distro_dispatch` to return specific distro systems

This commit is contained in:
Mitchell Hashimoto 2011-01-09 13:06:26 -08:00
parent 3ff1162230
commit d00f314eb9
6 changed files with 92 additions and 40 deletions

View File

@ -27,6 +27,15 @@ module Vagrant
@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.
#
# **Warning:** If a return value which subclasses from {Base} is
# returned, Vagrant will use it as the new system instance for the
# class.
def distro_dispatch; end
# Halt the machine. This method should gracefully shut down the
# operating system. This method will cause `vagrant halt` and associated
# commands to _block_, meaning that if the machine doesn't halt

View File

@ -1,32 +1,9 @@
require 'vagrant/systems/linux/error'
require 'vagrant/systems/linux/config'
module Vagrant
module Systems
# A general Vagrant system implementation for "linux." In general,
# any linux-based OS will work fine with this system, although its
# not tested exhaustively. BSD or other based systems may work as
# well, but that hasn't been tested at all.
#
# At any rate, this system implementation should server as an
# example of how to implement any custom systems necessary.
class Linux < Base
# A custom config class which will be made accessible via `config.linux`
# This is not necessary for all system implementers, of course. However,
# generally, Vagrant tries to make almost every aspect of its execution
# configurable, and this assists that goal.
class LinuxConfig < Vagrant::Config::Base
configures :linux
attr_accessor :halt_timeout
attr_accessor :halt_check_interval
def initialize
@halt_timeout = 30
@halt_check_interval = 1
end
end
#-------------------------------------------------------------------
# Overridden methods
#-------------------------------------------------------------------
def halt
vm.env.ui.info I18n.t("vagrant.systems.linux.attempting_halt")
vm.ssh.execute do |ssh|
@ -111,11 +88,5 @@ module Vagrant
end
end
end
class Linux < Base
class LinuxError < Errors::VagrantError
error_namespace("vagrant.systems.linux")
end
end
end
end

View File

@ -0,0 +1,21 @@
module Vagrant
module Systems
class Linux < Vagrant::Systems::Base
# A custom config class which will be made accessible via `config.linux`
# This is not necessary for all system implementers, of course. However,
# generally, Vagrant tries to make almost every aspect of its execution
# configurable, and this assists that goal.
class LinuxConfig < Vagrant::Config::Base
configures :linux
attr_accessor :halt_timeout
attr_accessor :halt_check_interval
def initialize
@halt_timeout = 30
@halt_check_interval = 1
end
end
end
end
end

View File

@ -0,0 +1,9 @@
module Vagrant
module Systems
class Linux < Vagrant::Systems::Base
class LinuxError < Errors::VagrantError
error_namespace("vagrant.systems.linux")
end
end
end
end

View File

@ -3,7 +3,6 @@ module Vagrant
include Vagrant::Util
attr_reader :env
attr_reader :system
attr_reader :name
attr_reader :vm
@ -41,6 +40,8 @@ module Vagrant
# Load the associated system.
load_system!
end
@loaded_system_distro = false
end
# Loads the system associated with the VM. The system class is
@ -48,8 +49,8 @@ module Vagrant
# can be found by reading the documentation on {Vagrant::Systems::Base}.
#
# **This method should never be called manually.**
def load_system!
system = env.config.vm.system
def load_system!(system=nil)
system ||= env.config.vm.system
if system.is_a?(Class)
@system = system.new(self)
@ -65,6 +66,19 @@ module Vagrant
end
end
# Returns the system for this VM, loading the distro of the system if
# we can.
def system
if !@loaded_system_distro && created? && vm.running?
# Load the system distro for the first time
result = @system.distro_dispatch
load_system!(result)
@loaded_system_distro = true
end
@system
end
# Access the {Vagrant::SSH} object associated with this VM.
# On the initial call, this will initialize the object. On
# subsequent calls it will reuse the existing object.

View File

@ -25,6 +25,7 @@ class VMTest < Test::Unit::TestCase
setup do
@vm_name = "foo"
@mock_vm = mock("vm")
@mock_vm.stubs(:running?).returns(false)
@vm = Vagrant::VM.new(:env => @env, :vm => @mock_vm, :name => @vm_name)
@mock_vm.stubs(:uuid).returns("foo")
end
@ -96,11 +97,14 @@ class VMTest < Test::Unit::TestCase
}
end
context "with a class" do
class FakeSystemClass
def initialize(vm); end
end
should "load the given system if specified" do
fake_class = Class.new(Vagrant::Systems::Base)
assert_nothing_raised { @vm.load_system!(fake_class) }
assert @vm.system.is_a?(fake_class)
end
context "with a class" do
should "initialize class if given" do
@vm.env.config.vm.system = Vagrant::Systems::Linux
@ -109,7 +113,7 @@ class VMTest < Test::Unit::TestCase
end
should "raise error if class has invalid parent" do
@vm.env.config.vm.system = FakeSystemClass
@vm.env.config.vm.system = Class.new
assert_raises(Vagrant::Errors::VMSystemError) {
@vm.load_system!
}
@ -140,6 +144,30 @@ class VMTest < Test::Unit::TestCase
}
end
end
context "loading the distro" do
setup do
@vm.vm.stubs(:running?).returns(true)
end
should "not replace the distro if it is nil" do
@vm.env.config.vm.system = Class.new(Vagrant::Systems::Base)
@vm.load_system!
assert @vm.system.is_a?(@vm.env.config.vm.system)
end
should "replace the distro if it is not nil" do
@vm.env.config.vm.system = Class.new(Vagrant::Systems::Base) do
def distro_dispatch
:linux
end
end
@vm.load_system!
assert @vm.system.is_a?(Vagrant::Systems::Linux)
end
end
end
context "uuid" do