Clear forwarded ports middleware

This commit is contained in:
Mitchell Hashimoto 2010-07-09 10:14:26 -07:00
parent 8bd64de61d
commit 409be1146f
8 changed files with 221 additions and 140 deletions

View File

@ -16,6 +16,7 @@ module Vagrant
# environment.
start = Builder.new do
use VM::Customize
use VM::ClearForwardedPorts
use VM::ForwardPorts
use VM::Provision
use VM::ClearSharedFolders

View File

@ -0,0 +1,39 @@
require File.join(File.dirname(__FILE__), 'forward_ports_helpers')
module Vagrant
class Action
module VM
class ClearForwardedPorts
include ForwardPortsHelpers
def initialize(app, env)
@app = app
@env = env
end
def call(env)
@env = env
clear
@app.call(env)
end
def clear
if used_ports.length > 0
@env.logger.info "Deleting any previously set forwarded ports..."
clear_ports
@env["vm"].reload!
end
end
# Deletes existing forwarded ports.
def clear_ports
@env["vm"].vm.network_adapters.each do |na|
na.nat_driver.forwarded_ports.dup.each do |fp|
fp.destroy
end
end
end
end
end
end
end

View File

@ -1,7 +1,11 @@
require File.join(File.dirname(__FILE__), 'forward_ports_helpers')
module Vagrant
class Action
module VM
class ForwardPorts
include ForwardPortsHelpers
def initialize(app,env)
@app = app
@env = env
@ -63,20 +67,11 @@ module Vagrant
def call(env)
@env = env
clear
forward_ports
@app.call(env)
end
def clear
if used_ports.length > 0
@env.logger.info "Deleting any previously set forwarded ports..."
clear_ports
@env["vm"].reload!
end
end
def forward_ports
@env.logger.info "Forwarding ports..."
@ -103,34 +98,6 @@ module Vagrant
# General Helpers
#--------------------------------------------------------------
# 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.running? && vm.uuid != @env["vm"].uuid
vm.network_adapters.collect do |na|
na.nat_driver.forwarded_ports.collect do |fp|
fp.hostport.to_s
end
end
end
end
result.flatten.uniq
end
# Deletes existing forwarded ports.
def clear_ports
@env["vm"].vm.network_adapters.each do |na|
na.nat_driver.forwarded_ports.dup.each do |fp|
fp.destroy
end
end
end
# Forwards a port.
def forward_port(name, options)
port = VirtualBox::NATForwardedPort.new

View File

@ -0,0 +1,28 @@
module Vagrant
class 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.running? && vm.uuid != @env["vm"].uuid
vm.network_adapters.collect do |na|
na.nat_driver.forwarded_ports.collect do |fp|
fp.hostport.to_s
end
end
end
end
result.flatten.uniq
end
end
end
end
end

View File

@ -0,0 +1,72 @@
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
class ClearForwardedPortsVMActionTest < Test::Unit::TestCase
setup do
@klass = Vagrant::Action::VM::ClearForwardedPorts
@app, @env = mock_action_data
@vm = mock("vm")
@vm.stubs(:name).returns("foo")
@env["vm"] = @vm
@instance = @klass.new(@app, @env)
end
context "calling" do
should "call the proper methods and continue chain" do
seq = sequence('seq')
@instance.expects(:clear).in_sequence(seq)
@app.expects(:call).with(@env).in_sequence(seq)
@instance.call(@env)
end
end
context "clearing forwarded ports" do
setup do
@instance.stubs(:used_ports).returns([:a])
@instance.stubs(:clear_ports)
end
should "call destroy on all forwarded ports" do
@instance.expects(:clear_ports).once
@vm.expects(:reload!)
@instance.clear
end
should "do nothing if there are no forwarded ports" do
@instance.stubs(:used_ports).returns([])
@vm.expects(:reload!).never
@instance.clear
end
end
context "clearing ports" do
def mock_fp
fp = mock("fp")
fp.expects(:destroy).once
fp
end
setup do
VirtualBox.stubs(:version).returns("3.2.8")
@adapters = []
@internal_vm = mock("internal_vm")
@internal_vm.stubs(:network_adapters).returns(@adapters)
@vm.stubs(:vm).returns(@internal_vm)
end
def mock_adapter
na = mock("adapter")
engine = mock("engine")
engine.stubs(:forwarded_ports).returns([mock_fp])
na.stubs(:nat_driver).returns(engine)
na
end
should "destroy each forwarded port" do
@adapters << mock_adapter
@adapters << mock_adapter
@instance.clear_ports
end
end
end

