Class: Vagrant::Action::VM::ForwardPorts

Inherits:
Object
  • Object
show all
Includes:
ForwardPortsHelpers
Defined in:
lib/vagrant/action/vm/forward_ports.rb

Instance Method Summary collapse

Methods included from ForwardPortsHelpers

#used_ports

Constructor Details

#initialize(app, env) ⇒ ForwardPorts

Returns a new instance of ForwardPorts.



9
10
11
12
13
14
15
# File 'lib/vagrant/action/vm/forward_ports.rb', line 9

def initialize(app,env)
  @app = app
  @env = env

  threshold_check
  external_collision_check
end

Instance Method Details

#call(env) ⇒ Object


Execution



86
87
88
89
90
91
92
93
94
95
96
# File 'lib/vagrant/action/vm/forward_ports.rb', line 86

def call(env)
  @env = env

  proc = lambda do |vm|
    env.ui.info I18n.t("vagrant.actions.vm.forward_ports.forwarding")
    forward_ports(vm)
  end

  env["vm.modify"].call(proc)
  @app.call(env)
end

#external_collision_checkObject

This method checks for any port collisions with any VMs which are already created (by Vagrant or otherwise). report the collisions detected or will attempt to fix them automatically if the port is configured to do so.



37
38
39
40
41
42
43
44
# File 'lib/vagrant/action/vm/forward_ports.rb', line 37

def external_collision_check
  existing = used_ports
  @env.env.config.vm.forwarded_ports.each do |name, options|
    if existing.include?(options[:hostport].to_i)
      handle_collision(name, options, existing)
    end
  end
end

#forward_port(vm, name, options) ⇒ Object

Forwards a port.



125
126
127
128
129
130
131
132
# File 'lib/vagrant/action/vm/forward_ports.rb', line 125

def forward_port(vm, name, options)
  port = VirtualBox::NATForwardedPort.new
  port.name = name
  port.guestport = options[:guestport]
  port.hostport = options[:hostport]
  port.protocol = options[:protocol] || :tcp
  vm.network_adapters[options[:adapter]].nat_driver.forwarded_ports << port
end

#forward_ports(vm) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/vagrant/action/vm/forward_ports.rb', line 98

def forward_ports(vm)
  @env.env.config.vm.forwarded_ports.each do |name, options|
    adapter = options[:adapter]
    message_attributes = {
      :name => name,
      :guest_port => options[:guestport],
      :host_port => options[:hostport],
      :adapter => adapter + 1
    }

    # Assuming the only reason to establish port forwarding is because the VM is using Virtualbox NAT networking.
    # Host-only or Bridged networking don't require port-forwarding and establishing forwarded ports on these
    # attachment types has uncertain behaviour.
    if vm.network_adapters[adapter].attachment_type == :nat
      @env.ui.info(I18n.t("vagrant.actions.vm.forward_ports.forwarding_entry", message_attributes))
      forward_port(vm, name, options)
    else
      @env.ui.info(I18n.t("vagrant.actions.vm.forward_ports.non_nat", message_attributes))
    end
  end
end

#handle_collision(name, options, existing_ports) ⇒ Object

Handles any collisions. This method will either attempt to fix the collision automatically or will raise an error if auto fixing is disabled.



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/vagrant/action/vm/forward_ports.rb', line 49

def handle_collision(name, options, existing_ports)
  if !options[:auto]
    # Auto fixing is disabled for this port forward, so we
    # must throw an error so the user can fix it.
    raise Errors::ForwardPortCollision, :name => name,
                                        :host_port => options[:hostport].to_s,
                                        :guest_port => options[:guestport].to_s
  end

  # Get the auto port range and get rid of the used ports and
  # ports which are being used in other forwards so we're just
  # left with available ports.
  range = @env.env.config.vm.auto_port_range.to_a
  range -= @env.env.config.vm.forwarded_ports.collect { |n, o| o[:hostport].to_i }
  range -= existing_ports

  if range.empty?
    raise Errors::ForwardPortAutolistEmpty, :vm_name => @env["vm"].name,
                                            :name => name,
                                            :host_port => options[:hostport].to_s,
                                            :guest_port => options[:guestport].to_s
  end

  # Set the port up to be the first one and add that port to
  # the used list.
  options[:hostport] = range.shift
  existing_ports << options[:hostport]

  # Notify the user
  @env.ui.info(I18n.t("vagrant.actions.vm.forward_ports.fixed_collision",
               :name => name,
               :new_port => options[:hostport]))
end

#threshold_checkObject

This method checks for any forwarded ports on the host below 1024, which causes the forwarded ports to fail.



24
25
26
27
28
29
30
31
# File 'lib/vagrant/action/vm/forward_ports.rb', line 24

def threshold_check
  @env.env.config.vm.forwarded_ports.each do |name, options|
    if options[:hostport] <= 1024
      @env.ui.warn I18n.t("vagrant.actions.vm.forward_ports.privileged_ports")
      return
    end
  end
end