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



83
84
85
86
87
88
89
# File 'lib/vagrant/action/vm/forward_ports.rb', line 83

def call(env)
  @env = env

  forward_ports

  @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.



34
35
36
37
38
39
40
41
# File 'lib/vagrant/action/vm/forward_ports.rb', line 34

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(name, options) ⇒ Object

Forwards a port.



123
124
125
126
127
128
129
# File 'lib/vagrant/action/vm/forward_ports.rb', line 123

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

#forward_portsObject



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/vagrant/action/vm/forward_ports.rb', line 91

def forward_ports
  @env.ui.info I18n.t("vagrant.actions.vm.forward_ports.forwarding")

  @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 @env["vm"].vm.network_adapters[adapter].attachment_type == :nat
      @env.ui.info(I18n.t("vagrant.actions.vm.forward_ports.forwarding_entry", message_attributes))
      forward_port(name, options)
    else
      @env.ui.info(I18n.t("vagrant.actions.vm.forward_ports.non_nat", message_attributes))
    end
  end

  @env["vm"].vm.save
  @env["vm"].reload!
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.



46
47
48
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
# File 'lib/vagrant/action/vm/forward_ports.rb', line 46

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
# File 'lib/vagrant/action/vm/forward_ports.rb', line 24

def threshold_check
  @env.env.config.vm.forwarded_ports.each do |name, options|
    raise Errors::ForwardPortBelowThreshold if options[:hostport] <= 1024
  end
end