Import and destroy work with the new driver interface

This commit is contained in:
Mitchell Hashimoto 2011-12-18 21:41:19 -08:00
parent 2de7a1424d
commit 96868e5d29
10 changed files with 89 additions and 45 deletions

View File

@ -7,7 +7,7 @@ module Vagrant
end
def call(env)
if env[:vm] && env[:vm].created? && !env[:vm].vm.accessible?
if env[:vm].state == :inaccessible
# The VM we are attempting to manipulate is inaccessible. This
# is a very bad situation and can only be fixed by the user. It
# also prohibits us from actually doing anything with the virtual

View File

@ -12,20 +12,20 @@ module Vagrant
def call(env)
# Use the raw interface for now, while the virtualbox gem
# doesn't support guest properties (due to cross platform issues)
version = env[:vm].vm.interface.get_guest_property_value("/VirtualBox/GuestAdd/Version")
version = env[:vm].driver.guest_additions_version(env[:vm].uuid)
if version.empty?
env[:ui].warn I18n.t("vagrant.actions.vm.check_guest_additions.not_detected")
else
# Strip the -OSE/_OSE off from the guest additions and the virtual box
# version since all the matters are that the version _numbers_ match up.
guest_version, vb_version = [version, VirtualBox.version].map do |v|
guest_version, vb_version = [version, env[:vm].driver.version].map do |v|
v.gsub(/[-_]ose/i, '')
end
if guest_version != vb_version
env[:ui].warn(I18n.t("vagrant.actions.vm.check_guest_additions.version_mismatch",
:guest_version => version,
:virtualbox_version => VirtualBox.version))
:virtualbox_version => vb_version))
end
end

View File

@ -8,8 +8,8 @@ module Vagrant
def call(env)
env[:ui].info I18n.t("vagrant.actions.vm.destroy.destroying")
env[:vm].vm.destroy
env[:vm].vm = nil
env[:vm].driver.delete(env[:vm].uuid)
env[:vm].uuid = nil
@app.call(env)
end

View File

@ -9,7 +9,7 @@ module Vagrant
end
def call(env)
if env[:vm].created? && env[:vm].vm.saved?
if env[:vm].state == :saved
env[:ui].info I18n.t("vagrant.actions.vm.discard_state.discarding")
env[:vm].vm.discard_state
end

View File

@ -8,10 +8,10 @@ module Vagrant
end
def call(env)
if env[:vm].created? && env[:vm].vm.running?
if env[:vm].state == :running
env[:vm].guest.halt if !env["force"]
if env[:vm].vm.state(true) != :powered_off
if env[:vm].state != :poweredoff
env[:ui].info I18n.t("vagrant.actions.vm.halt.force")
env[:vm].vm.stop
end

View File

@ -10,7 +10,8 @@ module Vagrant
env[:ui].info I18n.t("vagrant.actions.vm.import.importing", :name => env[:vm].box.name)
# Import the virtual machine
env[:vm].vm = VirtualBox::VM.import(env[:vm].box.directory.join("box.ovf").to_s) do |progress|
ovf_file = env[:vm].box.directory.join("box.ovf").to_s
env[:vm].uuid = env[:vm].driver.import(ovf_file) do |progress|
env[:ui].clear_line
env[:ui].report_progress(progress.percent, 100, false)
end
@ -20,7 +21,7 @@ module Vagrant
env[:ui].clear_line
# Flag as erroneous and return if import failed
raise Errors::VMImportFailure if !env[:vm].vm
raise Errors::VMImportFailure if !env[:vm].uuid
# Import completed successfully. Continue the chain
@app.call(env)

View File

@ -17,17 +17,8 @@ module Vagrant
state = nil
results = []
with_target_vms(argv[0]) do |vm|
if vm.created?
if vm.vm.accessible?
state = vm.vm.state.to_s
else
state = "inaccessible"
end
else
state = "not_created"
end
results << "#{vm.name.to_s.ljust(25)}#{state.gsub("_", " ")}"
state = vm.state.to_s if !state
results << "#{vm.name.to_s.ljust(25)}#{vm.state.to_s.gsub("_", " ")}"
end
state = results.length == 1 ? state : "listing"

