diff --git a/plugins/providers/docker/action/prepare_networks.rb b/plugins/providers/docker/action/prepare_networks.rb index e52126f47..a61aa82e9 100644 --- a/plugins/providers/docker/action/prepare_networks.rb +++ b/plugins/providers/docker/action/prepare_networks.rb @@ -191,7 +191,8 @@ module VagrantPlugins base_opts[:opt] = "parent=#{bridge_interface.name}" subnet = IPAddr.new(bridge_interface.addr.ip_address << "/" << bridge_interface.netmask.ip_unpack.first) - prefix = subnet.ipv4? ? 24 : 64 + netmask = bridge_interface.netmask.ip_unpack.first + prefix = IPAddr.new("255.255.255.255/#{netmask}").to_i.to_s(2).count("1") base_opts[:subnet] = "#{subnet}/#{prefix}" subnet_addr = IPAddr.new(base_opts[:subnet]) base_opts[:driver] = "macvlan" @@ -214,7 +215,7 @@ module VagrantPlugins network_options, bridge_interface.name, env) end network_options[:ip_range] = request_public_iprange( - network_options, bridge_interface.name, env) + network_options, bridge_interface, env) end end [network_name, network_options] @@ -259,7 +260,7 @@ module VagrantPlugins # public network # # @param [Hash] network_options Docker scoped networking options - # @param [String] interface The bridge interface used + # @param [Socket::Ifaddr] interface The bridge interface used # @param [Hash] env Local call env # @return [String] Address range def request_public_iprange(network_options, interface, env) @@ -273,7 +274,7 @@ module VagrantPlugins while !range range = env[:ui].ask(I18n.t( "docker_provider.network_bridge_iprange_request", - interface: interface, + interface: interface.name, default_range: network_options[:subnet]) + " ", prefix: false ).strip @@ -283,10 +284,12 @@ module VagrantPlugins begin range = IPAddr.new(range) if !subnet.include?(range) + netmask = interface.netmask.ip_unpack.first + prefix = IPAddr.new("255.255.255.255/#{netmask}").to_i.to_s(2).count("1") env[:ui].warn(I18n.t( "docker_provider.network_bridge_iprange_outofbounds", subnet: network_options[:subnet], - range: "#{range}/#{range.prefix}" + range: "#{range}/#{prefix}" ) + "\n", prefix: false) range = nil end @@ -297,7 +300,9 @@ module VagrantPlugins range = nil end end - prefix = range.ipv4? ? 24 : 64 + + netmask = interface.netmask.ip_unpack.first + prefix = IPAddr.new("255.255.255.255/#{netmask}").to_i.to_s(2).count("1") "#{range}/#{prefix}" end diff --git a/test/unit/plugins/providers/docker/action/prepare_networks_test.rb b/test/unit/plugins/providers/docker/action/prepare_networks_test.rb index 039669417..17424b9a2 100644 --- a/test/unit/plugins/providers/docker/action/prepare_networks_test.rb +++ b/test/unit/plugins/providers/docker/action/prepare_networks_test.rb @@ -305,7 +305,8 @@ describe VagrantPlugins::DockerProvider::Action::PrepareNetworks do describe "#process_public_network" do let(:options) { {:ip=>"172.30.130.2", :subnet=>"172.30.0.0/16", :driver=>"bridge", :id=>"30e017d5-488f-5a2f-a3ke-k8dce8246b60"} } - let(:ipaddr) { double("ipaddr", prefix: 22, succ: "10.1.10.2", ipv4?: true, ipv6?: false) } + let(:ipaddr) { double("ipaddr", prefix: 22, succ: "10.1.10.2", ipv4?: true, + ipv6?: false, to_i: 4294967040) } it "raises an error if there are no network interfaces" do expect(subject).to receive(:list_interfaces).and_return([]) @@ -351,13 +352,20 @@ describe VagrantPlugins::DockerProvider::Action::PrepareNetworks do let(:subnet) { double("ipaddr", to_s: "172.30.130.2", prefix: 22, succ: "172.30.130.3", ipv6?: false) } + let(:ipaddr_prefix) { double("ipaddr_prefix", to_s: "255.255.255.255/255.255.255.0", + to_i: 4294967040 ) } + + let(:netmask) { double("netmask", ip_unpack: ["255.255.255.0", 0]) } + let(:interface) { double("interface", name: "bridge", netmask: netmask) } + it "requests a public ip range" do allow(IPAddr).to receive(:new).with(options[:subnet]).and_return(subnet) allow(IPAddr).to receive(:new).with("172.30.130.2").and_return(ipaddr) + allow(IPAddr).to receive(:new).with("255.255.255.255/255.255.255.0").and_return(ipaddr_prefix) allow(subnet).to receive(:include?).and_return(true) allow(machine.ui).to receive(:ask).and_return(options[:ip]) - addr = subject.request_public_iprange(options, "bridge", env) + addr = subject.request_public_iprange(options, interface, env) end end end