Mitchell Hashimoto da15105a8f Make Box2 the new Box
This involved defaulting all box searching at the moment to VirtualBox.
Additionally, box upgrading is not yet handled. This needs to be done at
some point.
2012-07-11 18:36:21 -07:00

206 lines
5.0 KiB
Ruby

require 'log4r'
module Vagrant
class VM
include Vagrant::Util
attr_reader :uuid
attr_reader :env
attr_reader :name
attr_reader :vm
attr_reader :box
attr_reader :config
attr_reader :driver
def initialize(name, env, config, opts=nil)
@logger = Log4r::Logger.new("vagrant::vm")
@name = name
@vm = nil
@env = env
@config = config
@box = nil
@box = env.boxes.find(config.vm.box, :virtualbox) if config.vm.box
opts ||= {}
if opts[:base]
# The name is the ID we use.
@uuid = name
else
# Load the UUID if its saved.
active = env.local_data[:active] || {}
@uuid = active[@name.to_s]
end
# Reload ourselves to get the state
reload!
# Load the associated guest.
load_guest!
@loaded_guest_distro = false
end
# Loads the guest associated with the VM. The guest class is
# responsible for OS-specific functionality. More information
# can be found by reading the documentation on {Vagrant::Guest::Base}.
#
# **This method should never be called manually.**
def load_guest!(guest=nil)
guest ||= config.vm.guest
@logger.info("Loading guest: #{guest}")
if guest.is_a?(Class)
raise Errors::VMGuestError, :_key => :invalid_class, :guest => guest.to_s if !(guest <= Vagrant.plugin("1", :guest))
@guest = guest.new(self)
elsif guest.is_a?(Symbol)
# Look for the guest as a registered plugin
guest_klass = nil
Vagrant.plugin("1").registered.each do |plugin|
if plugin.guest.has_key?(guest)
guest_klass = plugin.guest[guest]
break
end
end
raise Errors::VMGuestError, :_key => :unknown_type, :guest => guest.to_s if !guest_klass
@guest = guest_klass.new(self)
else
raise Errors::VMGuestError, :unspecified
end
end
# Returns a channel object to communicate with the virtual
# machine.
def channel
@channel ||= Communication::SSH.new(self)
end
# Returns the guest for this VM, loading the distro of the system if
# we can.
def guest
if !@loaded_guest_distro && state == :running
# Load the guest distro for the first time
result = @guest.distro_dispatch
load_guest!(result)
@loaded_guest_distro = true
@logger.info("Guest class: #{@guest.class}")
end
@guest
end
# Access the {Vagrant::SSH} object associated with this VM, which
# is used to get SSH credentials with the virtual machine.
def ssh
@ssh ||= SSH.new(self)
end
# Returns the state of the VM as a symbol.
#
# @return [Symbol]
def state
return :not_created if !@uuid
state = @driver.read_state
return :not_created if !state
return state
end
# Returns a boolean true if the VM has been created, otherwise
# returns false.
#
# @return [Boolean]
def created?
state != :not_created
end
# Sets the currently active VM for this VM. If the VM is a valid,
# created virtual machine, then it will also update the local data
# to persist the VM. Otherwise, it will remove itself from the
# local data (if it exists).
def uuid=(value)
env.local_data[:active] ||= {}
if value
env.local_data[:active][name.to_s] = value
else
env.local_data[:active].delete(name.to_s)
end
# Commit the local data so that the next time vagrant is initialized,
# it realizes the VM exists
env.local_data.commit
# Store the uuid and reload the instance
@uuid = value
reload!
end
def reload!
begin
@driver = Driver::VirtualBox.new(@uuid)
rescue Driver::VirtualBox::VMNotFound
# Clear the UUID since this VM doesn't exist.
@uuid = nil
# Reset the driver. This shouldn't raise a VMNotFound since we won't
# feed it a UUID.
@driver = Driver::VirtualBox.new
end
end
def package(options=nil)
run_action(:package, { "validate" => false }.merge(options || {}))
end
def up(options=nil)
run_action(:up, options)
end
def start(options=nil)
return if state == :running
return resume if state == :saved
run_action(:start, options)
end
def halt(options=nil)
run_action(:halt, options)
end
def reload(options=nil)
run_action(:reload, options)
end
def provision
run_action(:provision)
end
def destroy
run_action(:destroy)
end
def suspend
run_action(:suspend)
end
def resume
run_action(:resume)
end
def ui
return @_ui if defined?(@_ui)
@_ui = @env.ui.dup
@_ui.resource = @name
@_ui
end
def run_action(name, options=nil)
options = {
:vm => self,
:ui => ui
}.merge(options || {})
env.action_runner.run(name, options)
end
end
end