View File

@ -0,0 +1,70 @@
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
class ForwardPortsHelpersVMActionTest < Test::Unit::TestCase
setup do
@klass = Class.new do
def initialize(env); @env = env; end
end
@klass.send(:include, Vagrant::Action::VM::ForwardPortsHelpers)
@app, @env = mock_action_data
@vm = mock("vm")
@vm.stubs(:name).returns("foo")
@env["vm"] = @vm
@instance = @klass.new(@env)
end
context "getting list of used ports" do
setup do
@vms = []
VirtualBox::VM.stubs(:all).returns(@vms)
VirtualBox.stubs(:version).returns("3.1.0")
@vm.stubs(:uuid).returns(:bar)
end
def mock_vm(options={})
options = {
:running? => true,
:uuid => :foo
}.merge(options)
vm = mock("vm")
options.each do |k,v|
vm.stubs(k).returns(v)
end
vm
end
def mock_fp(hostport)
fp = mock("fp")
fp.stubs(:hostport).returns(hostport.to_s)
fp
end
should "ignore VMs which aren't running" do
@vms << mock_vm(:running? => false)
@vms[0].expects(:forwarded_ports).never
@instance.used_ports
end
should "ignore VMs of the same uuid" do
@vms << mock_vm(:uuid => @vm.uuid)
@vms[0].expects(:forwarded_ports).never
@instance.used_ports
end
should "return the forwarded ports for VB 3.2.x" do
VirtualBox.stubs(:version).returns("3.2.4")
fps = [mock_fp(2222), mock_fp(80)]
na = mock("na")
ne = mock("ne")
na.stubs(:nat_driver).returns(ne)
ne.stubs(:forwarded_ports).returns(fps)
@vms << mock_vm(:network_adapters => [na])
assert_equal %W[2222 80], @instance.used_ports
end
end
end

View File

@ -97,7 +97,6 @@ class ForwardPortsVMActionTest < Test::Unit::TestCase
context "calling" do
should "clear all previous ports and forward new ports" do
exec_seq = sequence("exec_seq")
@instance.expects(:clear).once.in_sequence(exec_seq)
@instance.expects(:forward_ports).once.in_sequence(exec_seq)
@app.expects(:call).once.with(@env).in_sequence(exec_seq)
@instance.call(@env)
@ -135,107 +134,6 @@ class ForwardPortsVMActionTest < Test::Unit::TestCase
end
end
context "clearing forwarded ports" do
setup do
@instance.stubs(:used_ports).returns([:a])
@instance.stubs(:clear_ports)
end
should "call destroy on all forwarded ports" do
@instance.expects(:clear_ports).once
@vm.expects(:reload!)
@instance.clear
end
should "do nothing if there are no forwarded ports" do
@instance.stubs(:used_ports).returns([])
@vm.expects(:reload!).never
@instance.clear
end
end
context "getting list of used ports" do
setup do
@vms = []
VirtualBox::VM.stubs(:all).returns(@vms)
VirtualBox.stubs(:version).returns("3.1.0")
@vm.stubs(:uuid).returns(:bar)
end
def mock_vm(options={})
options = {
:running? => true,
:uuid => :foo
}.merge(options)
vm = mock("vm")
options.each do |k,v|
vm.stubs(k).returns(v)
end
vm
end
def mock_fp(hostport)
fp = mock("fp")
fp.stubs(:hostport).returns(hostport.to_s)
fp
end
should "ignore VMs which aren't running" do
@vms << mock_vm(:running? => false)
@vms[0].expects(:forwarded_ports).never
@instance.used_ports
end
should "ignore VMs of the same uuid" do
@vms << mock_vm(:uuid => @vm.uuid)
@vms[0].expects(:forwarded_ports).never
@instance.used_ports
end
should "return the forwarded ports for VB 3.2.x" do
VirtualBox.stubs(:version).returns("3.2.4")
fps = [mock_fp(2222), mock_fp(80)]
na = mock("na")
ne = mock("ne")
na.stubs(:nat_driver).returns(ne)
ne.stubs(:forwarded_ports).returns(fps)
@vms << mock_vm(:network_adapters => [na])
assert_equal %W[2222 80], @instance.used_ports
end
end
context "clearing ports" do
def mock_fp
fp = mock("fp")
fp.expects(:destroy).once
fp
end
setup do
VirtualBox.stubs(:version).returns("3.2.8")
@adapters = []
@internal_vm = mock("internal_vm")
@internal_vm.stubs(:network_adapters).returns(@adapters)
@vm.stubs(:vm).returns(@internal_vm)
end
def mock_adapter
na = mock("adapter")
engine = mock("engine")
engine.stubs(:forwarded_ports).returns([mock_fp])
na.stubs(:nat_driver).returns(engine)
na
end
should "destroy each forwarded port" do
@adapters << mock_adapter
@adapters << mock_adapter
@instance.clear_ports
end
end
context "forwarding ports implementation" do
setup do
VirtualBox.stubs(:version).returns("3.2.8")

