`vagrant resume` works with the new machine abstraction
This commit is contained in:
parent
db11c16b79
commit
bca8663742
|
@ -4,10 +4,8 @@ module VagrantPlugins
|
|||
module CommandResume
|
||||
class Command < Vagrant.plugin("1", :command)
|
||||
def execute
|
||||
options = {}
|
||||
|
||||
opts = OptionParser.new do |opts|
|
||||
opts.banner = "Usage: vagrant resume [vm-name]"
|
||||
opts = OptionParser.new do |o|
|
||||
o.banner = "Usage: vagrant resume [vm-name]"
|
||||
end
|
||||
|
||||
# Parse the options
|
||||
|
@ -15,19 +13,13 @@ module VagrantPlugins
|
|||
return if !argv
|
||||
|
||||
@logger.debug("'resume' each target VM...")
|
||||
with_target_vms(argv) do |vm|
|
||||
if vm.created?
|
||||
@logger.info("Resume: #{vm.name}")
|
||||
vm.resume
|
||||
else
|
||||
@logger.info("Not created: #{vm.name}. Not resuming.")
|
||||
vm.ui.info I18n.t("vagrant.commands.common.vm_not_created")
|
||||
end
|
||||
with_target_vms(argv) do |machine|
|
||||
machine.action(:resume)
|
||||
end
|
||||
|
||||
# Success, exit status 0
|
||||
0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,8 +3,10 @@ require "vagrant/action/builder"
|
|||
module VagrantPlugins
|
||||
module ProviderVirtualBox
|
||||
module Action
|
||||
autoload :Boot, File.expand_path("../action/boot", __FILE__)
|
||||
autoload :CheckAccessible, File.expand_path("../action/check_accessible", __FILE__)
|
||||
autoload :CheckCreated, File.expand_path("../action/check_created", __FILE__)
|
||||
autoload :CheckPortCollisions, File.expand_path("../action/check_port_collisions", __FILE__)
|
||||
autoload :CheckRunning, File.expand_path("../action/check_running", __FILE__)
|
||||
autoload :CheckVirtualbox, File.expand_path("../action/check_virtualbox", __FILE__)
|
||||
autoload :Created, File.expand_path("../action/created", __FILE__)
|
||||
|
@ -13,6 +15,7 @@ module VagrantPlugins
|
|||
autoload :Halt, File.expand_path("../action/halt", __FILE__)
|
||||
autoload :MessageNotCreated, File.expand_path("../action/message_not_created", __FILE__)
|
||||
autoload :MessageWillNotDestroy, File.expand_path("../action/message_will_not_destroy", __FILE__)
|
||||
autoload :Resume, File.expand_path("../action/resume", __FILE__)
|
||||
autoload :Suspend, File.expand_path("../action/suspend", __FILE__)
|
||||
|
||||
# Include the built-in modules so that we can use them as top-level
|
||||
|
@ -59,6 +62,23 @@ module VagrantPlugins
|
|||
end
|
||||
end
|
||||
|
||||
# This is the action that is primarily responsible for resuming
|
||||
# suspended machines.
|
||||
def self.action_resume
|
||||
Vagrant::Action::Builder.new.tap do |b|
|
||||
b.use CheckVirtualbox
|
||||
b.use Call, Created do |env, b2|
|
||||
if env[:result]
|
||||
b2.use CheckAccessible
|
||||
b2.use CheckPortCollisions
|
||||
b2.use Resume
|
||||
else
|
||||
b2.use MessageNotCreated
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# This is the action that will exec into an SSH shell.
|
||||
def self.action_ssh
|
||||
Vagrant::Action::Builder.new.tap do |b|
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
module VagrantPlugins
|
||||
module ProviderVirtualBox
|
||||
module Action
|
||||
class Boot
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
@env = env
|
||||
|
||||
# Start up the VM and wait for it to boot.
|
||||
env[:ui].info I18n.t("vagrant.actions.vm.boot.booting")
|
||||
env[:machine].provider.driver.start(@env[:machine].config.vm.boot_mode)
|
||||
raise Errors::VMFailedToBoot if !wait_for_boot
|
||||
|
||||
@app.call(env)
|
||||
end
|
||||
|
||||
def wait_for_boot
|
||||
@env[:ui].info I18n.t("vagrant.actions.vm.boot.waiting")
|
||||
|
||||
@env[:machine].config.ssh.max_tries.to_i.times do |i|
|
||||
if @env[:machine].communicate.ready?
|
||||
@env[:ui].info I18n.t("vagrant.actions.vm.boot.ready")
|
||||
return true
|
||||
end
|
||||
|
||||
# Return true so that the vm_failed_to_boot error doesn't
|
||||
# get shown
|
||||
return true if @env[:interrupted]
|
||||
|
||||
# If the VM is not starting or running, something went wrong
|
||||
# and we need to show a useful error.
|
||||
state = @env[:machine].provider.state
|
||||
raise Errors::VMFailedToRun if state != :starting && state != :running
|
||||
|
||||
sleep 2 if !@env["vagrant.test"]
|
||||
end
|
||||
|
||||
@env[:ui].error I18n.t("vagrant.actions.vm.boot.failed")
|
||||
false
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,89 @@
|
|||
require "vagrant/util/is_port_open"
|
||||
|
||||
module VagrantPlugins
|
||||
module ProviderVirtualBox
|
||||
module Action
|
||||
class CheckPortCollisions
|
||||
include Vagrant::Util::IsPortOpen
|
||||
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
# For the handlers...
|
||||
@env = env
|
||||
|
||||
# Figure out how we handle port collisions. By default we error.
|
||||
handler = env[:port_collision_handler] || :error
|
||||
|
||||
# Read our forwarded ports, if we have any, to override what
|
||||
# we have configured.
|
||||
current = {}
|
||||
env[:machine].provider.driver.read_forwarded_ports.each do |nic, name, hostport, guestport|
|
||||
current[name] = hostport.to_i
|
||||
end
|
||||
|
||||
existing = env[:machine].provider.driver.read_used_ports
|
||||
env[:machine].config.vm.forwarded_ports.each do |options|
|
||||
# Use the proper port, whether that be the configured port or the
|
||||
# port that is currently on use of the VM.
|
||||
hostport = options[:hostport].to_i
|
||||
hostport = current[options[:name]] if current.has_key?(options[:name])
|
||||
|
||||
if existing.include?(hostport) || is_port_open?("localhost", hostport)
|
||||
# We have a collision! Handle it
|
||||
send("handle_#{handler}".to_sym, options, existing)
|
||||
end
|
||||
end
|
||||
|
||||
@app.call(env)
|
||||
end
|
||||
|
||||
# Handles a port collision by raising an exception.
|
||||
def handle_error(options, existing_ports)
|
||||
raise Vagrant::Errors::ForwardPortCollisionResume
|
||||
end
|
||||
|
||||
# Handles a port collision by attempting to fix it.
|
||||
def handle_correct(options, existing_ports)
|
||||
# We need to keep this for messaging purposes
|
||||
original_hostport = options[:hostport]
|
||||
|
||||
if !options[:auto]
|
||||
# Auto fixing is disabled for this port forward, so we
|
||||
# must throw an error so the user can fix it.
|
||||
raise Vagrant::Errors::ForwardPortCollision,
|
||||
:host_port => options[:hostport].to_s,
|
||||
:guest_port => options[:guestport].to_s
|
||||
end
|
||||
|
||||
# Get the auto port range and get rid of the used ports and
|
||||
# ports which are being used in other forwards so we're just
|
||||
# left with available ports.
|
||||
range = @env[:machine].config.vm.auto_port_range.to_a
|
||||
range -= @env[:machine].config.vm.forwarded_ports.collect { |opts| opts[:hostport].to_i }
|
||||
range -= existing_ports
|
||||
|
||||
if range.empty?
|
||||
raise Vagrant::Errors::ForwardPortAutolistEmpty,
|
||||
:vm_name => @env[:machine].name,
|
||||
:host_port => options[:hostport].to_s,
|
||||
:guest_port => options[:guestport].to_s
|
||||
end
|
||||
|
||||
# Set the port up to be the first one and add that port to
|
||||
# the used list.
|
||||
options[:hostport] = range.shift
|
||||
existing_ports << options[:hostport]
|
||||
|
||||
# Notify the user
|
||||
@env[:ui].info(I18n.t("vagrant.actions.vm.forward_ports.fixed_collision",
|
||||
:host_port => original_hostport.to_s,
|
||||
:guest_port => options[:guestport].to_s,
|
||||
:new_port => options[:hostport]))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,13 +1,13 @@
|
|||
module Vagrant
|
||||
module Action
|
||||
module VM
|
||||
module VagrantPlugins
|
||||
module ProviderVirtualBox
|
||||
module Action
|
||||
class Resume
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
if env[:vm].state == :saved
|
||||
if env[:machine].provider.state == :saved
|
||||
env[:ui].info I18n.t("vagrant.actions.vm.resume.resuming")
|
||||
env[:action_runner].run(Boot, env)
|
||||
end
|
Loading…
Reference in New Issue