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 @vm = vm
end 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 # Halt the machine. This method should gracefully shut down the
# operating system. This method will cause `vagrant halt` and associated # operating system. This method will cause `vagrant halt` and associated
# commands to _block_, meaning that if the machine doesn't halt # 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 Vagrant
module Systems 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 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 def halt
vm.env.ui.info I18n.t("vagrant.systems.linux.attempting_halt") vm.env.ui.info I18n.t("vagrant.systems.linux.attempting_halt")
vm.ssh.execute do |ssh| vm.ssh.execute do |ssh|
@ -111,11 +88,5 @@ module Vagrant
end end
end end
end end
class Linux < Base
class LinuxError < Errors::VagrantError
error_namespace("vagrant.systems.linux")
end
end
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 include Vagrant::Util
attr_reader :env attr_reader :env
attr_reader :system
attr_reader :name attr_reader :name
attr_reader :vm attr_reader :vm
@ -41,6 +40,8 @@ module Vagrant
# Load the associated system. # Load the associated system.
load_system! load_system!
end end
@loaded_system_distro = false
end end
# Loads the system associated with the VM. The system class is # 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}. # can be found by reading the documentation on {Vagrant::Systems::Base}.
# #
# **This method should never be called manually.** # **This method should never be called manually.**
def load_system! def load_system!(system=nil)
system = env.config.vm.system system ||= env.config.vm.system
if system.is_a?(Class) if system.is_a?(Class)
@system = system.new(self) @system = system.new(self)
@ -65,6 +66,19 @@ module Vagrant
end end
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. # Access the {Vagrant::SSH} object associated with this VM.
# On the initial call, this will initialize the object. On # On the initial call, this will initialize the object. On
# subsequent calls it will reuse the existing object. # subsequent calls it will reuse the existing object.

View File

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