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 end
def call(env) 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 # The VM we are attempting to manipulate is inaccessible. This
# is a very bad situation and can only be fixed by the user. It # is a very bad situation and can only be fixed by the user. It
# also prohibits us from actually doing anything with the virtual # also prohibits us from actually doing anything with the virtual

View File

@ -12,20 +12,20 @@ module Vagrant
def call(env) def call(env)
# Use the raw interface for now, while the virtualbox gem # Use the raw interface for now, while the virtualbox gem
# doesn't support guest properties (due to cross platform issues) # 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? if version.empty?
env[:ui].warn I18n.t("vagrant.actions.vm.check_guest_additions.not_detected") env[:ui].warn I18n.t("vagrant.actions.vm.check_guest_additions.not_detected")
else else
# Strip the -OSE/_OSE off from the guest additions and the virtual box # 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. # 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, '') v.gsub(/[-_]ose/i, '')
end end
if guest_version != vb_version if guest_version != vb_version
env[:ui].warn(I18n.t("vagrant.actions.vm.check_guest_additions.version_mismatch", env[:ui].warn(I18n.t("vagrant.actions.vm.check_guest_additions.version_mismatch",
:guest_version => version, :guest_version => version,
:virtualbox_version => VirtualBox.version)) :virtualbox_version => vb_version))
end end
end end

View File

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

View File

@ -9,7 +9,7 @@ module Vagrant
end end
def call(env) 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[:ui].info I18n.t("vagrant.actions.vm.discard_state.discarding")
env[:vm].vm.discard_state env[:vm].vm.discard_state
end end

View File

@ -8,10 +8,10 @@ module Vagrant
end end
def call(env) def call(env)
if env[:vm].created? && env[:vm].vm.running? if env[:vm].state == :running
env[:vm].guest.halt if !env["force"] 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[:ui].info I18n.t("vagrant.actions.vm.halt.force")
env[:vm].vm.stop env[:vm].vm.stop
end end

View File

@ -10,7 +10,8 @@ module Vagrant
env[:ui].info I18n.t("vagrant.actions.vm.import.importing", :name => env[:vm].box.name) env[:ui].info I18n.t("vagrant.actions.vm.import.importing", :name => env[:vm].box.name)
# Import the virtual machine # 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].clear_line
env[:ui].report_progress(progress.percent, 100, false) env[:ui].report_progress(progress.percent, 100, false)
end end
@ -20,7 +21,7 @@ module Vagrant
env[:ui].clear_line env[:ui].clear_line
# Flag as erroneous and return if import failed # 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 # Import completed successfully. Continue the chain
@app.call(env) @app.call(env)

View File

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

View File

@ -22,14 +22,63 @@ module Vagrant
end end
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 protected
# This returns the version of VirtualBox that is running. # This returns the version of VirtualBox that is running.
# #
# @return [String] # @return [String]
def read_version def read_version
result = Subprocess.execute("VBoxManage", "--version") execute("--version").split("r")[0]
result.stdout.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 end
end end

View File

@ -4,6 +4,7 @@ module Vagrant
class VM class VM
include Vagrant::Util include Vagrant::Util
attr_reader :uuid
attr_reader :env attr_reader :env
attr_reader :name attr_reader :name
attr_reader :vm attr_reader :vm
@ -23,7 +24,8 @@ module Vagrant
# Look for the VM if it exists # Look for the VM if it exists
active = env.local_data[:active] || {} 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 the associated guest.
load_guest! load_guest!
@ -71,24 +73,34 @@ module Vagrant
@ssh ||= SSH.new(self) @ssh ||= SSH.new(self)
end 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 a boolean true if the VM has been created, otherwise
# returns false. # returns false.
# #
# @return [Boolean] # @return [Boolean]
def created? def created?
!vm.nil? state != :not_created
end end
# Sets the currently active VM for this VM. If the VM is a valid, # 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 # created virtual machine, then it will also update the local data
# to persist the VM. Otherwise, it will remove itself from the # to persist the VM. Otherwise, it will remove itself from the
# local data (if it exists). # local data (if it exists).
def vm=(value) def uuid=(value)
@vm = value @uuid = value
env.local_data[:active] ||= {}
if value && value.uuid env.local_data[:active] ||= {}
env.local_data[:active][name.to_s] = value.uuid if value
env.local_data[:active][name.to_s] = value
else else
env.local_data[:active].delete(name.to_s) env.local_data[:active].delete(name.to_s)
end end
@ -98,10 +110,6 @@ module Vagrant
env.local_data.commit env.local_data.commit
end end
def uuid
vm ? vm.uuid : nil
end
def reload! def reload!
@vm = VirtualBox::VM.find(@vm.uuid) @vm = VirtualBox::VM.find(@vm.uuid)
end end
@ -115,8 +123,7 @@ module Vagrant
end end
def start(options=nil) def start(options=nil)
raise Errors::VMInaccessible if !@vm.accessible? return if state == :running
return if @vm.running?
return resume if @vm.saved? return resume if @vm.saved?
run_action(:start, options) run_action(:start, options)
@ -146,12 +153,6 @@ module Vagrant
run_action(:resume) run_action(:resume)
end end
def saved?
@vm.saved?
end
def powered_off?; @vm.powered_off? end
def ui def ui
return @_ui if defined?(@_ui) return @_ui if defined?(@_ui)
@_ui = @env.ui.dup @_ui = @env.ui.dup

View File

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