diff --git a/lib/vagrant/action/vm/forward_ports.rb b/lib/vagrant/action/vm/forward_ports.rb index fe55b2514..181080795 100644 --- a/lib/vagrant/action/vm/forward_ports.rb +++ b/lib/vagrant/action/vm/forward_ports.rb @@ -12,19 +12,37 @@ module Vagrant def call(env) @env = env + # Get the ports we're forwarding + ports = forward_port_definitions + # Warn if we're port forwarding to any privileged ports... - threshold_check + threshold_check(ports) env[:ui].info I18n.t("vagrant.actions.vm.forward_ports.forwarding") - forward_ports(env[:vm]) + forward_ports(ports) @app.call(env) end + # This returns an array of forwarded ports with overrides properly + # squashed. + def forward_port_definitions + # Get all the port mappings in the order they're defined and + # organize them by their guestport, taking the "last one wins" + # approach. + guest_port_mapping = {} + @env[:vm].config.vm.forwarded_ports.each do |options| + guest_port_mapping[options[:guestport]] = options + end + + # Return the values, since the order doesn't really matter + guest_port_mapping.values + end + # This method checks for any forwarded ports on the host below # 1024, which causes the forwarded ports to fail. - def threshold_check - @env[:vm].config.vm.forwarded_ports.each do |options| + def threshold_check(ports) + ports.each do |options| if options[:hostport] <= 1024 @env[:ui].warn I18n.t("vagrant.actions.vm.forward_ports.privileged_ports") return @@ -32,12 +50,12 @@ module Vagrant end end - def forward_ports(vm) + def forward_ports(mappings) ports = [] interfaces = @env[:vm].driver.read_network_interfaces - @env[:vm].config.vm.forwarded_ports.each do |options| + mappings.each do |options| message_attributes = { :guest_port => options[:guestport], :host_port => options[:hostport],