View File

@ -9,7 +9,7 @@ Gem::Specification.new do |s|
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
s.authors = ["Mitchell Hashimoto", "John Bender"]
s.date = %q{2010-07-08}
s.date = %q{2010-07-09}
s.default_executable = %q{vagrant}
s.description = %q{Vagrant is a tool for building and distributing virtualized development environments.}
s.email = ["mitchell.hashimoto@gmail.com", "john.m.bender@gmail.com"]
@ -46,12 +46,14 @@ Gem::Specification.new do |s|
"lib/vagrant/action/exception_catcher.rb",
"lib/vagrant/action/vm/boot.rb",
"lib/vagrant/action/vm/check_guest_additions.rb",
"lib/vagrant/action/vm/clear_forwarded_ports.rb",
"lib/vagrant/action/vm/clear_shared_folders.rb",
"lib/vagrant/action/vm/customize.rb",
"lib/vagrant/action/vm/destroy.rb",
"lib/vagrant/action/vm/destroy_unused_network_interfaces.rb",
"lib/vagrant/action/vm/export.rb",
"lib/vagrant/action/vm/forward_ports.rb",
"lib/vagrant/action/vm/forward_ports_helpers.rb",
"lib/vagrant/action/vm/halt.rb",
"lib/vagrant/action/vm/import.rb",
"lib/vagrant/action/vm/match_mac_address.rb",
@ -126,11 +128,13 @@ Gem::Specification.new do |s|
"test/vagrant/action/exception_catcher_test.rb",
"test/vagrant/action/vm/boot_test.rb",
"test/vagrant/action/vm/check_guest_additions_test.rb",
"test/vagrant/action/vm/clear_forwarded_ports_test.rb",
"test/vagrant/action/vm/clear_shared_folders_test.rb",
"test/vagrant/action/vm/customize_test.rb",
"test/vagrant/action/vm/destroy_test.rb",
"test/vagrant/action/vm/destroy_unused_network_interfaces_test.rb",
"test/vagrant/action/vm/export_test.rb",
"test/vagrant/action/vm/forward_ports_helpers_test.rb",
"test/vagrant/action/vm/forward_ports_test.rb",
"test/vagrant/action/vm/halt_test.rb",
"test/vagrant/action/vm/import_test.rb",
@ -204,11 +208,13 @@ Gem::Specification.new do |s|
"test/vagrant/action/exception_catcher_test.rb",
"test/vagrant/action/vm/boot_test.rb",
"test/vagrant/action/vm/check_guest_additions_test.rb",
"test/vagrant/action/vm/clear_forwarded_ports_test.rb",
"test/vagrant/action/vm/clear_shared_folders_test.rb",
"test/vagrant/action/vm/customize_test.rb",
"test/vagrant/action/vm/destroy_test.rb",
"test/vagrant/action/vm/destroy_unused_network_interfaces_test.rb",
"test/vagrant/action/vm/export_test.rb",
"test/vagrant/action/vm/forward_ports_helpers_test.rb",
"test/vagrant/action/vm/forward_ports_test.rb",
"test/vagrant/action/vm/halt_test.rb",
"test/vagrant/action/vm/import_test.rb",