Import and destroy work with the new driver interface
This commit is contained in:
parent
2de7a1424d
commit
96868e5d29
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in New Issue