diff --git a/lib/vagrant/action/builtin/handle_forwarded_port_collisions.rb b/lib/vagrant/action/builtin/handle_forwarded_port_collisions.rb index 1fff8b6a1..82fe2891b 100644 --- a/lib/vagrant/action/builtin/handle_forwarded_port_collisions.rb +++ b/lib/vagrant/action/builtin/handle_forwarded_port_collisions.rb @@ -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 diff --git a/test/unit/vagrant/action/builtin/handle_forwarded_port_collisions_test.rb b/test/unit/vagrant/action/builtin/handle_forwarded_port_collisions_test.rb index 7cb34f860..7785b036a 100644 --- a/test/unit/vagrant/action/builtin/handle_forwarded_port_collisions_test.rb +++ b/test/unit/vagrant/action/builtin/handle_forwarded_port_collisions_test.rb @@ -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