178 lines
4.3 KiB
Ruby

module Vagrant
class VM
include Vagrant::Util
attr_reader :env
attr_reader :name
attr_reader :vm
class << self
# Finds a virtual machine by a given UUID and either returns
# a Vagrant::VM object or returns nil.
def find(uuid, env=nil, name=nil)
vm = VirtualBox::VM.find(uuid)
new(:vm => vm, :env => env, :name => name)
end
end
def initialize(opts=nil)
defaults = {
:vm => nil,
:env => nil,
:name => nil
}
opts = defaults.merge(opts || {})
@vm = opts[:vm]
@name = opts[:name]
if !opts[:env].nil?
# We have an environment, so we create a new child environment
# specifically for this VM. This step will load any custom
# config and such.
@env = Vagrant::Environment.new({
:cwd => opts[:env].cwd,
:parent => opts[:env],
:vm => self
}).load!
# Load the associated system.
load_system!
end
@loaded_system_distro = false
end
# Loads the system associated with the VM. The system class is
# responsible for OS-specific functionality. More information
# can be found by reading the documentation on {Vagrant::Systems::Base}.
#
# **This method should never be called manually.**
def load_system!(system=nil)
system ||= env.config.vm.system
if system.is_a?(Class)
raise Errors::VMSystemError, :_key => :invalid_class, :system => system.to_s if !(system <= Systems::Base)
@system = system.new(self)
elsif system.is_a?(Symbol)
# Hard-coded internal systems
mapping = {
:debian => Systems::Debian,
:ubuntu => Systems::Ubuntu,
:freebsd => Systems::FreeBSD,
:gentoo => Systems::Gentoo,
:redhat => Systems::Redhat,
:linux => Systems::Linux,
:solaris => Systems::Solaris
}
raise Errors::VMSystemError, :_key => :unknown_type, :system => system.to_s if !mapping.has_key?(system)
@system = mapping[system].new(self)
else
raise Errors::VMSystemError, :unspecified
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.
def ssh
@ssh ||= SSH.new(env)
end
# Returns a boolean true if the VM has been created, otherwise
# returns false.
#
# @return [Boolean]
def created?
!vm.nil?
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 vm=(value)
@vm = value
env.local_data[:active] ||= {}
if value && value.uuid
env.local_data[:active][name.to_s] = value.uuid
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
end
def uuid
vm ? vm.uuid : nil
end
def reload!
@vm = VirtualBox::VM.find(@vm.uuid)
end
def package(options=nil)
env.actions.run(:package, { "validate" => false }.merge(options || {}))
end
def up(options=nil)
env.actions.run(:up, options)
end
def start(options=nil)
return if @vm.running?
return resume if @vm.saved?
env.actions.run(:start, options)
end
def halt(options=nil)
env.actions.run(:halt, options)
end
def reload
env.actions.run(:reload)
end
def provision
env.actions.run(:provision)
end
def destroy
env.actions.run(:destroy)
end
def suspend
env.actions.run(:suspend)
end
def resume
env.actions.run(:resume)
end
def saved?
@vm.saved?
end
def powered_off?; @vm.powered_off? end
end
end