Ignore inactive docker containers when assigning ports

Checks to make sure that a docker container is running before determining
whether or not the port is in use. This prevents the a port on an inactive
container from being treated as if it is use.

Fixes https://github.com/hashicorp/vagrant/issues/13110
This commit is contained in:
Allison Larson 2023-05-09 16:17:23 -07:00
parent 9076445d64
commit 10e45f1df1
2 changed files with 24 additions and 7 deletions

View File

@ -140,6 +140,9 @@ module VagrantPlugins
all_containers.each do |c| all_containers.each do |c|
container_info = inspect_container(c) container_info = inspect_container(c)
active = container_info["State"]["Running"]
next unless active # Ignore used ports on inactive containers
if container_info["HostConfig"]["PortBindings"] if container_info["HostConfig"]["PortBindings"]
port_bindings = container_info["HostConfig"]["PortBindings"] port_bindings = container_info["HostConfig"]["PortBindings"]
next if port_bindings.empty? # Nothing defined, but not nil either next if port_bindings.empty? # Nothing defined, but not nil either

View File

@ -346,13 +346,14 @@ describe VagrantPlugins::DockerProvider::Driver do
describe '#read_used_ports' do describe '#read_used_ports' do
let(:all_containers) { ["container1\ncontainer2"] } let(:all_containers) { ["container1\ncontainer2"] }
let(:container_info) { {"Name"=>"/container", "HostConfig"=>{"PortBindings"=>{}}} } let(:container_info) { {"Name"=>"/container", "State"=>{"Running"=>true}, "HostConfig"=>{"PortBindings"=>{}}} }
let(:empty_used_ports) { {} } let(:empty_used_ports) { {} }
context "with existing port forwards" do context "with existing port forwards" do
let(:container_info) { {"Name"=>"/container", "HostConfig"=>{"PortBindings"=>{"22/tcp"=>[{"HostIp"=>"127.0.0.1","HostPort"=>"2222"}] }}} } let(:container_info) { {"Name"=>"/container","State"=>{"Running"=>true}, "HostConfig"=>{"PortBindings"=>{"22/tcp"=>[{"HostIp"=>"127.0.0.1","HostPort"=>"2222"}] }}} }
let(:used_ports_set) { {"2222"=>Set["127.0.0.1"]} } let(:used_ports_set) { {"2222"=>Set["127.0.0.1"]} }
context "with active containers" do
it 'should read all port bindings and return a hash of sets' do it 'should read all port bindings and return a hash of sets' do
allow(subject).to receive(:all_containers).and_return(all_containers) allow(subject).to receive(:all_containers).and_return(all_containers)
allow(subject).to receive(:inspect_container).and_return(container_info) allow(subject).to receive(:inspect_container).and_return(container_info)
@ -362,6 +363,19 @@ describe VagrantPlugins::DockerProvider::Driver do
end end
end end
context "with inactive containers" do
let(:container_info) { {"Name"=>"/container", "State"=>{"Running"=>false}, "HostConfig"=>{"PortBindings"=>{"22/tcp"=>[{"HostIp"=>"127.0.0.1","HostPort"=>"2222"}] }}} }
it 'returns empty' do
allow(subject).to receive(:all_containers).and_return(all_containers)
allow(subject).to receive(:inspect_container).and_return(container_info)
used_ports = subject.read_used_ports
expect(used_ports).to eq(empty_used_ports)
end
end
end
it 'returns empty if no ports are already bound' do it 'returns empty if no ports are already bound' do
allow(subject).to receive(:all_containers).and_return(all_containers) allow(subject).to receive(:all_containers).and_return(all_containers)
allow(subject).to receive(:inspect_container).and_return(container_info) allow(subject).to receive(:inspect_container).and_return(container_info)