Support port checker methods which only accept the host port

When calling the port_checker an arity check is done to determine
if the helper accepts the host_ip and host_port or only the host_port.

Fixes #8423
This commit is contained in:
Chris Roberts 2017-04-19 10:49:27 -07:00
parent 61c556ff90
commit 82ca8f8058
2 changed files with 45 additions and 2 deletions

View File

@ -118,7 +118,7 @@ module Vagrant
# If the port is open (listening for TCP connections)
in_use = is_forwarded_already(extra_in_use, host_port, host_ip) ||
port_checker[host_ip, host_port] ||
call_port_checker(port_checker, host_ip, host_port) ||
lease_check(host_ip, host_port)
if in_use
if !repair || !options[:auto_correct]
@ -137,7 +137,7 @@ module Vagrant
# If the port is in use, then we can't use this either...
in_use = is_forwarded_already(extra_in_use, repaired_port, host_ip) ||
port_checker[host_ip, repaired_port] ||
call_port_checker(port_checker, host_ip, repaired_port) ||
lease_check(host_ip, repaired_port)
if in_use
@logger.info("Repaired port also in use: #{repaired_port}. Trying another...")
@ -266,6 +266,13 @@ module Vagrant
yield options
end
end
def call_port_checker(port_checker, host_ip, host_port)
call_args = [host_ip, host_port]
# Trim args if checker method does not support inclusion of host_ip
call_args = call_args.slice(call_args.size - port_checker.arity.abs, port_checker.arity.abs)
port_checker[*call_args]
end
end
end
end

View File

@ -15,6 +15,7 @@ describe Vagrant::Action::Builtin::HandleForwardedPortCollisions do
let(:collision_remap){ nil }
let(:collision_repair){ nil }
let(:collision_port_check){ nil }
let(:port_check_method){ nil }
let(:machine) do
double("machine").tap do |machine|
@ -101,6 +102,41 @@ describe Vagrant::Action::Builtin::HandleForwardedPortCollisions do
end
end
end
context "with custom port_check method" do
let(:check_result){ [] }
let(:port_options){ {guest: 80, host: 8080, host_ip: "127.0.1.1"} }
context "that accepts two parameters" do
let(:collision_port_check) do
lambda do |host_ip, host_port|
check_result.push(host_ip)
check_result.push(host_port)
false
end
end
it "should receive both host_ip and host_port" do
instance.call(env)
expect(check_result).to include(port_options[:host])
expect(check_result).to include(port_options[:host_ip])
end
end
context "that accepts one parameter" do
let(:collision_port_check) do
lambda do |host_port|
check_result.push(host_port)
false
end
end
it "should receive the host_port only" do
instance.call(env)
expect(check_result).to eq([port_options[:host]])
end
end
end
end
end