View File

@ -22,14 +22,63 @@ module Vagrant
end
end
# Imports the VM with the given path to the OVF file. It returns
# the UUID as a string.
def import(ovf)
output = execute("import", ovf)
if output =~ /VM name "(.+?)"/
name = $1.to_s
output = execute("list", "vms")
if output =~ /^"#{name}" {(.+?)}$/
return $1.to_s
end
end
nil
end
# This deletes the VM with the given name.
def delete(uuid)
execute("unregistervm", uuid, "--delete")
end
# This reads the guest additions version for a VM.
def guest_additions_version(uuid)
output = execute("guestproperty", "get", uuid, "/VirtualBox/GuestAdd/Version")
return $1.to_s if output =~ /^Value: (.+?)$/
return nil
end
# This reads the state for the given UUID. The state of the VM
# will be returned as a symbol.
def read_state(uuid)
output = execute("showvminfo", uuid, "--machinereadable")
if output =~ /^name="<inaccessible>"$/
return :inaccessible
elsif output =~ /^VMState="(.+?)"$/
return $1.to_sym
end
nil
end
protected
# This returns the version of VirtualBox that is running.
#
# @return [String]
def read_version
result = Subprocess.execute("VBoxManage", "--version")
result.stdout.split("r")[0]
execute("--version").split("r")[0]
end
# Execute the given subcommand for VBoxManage and return the output.
def execute(*command)
# TODO: Detect failures and handle them
r = Subprocess.execute("VBoxManage", *command)
if r.exit_code != 0
raise Exception, "FAILURE: #{r.stderr}"
end
r.stdout
end
end
end

View File

@ -4,6 +4,7 @@ module Vagrant
class VM
include Vagrant::Util
attr_reader :uuid
attr_reader :env
attr_reader :name
attr_reader :vm
@ -23,7 +24,8 @@ module Vagrant
# Look for the VM if it exists
active = env.local_data[:active] || {}
@vm = VirtualBox::VM.find(active[@name.to_s]) if active[@name.to_s]
@uuid = active[@name.to_s]
# @vm = VirtualBox::VM.find(@uuid) if @uuid
# Load the associated guest.
load_guest!
@ -71,24 +73,34 @@ module Vagrant
@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(@uuid)
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?
!vm.nil?
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 vm=(value)
@vm = value
env.local_data[:active] ||= {}
def uuid=(value)
@uuid = value
if value && value.uuid
env.local_data[:active][name.to_s] = value.uuid
env.local_data[:active] ||= {}
if value
env.local_data[:active][name.to_s] = value
else
env.local_data[:active].delete(name.to_s)
end
@ -98,10 +110,6 @@ module Vagrant
env.local_data.commit
end
def uuid
vm ? vm.uuid : nil
end
def reload!
@vm = VirtualBox::VM.find(@vm.uuid)
end
@ -115,8 +123,7 @@ module Vagrant
end
def start(options=nil)
raise Errors::VMInaccessible if !@vm.accessible?
return if @vm.running?
return if state == :running
return resume if @vm.saved?
run_action(:start, options)
@ -146,12 +153,6 @@ module Vagrant
run_action(:resume)
end
def saved?
@vm.saved?
end
def powered_off?; @vm.powered_off? end
def ui
return @_ui if defined?(@_ui)
@_ui = @env.ui.dup

View File

@ -227,13 +227,15 @@ en:
not_created: |-
The environment has not yet been created. Run `vagrant up` to
create the environment.
powered_off: The VM is powered off. To restart the VM, simply run `vagrant up`
poweroff: |-
The VM is powered off. To restart the VM, simply run `vagrant up`
running: |-
The VM is running. To stop this VM, you can run `vagrant halt` to
shut it down forcefully, or you can run `vagrant suspend` to simply
suspend the virtual machine. In either case, to restart it again,
simply run `vagrant up`.
saved: To resume this VM, simply run `vagrant up`.
saved: |-
To resume this VM, simply run `vagrant up`.
stuck: |-
The VM is "stuck!" This is a very rare state which means that
VirtualBox is unable to recover the current state of the VM.