VirtualBox should use the new port forwarding collision detection stuff
This commit is contained in:
parent
79609d42bb
commit
5d82123da9
|
@ -178,6 +178,22 @@ module VagrantPlugins
|
|||
# default VM which just inherits the rest of the configuration.
|
||||
define(DEFAULT_VM_NAME) if defined_vm_keys.empty?
|
||||
|
||||
# Do some defaults for networks
|
||||
@__networks.each do |type, args|
|
||||
if type == :forwarded_port
|
||||
options = args.last
|
||||
|
||||
# If the last argument isn't an option hash, add it on.
|
||||
if !options.is_a?(Hash)
|
||||
options = {}
|
||||
args << options
|
||||
end
|
||||
|
||||
# Set the default name
|
||||
options[:id] = "#{args[0].to_s(32)}-#{args[1].to_s(32)}"
|
||||
end
|
||||
end
|
||||
|
||||
# Compile all the provider configurations
|
||||
@__providers.each do |name, blocks|
|
||||
# Find the configuration class for this provider
|
||||
|
|
|
@ -7,7 +7,6 @@ module VagrantPlugins
|
|||
autoload :CheckAccessible, File.expand_path("../action/check_accessible", __FILE__)
|
||||
autoload :CheckCreated, File.expand_path("../action/check_created", __FILE__)
|
||||
autoload :CheckGuestAdditions, File.expand_path("../action/check_guest_additions", __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 :CleanMachineFolder, File.expand_path("../action/clean_machine_folder", __FILE__)
|
||||
|
@ -36,6 +35,7 @@ module VagrantPlugins
|
|||
autoload :Package, File.expand_path("../action/package", __FILE__)
|
||||
autoload :PackageVagrantfile, File.expand_path("../action/package_vagrantfile", __FILE__)
|
||||
autoload :PrepareNFSSettings, File.expand_path("../action/prepare_nfs_settings", __FILE__)
|
||||
autoload :PrepareForwardedPortCollisionParams, File.expand_path("../action/prepare_forwarded_port_collision_params", __FILE__)
|
||||
autoload :PruneNFSExports, File.expand_path("../action/prune_nfs_exports", __FILE__)
|
||||
autoload :Resume, File.expand_path("../action/resume", __FILE__)
|
||||
autoload :SaneDefaults, File.expand_path("../action/sane_defaults", __FILE__)
|
||||
|
@ -56,9 +56,10 @@ module VagrantPlugins
|
|||
b.use CleanMachineFolder
|
||||
b.use SetName
|
||||
b.use ClearForwardedPorts
|
||||
b.use EnvSet, :port_collision_handler => :correct
|
||||
b.use Provision
|
||||
b.use CheckPortCollisions
|
||||
b.use EnvSet, :port_collision_repair => true
|
||||
b.use PrepareForwardedPortCollisionParams
|
||||
b.use HandleForwardedPortCollisions
|
||||
b.use PruneNFSExports
|
||||
b.use NFS
|
||||
b.use PrepareNFSSettings
|
||||
|
@ -203,8 +204,9 @@ module VagrantPlugins
|
|||
b.use Call, Created do |env, b2|
|
||||
if env[:result]
|
||||
b2.use CheckAccessible
|
||||
b2.use EnvSet, :port_collision_handler => :error
|
||||
b2.use CheckPortCollisions
|
||||
b2.use EnvSet, :port_collision_repair => false
|
||||
b2.use PrepareForwardedPortCollisionParams
|
||||
b2.use HandleForwardedPortCollisions
|
||||
b2.use Resume
|
||||
else
|
||||
b2.use MessageNotCreated
|
||||
|
|
|
@ -1,96 +0,0 @@
|
|||
require "set"
|
||||
|
||||
require "vagrant/util/is_port_open"
|
||||
|
||||
module VagrantPlugins
|
||||
module ProviderVirtualBox
|
||||
module Action
|
||||
class CheckPortCollisions
|
||||
include Util::CompileForwardedPorts
|
||||
include Vagrant::Util::IsPortOpen
|
||||
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
# For the handlers...
|
||||
@env = env
|
||||
|
||||
# If we don't have forwarded ports set on the environment, then
|
||||
# we compile them.
|
||||
env[:forwarded_ports] ||= compile_forwarded_ports(env[:machine].config)
|
||||
|
||||
existing = env[:machine].provider.driver.read_used_ports
|
||||
|
||||
# Calculate the auto-correct port range
|
||||
@usable_ports = Set.new(env[:machine].config.vm.usable_port_range)
|
||||
@usable_ports.subtract(env[:forwarded_ports].collect { |fp| fp.host_port })
|
||||
@usable_ports.subtract(existing)
|
||||
|
||||
# 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
|
||||
|
||||
env[:forwarded_ports].each do |fp|
|
||||
# Use the proper port, whether that be the configured port or the
|
||||
# port that is currently on use of the VM.
|
||||
host_port = fp.host_port
|
||||
host_port = current[fp.id] if current.has_key?(fp.id)
|
||||
|
||||
if existing.include?(host_port) || is_port_open?("127.0.0.1", host_port)
|
||||
# We have a collision! Handle it
|
||||
send("handle_#{handler}".to_sym, fp, existing)
|
||||
end
|
||||
end
|
||||
|
||||
@app.call(env)
|
||||
end
|
||||
|
||||
# Handles a port collision by raising an exception.
|
||||
def handle_error(fp, existing_ports)
|
||||
raise Vagrant::Errors::ForwardPortCollisionResume
|
||||
end
|
||||
|
||||
# Handles a port collision by attempting to fix it.
|
||||
def handle_correct(fp, existing_ports)
|
||||
# We need to keep this for messaging purposes
|
||||
original_hostport = fp.host_port
|
||||
|
||||
if !fp.auto_correct
|
||||
# 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 => fp.host_port.to_s,
|
||||
:guest_port => fp.guest_port.to_s
|
||||
end
|
||||
|
||||
if @usable_ports.empty?
|
||||
raise Vagrant::Errors::ForwardPortAutolistEmpty,
|
||||
:vm_name => @env[:machine].name,
|
||||
:host_port => fp.host_port.to_s,
|
||||
:guest_port => fp.guest_port.to_s
|
||||
end
|
||||
|
||||
# Get the first usable port and set it up
|
||||
new_port = @usable_ports.to_a.sort[0]
|
||||
@usable_ports.delete(new_port)
|
||||
fp.correct_host_port(new_port)
|
||||
existing_ports << new_port
|
||||
|
||||
# Notify the user
|
||||
@env[:ui].info(I18n.t("vagrant.actions.vm.forward_ports.fixed_collision",
|
||||
:host_port => original_hostport.to_s,
|
||||
:guest_port => fp.guest_port.to_s,
|
||||
:new_port => fp.host_port.to_s))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,36 @@
|
|||
module VagrantPlugins
|
||||
module ProviderVirtualBox
|
||||
module Action
|
||||
class PrepareForwardedPortCollisionParams
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
# Get the forwarded ports used by other virtual machines and
|
||||
# consider those in use as well.
|
||||
env[:port_collision_extra_in_use] = env[:machine].provider.driver.read_used_ports
|
||||
|
||||
# Build the remap for any existing collision detections
|
||||
remap = {}
|
||||
env[:port_collision_remap] = remap
|
||||
env[:machine].provider.driver.read_forwarded_ports.each do |_nic, name, hostport, _guestport|
|
||||
env[:machine].config.vm.networks.each do |type, args|
|
||||
next if type != :forwarded_port
|
||||
|
||||
# If the ID matches the name of the forwarded port, then
|
||||
# remap.
|
||||
options = args.last
|
||||
if options[:id] == name
|
||||
remap[name] = hostport
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue