Forwarded ports
This commit is contained in:
parent
c59defa7e8
commit
a39df9f150
|
@ -7,17 +7,9 @@ module Vagrant
|
|||
end
|
||||
|
||||
def call(env)
|
||||
proc = lambda do |vm|
|
||||
env[:ui].info I18n.t("vagrant.actions.vm.clear_forward_ports.deleting")
|
||||
env[:ui].info I18n.t("vagrant.actions.vm.clear_forward_ports.deleting")
|
||||
env[:vm].driver.clear_forwarded_ports
|
||||
|
||||
vm.network_adapters.each do |na|
|
||||
na.nat_driver.forwarded_ports.dup.each do |fp|
|
||||
fp.destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
env["vm.modify"].call(proc)
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
require File.join(File.dirname(__FILE__), 'forward_ports_helpers')
|
||||
|
||||
module Vagrant
|
||||
module Action
|
||||
module VM
|
||||
class ForwardPorts
|
||||
include ForwardPortsHelpers
|
||||
|
||||
def initialize(app,env)
|
||||
@app = app
|
||||
@env = env
|
||||
|
@ -35,7 +31,7 @@ module Vagrant
|
|||
# report the collisions detected or will attempt to fix them
|
||||
# automatically if the port is configured to do so.
|
||||
def external_collision_check
|
||||
existing = used_ports
|
||||
existing = @env[:vm].driver.read_used_ports
|
||||
@env[:vm].config.vm.forwarded_ports.each do |name, options|
|
||||
if existing.include?(options[:hostport].to_i)
|
||||
handle_collision(name, options, existing)
|
||||
|
@ -86,35 +82,41 @@ module Vagrant
|
|||
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[:ui].info I18n.t("vagrant.actions.vm.forward_ports.forwarding")
|
||||
forward_ports(env[:vm])
|
||||
|
||||
env["vm.modify"].call(proc)
|
||||
@app.call(env)
|
||||
end
|
||||
|
||||
def forward_ports(vm)
|
||||
ports = []
|
||||
|
||||
@env[:vm].config.vm.forwarded_ports.each do |name, options|
|
||||
adapter = options[:adapter]
|
||||
adapter = options[:adapter] + 1
|
||||
message_attributes = {
|
||||
:name => name,
|
||||
:guest_port => options[:guestport],
|
||||
:host_port => options[:hostport],
|
||||
:adapter => adapter + 1
|
||||
:adapter => adapter
|
||||
}
|
||||
|
||||
# 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
|
||||
# Assuming the only reason to establish port forwarding is
|
||||
# because the VM is using Virtualbox NAT networking. Host-only
|
||||
# bridged networking don't require port-forwarding and establishing
|
||||
# forwarded ports on these attachment types has uncertain behaviour.
|
||||
@env[:ui].info(I18n.t("vagrant.actions.vm.forward_ports.forwarding_entry",
|
||||
message_attributes))
|
||||
|
||||
# Add the options to the ports array to send to the driver later
|
||||
ports << options.merge(:name => name, :adapter => adapter)
|
||||
|
||||
# TODO: Check for non-nat again... This was removed during the VBoxManage
|
||||
# transition but should be brought back.
|
||||
# @env[:ui].info(I18n.t("vagrant.actions.vm.forward_ports.non_nat",
|
||||
# message_attributes))
|
||||
end
|
||||
|
||||
@env[:vm].driver.forward_ports(ports)
|
||||
end
|
||||
|
||||
#--------------------------------------------------------------
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
module Vagrant
|
||||
module Action
|
||||
module VM
|
||||
# Helper methods for forwarding ports. Requires that the environment
|
||||
# is set to the `@env` instance variable.
|
||||
module ForwardPortsHelpers
|
||||
# Returns an array of used ports. This method is implemented
|
||||
# differently depending on the VirtualBox version, but the
|
||||
# behavior is the same.
|
||||
#
|
||||
# @return [Array<String>]
|
||||
def used_ports
|
||||
result = VirtualBox::VM.all.collect do |vm|
|
||||
if vm.accessible? && vm.running? && vm.uuid != @env["vm"].uuid
|
||||
vm.network_adapters.collect do |na|
|
||||
na.nat_driver.forwarded_ports.collect do |fp|
|
||||
fp.hostport.to_i
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
result.flatten.uniq
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -24,6 +24,59 @@ module Vagrant
|
|||
end
|
||||
end
|
||||
|
||||
# This clears the forwarded ports that have been set on the
|
||||
# virtual machine.
|
||||
def clear_forwarded_ports
|
||||
args = []
|
||||
read_forwarded_ports(@uuid).each do |nic, name, _, _|
|
||||
args.concat(["--natpf#{nic}", "delete", name])
|
||||
end
|
||||
|
||||
execute("modifyvm", @uuid, *args) if !args.empty?
|
||||
end
|
||||
|
||||
# This deletes the VM with the given name.
|
||||
def delete
|
||||
execute("unregistervm", @uuid, "--delete")
|
||||
end
|
||||
|
||||
# Forwards a set of ports for a VM.
|
||||
#
|
||||
# This will not affect any previously set forwarded ports,
|
||||
# so be sure to delete those if you need to.
|
||||
#
|
||||
# The format of each port hash should be the following:
|
||||
#
|
||||
# {
|
||||
# :name => "foo",
|
||||
# :host_port => 8500,
|
||||
# :guest_port => 80,
|
||||
# :adapter => 1,
|
||||
# :protocol => "tcp"
|
||||
# }
|
||||
#
|
||||
# Note that "adapter" and "protocol" are optional and will default
|
||||
# to 1 and "tcp" respectively.
|
||||
#
|
||||
# @param [Array<Hash>] ports An array of ports to set. See documentation
|
||||
# for more information on the format.
|
||||
def forward_ports(ports)
|
||||
args = []
|
||||
ports.each do |options|
|
||||
pf_builder = [options[:name],
|
||||
options[:protocol] || "tcp",
|
||||
"",
|
||||
options[:host_port],
|
||||
"",
|
||||
options[:guest_port]]
|
||||
|
||||
args.concat(["--natpf#{options[:adapter] || 1}",
|
||||
pf_builder.join(",")])
|
||||
end
|
||||
|
||||
execute("modifyvm", @uuid, *args)
|
||||
end
|
||||
|
||||
# Imports the VM with the given path to the OVF file. It returns
|
||||
# the UUID as a string.
|
||||
def import(ovf, name)
|
||||
|
@ -36,11 +89,6 @@ module Vagrant
|
|||
nil
|
||||
end
|
||||
|
||||
# This deletes the VM with the given name.
|
||||
def delete
|
||||
execute("unregistervm", @uuid, "--delete")
|
||||
end
|
||||
|
||||
# This reads the guest additions version for a VM.
|
||||
def read_guest_additions_version
|
||||
output = execute("guestproperty", "get", @uuid, "/VirtualBox/GuestAdd/Version")
|
||||
|
@ -61,6 +109,21 @@ module Vagrant
|
|||
nil
|
||||
end
|
||||
|
||||
# This will read all the used ports for port forwarding by
|
||||
# all virtual machines.
|
||||
def read_used_ports
|
||||
ports = []
|
||||
execute("list", "vms").split("\n").each do |line|
|
||||
if line =~ /^".+?" \{(.+?)\}$/
|
||||
read_forwarded_ports($1.to_s, true).each do |_, _, hostport, _|
|
||||
ports << hostport
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ports
|
||||
end
|
||||
|
||||
# This sets the MAC address for a network adapter.
|
||||
def set_mac_address(mac)
|
||||
execute("modifyvm", @uuid, "--macaddress1", mac)
|
||||
|
@ -68,6 +131,33 @@ module Vagrant
|
|||
|
||||
protected
|
||||
|
||||
# This returns a list of the forwarded ports in the form
|
||||
# of `[nic, name, hostport, guestport]`.
|
||||
#
|
||||
# @return [Array<Array>]
|
||||
def read_forwarded_ports(uuid, active_only=false)
|
||||
results = []
|
||||
current_nic = nil
|
||||
execute("showvminfo", uuid, "--machinereadable").split("\n").each do |line|
|
||||
# This is how we find the nic that a FP is attached to,
|
||||
# since this comes first.
|
||||
current_nic = $1.to_i if line =~ /^nic(\d+)=".+?"$/
|
||||
|
||||
# If we care about active VMs only, then we check the state
|
||||
# to verify the VM is running.
|
||||
if active_only && line =~ /^VMState="(.+?)"$/ && $1.to_s != "running"
|
||||
return []
|
||||
end
|
||||
|
||||
# Parse out the forwarded port information
|
||||
if line =~ /^Forwarding.+?="(.+?),.+?,.*?,(.+?),.*?,(.+?)"$/
|
||||
results << [current_nic, $1.to_s, $2.to_i, $3.to_i]
|
||||
end
|
||||
end
|
||||
|
||||
results
|
||||
end
|
||||
|
||||
# This returns the version of VirtualBox that is running.
|
||||
#
|
||||
# @return [String]
|
||||
|
|
Loading…
Reference in New Issue