Implement `forward_port` method for VMs in configuration

This commit is contained in:
Mitchell Hashimoto 2010-02-03 00:02:12 -08:00
parent b2b2cfd68b
commit 7971d656fe
7 changed files with 64 additions and 27 deletions

View File

@ -3,11 +3,12 @@ Hobo::Config.run do |config|
config.ssh.uname = "hobo" config.ssh.uname = "hobo"
config.ssh.pass = "hobo" config.ssh.pass = "hobo"
config.ssh.host = "localhost" config.ssh.host = "localhost"
config.ssh.port = 2222 config.ssh.forwarded_port_key = "ssh"
config.ssh.max_tries = 10 config.ssh.max_tries = 10
config.dotfile_name = ".hobo" config.dotfile_name = ".hobo"
config.vm.base = "~/.hobo/base/base.ovf" config.vm.base = "~/.hobo/base/base.ovf"
config.vm.base_mac = "0800279C2E41" config.vm.base_mac = "0800279C2E41"
config.vm.forward_port("ssh", 22, 2222)
end end

View File

@ -41,13 +41,26 @@ module Hobo
attr_accessor :uname attr_accessor :uname
attr_accessor :pass attr_accessor :pass
attr_accessor :host attr_accessor :host
attr_accessor :port attr_accessor :forwarded_port_key
attr_accessor :max_tries attr_accessor :max_tries
end end
class VMConfig < Base class VMConfig < Base
attr_accessor :base attr_accessor :base
attr_accessor :base_mac attr_accessor :base_mac
attr_reader :forwarded_ports
def initialize
@forwarded_ports = {}
end
def forward_port(name, guestport, hostport, protocol="TCP")
forwarded_ports[name] = {
:guestport => guestport,
:hostport => hostport,
:protocol => protocol
}
end
end end
class Top < Base class Top < Base

View File

@ -5,21 +5,26 @@ module Hobo
class << self class << self
def connect(opts={}) def connect(opts={})
options = {} options = {}
[:port, :host, :pass, :uname].each do |param| [:host, :pass, :uname].each do |param|
options[param] = opts[param] || Hobo.config.ssh.send(param) options[param] = opts[param] || Hobo.config.ssh.send(param)
end end
# The port is special
options[:port] = opts[:port] || Hobo.config.vm.forwarded_ports[Hobo.config.ssh.forwarded_port_key][:hostport]
Kernel.exec "#{SCRIPT} #{options[:uname]} #{options[:pass]} #{options[:host]} #{options[:port]}".strip Kernel.exec "#{SCRIPT} #{options[:uname]} #{options[:pass]} #{options[:host]} #{options[:port]}".strip
end end
def execute def execute
Net::SSH.start("localhost", Hobo.config[:ssh][:uname], :port => Hobo.config[:ssh][:port], :password => Hobo.config[:ssh][:pass]) do |ssh| port = Hobo.config.vm.forwarded_ports[Hobo.config.ssh.forwarded_port_key][:hostport]
Net::SSH.start("localhost", Hobo.config[:ssh][:uname], :port => port, :password => Hobo.config[:ssh][:pass]) do |ssh|
yield ssh yield ssh
end end
end end
def up? def up?
Ping.pingecho "localhost", 1, Hobo.config[:ssh][:port] port = Hobo.config.vm.forwarded_ports[Hobo.config.ssh.forwarded_port_key][:hostport]
Ping.pingecho "localhost", 1, port
end end
end end
end end

View File

@ -23,7 +23,7 @@ module Hobo
SSH.connect SSH.connect
end end
# Save the state of the current hobo environment to disk # Save the state of the current hobo environment to disk
def suspend def suspend
Env.require_persisted_vm Env.require_persisted_vm
@ -61,7 +61,7 @@ error
import import
persist persist
setup_mac_address setup_mac_address
forward_ssh forward_ports
setup_shared_folder setup_shared_folder
start start
end end
@ -92,13 +92,18 @@ error
@vm.save(true) @vm.save(true)
end end
def forward_ssh def forward_ports
HOBO_LOGGER.info "Forwarding SSH ports..." HOBO_LOGGER.info "Forwarding ports..."
port = VirtualBox::ForwardedPort.new
port.name = "ssh" Hobo.config.vm.forwarded_ports.each do |name, options|
port.hostport = Hobo.config[:ssh][:port] HOBO_LOGGER.info "Forwarding \"#{name}\": #{options[:guestport]} => #{options[:hostport]}"
port.guestport = 22 port = VirtualBox::ForwardedPort.new
@vm.forwarded_ports << port port.name = name
port.hostport = options[:hostport]
port.guestport = options[:guestport]
@vm.forwarded_ports << port
end
@vm.save(true) @vm.save(true)
end end
@ -117,11 +122,11 @@ error
# Now we have to wait for the boot to be successful # Now we have to wait for the boot to be successful
HOBO_LOGGER.info "Waiting for VM to boot..." HOBO_LOGGER.info "Waiting for VM to boot..."
Hobo.config[:ssh][:max_tries].to_i.times do |i| Hobo.config[:ssh][:max_tries].to_i.times do |i|
sleep 5 unless ENV['HOBO_ENV'] == 'test' sleep 5 unless ENV['HOBO_ENV'] == 'test'
HOBO_LOGGER.info "Trying to connect (attempt ##{i+1} of #{Hobo.config[:ssh][:max_tries]})..." HOBO_LOGGER.info "Trying to connect (attempt ##{i+1} of #{Hobo.config[:ssh][:max_tries]})..."
if Hobo::SSH.up? if Hobo::SSH.up?
HOBO_LOGGER.info "VM booted and ready for use!" HOBO_LOGGER.info "VM booted and ready for use!"
return true return true
@ -133,7 +138,7 @@ error
end end
def saved?; @vm.saved? end def saved?; @vm.saved? end
def save_state(errs); @vm.save_state(errs) end def save_state(errs); @vm.save_state(errs) end
end end
end end

View File

@ -1,15 +1,19 @@
require File.join(File.dirname(__FILE__), '..', 'test_helper') require File.join(File.dirname(__FILE__), '..', 'test_helper')
class SshTest < Test::Unit::TestCase class SshTest < Test::Unit::TestCase
setup do
hobo_mock_config
end
context "hobo ssh" do context "hobo ssh" do
setup do setup do
@script = Hobo::SSH::SCRIPT @script = Hobo::SSH::SCRIPT
hobo_mock_config
end end
test "should call exec with defaults when no options are supplied" do test "should call exec with defaults when no options are supplied" do
ssh = Hobo.config.ssh ssh = Hobo.config.ssh
Kernel.expects(:exec).with("#{@script} #{ssh[:uname]} #{ssh[:pass]} #{ssh[:host]} #{ssh[:port]}") port = Hobo.config.vm.forwarded_ports[ssh.forwarded_port_key][:hostport]
Kernel.expects(:exec).with("#{@script} #{ssh[:uname]} #{ssh[:pass]} #{ssh[:host]} #{port}")
Hobo::SSH.connect Hobo::SSH.connect
end end
@ -26,4 +30,12 @@ class SshTest < Test::Unit::TestCase
Hobo::SSH.execute Hobo::SSH.execute
end end
end end
context "checking if host is up" do
should "pingecho the server" do
port = Hobo.config.vm.forwarded_ports[Hobo.config.ssh.forwarded_port_key][:hostport]
Ping.expects(:pingecho).with("localhost", 1, port).once
Hobo::SSH.up?
end
end
end end

View File

@ -77,7 +77,7 @@ class VMTest < Test::Unit::TestCase
@vm.expects(:import).in_sequence(create_seq) @vm.expects(:import).in_sequence(create_seq)
@vm.expects(:persist).in_sequence(create_seq) @vm.expects(:persist).in_sequence(create_seq)
@vm.expects(:setup_mac_address).in_sequence(create_seq) @vm.expects(:setup_mac_address).in_sequence(create_seq)
@vm.expects(:forward_ssh).in_sequence(create_seq) @vm.expects(:forward_ports).in_sequence(create_seq)
@vm.expects(:setup_shared_folder).in_sequence(create_seq) @vm.expects(:setup_shared_folder).in_sequence(create_seq)
@vm.expects(:start).in_sequence(create_seq) @vm.expects(:start).in_sequence(create_seq)
@vm.create @vm.create
@ -157,7 +157,7 @@ class VMTest < Test::Unit::TestCase
end end
end end
context "forwarding SSH" do context "forwarding ports" do
should "create a port forwarding for the VM" do should "create a port forwarding for the VM" do
# TODO: Test the actual port value to make sure it has the # TODO: Test the actual port value to make sure it has the
# correct attributes # correct attributes
@ -165,7 +165,7 @@ class VMTest < Test::Unit::TestCase
forwarded_ports.expects(:<<) forwarded_ports.expects(:<<)
@mock_vm.expects(:forwarded_ports).returns(forwarded_ports) @mock_vm.expects(:forwarded_ports).returns(forwarded_ports)
@mock_vm.expects(:save).with(true).once @mock_vm.expects(:save).with(true).once
@vm.forward_ssh @vm.forward_ports
end end
end end
@ -184,7 +184,7 @@ class VMTest < Test::Unit::TestCase
end end
context "suspending and resuming a vm" do context "suspending and resuming a vm" do
should "put the vm in a suspended state" do should "put the vm in a suspended state" do
saved_state_expectation(false) saved_state_expectation(false)
save_expectation save_expectation
Hobo::VM.suspend Hobo::VM.suspend
@ -197,7 +197,7 @@ class VMTest < Test::Unit::TestCase
Hobo::VM.suspend Hobo::VM.suspend
end end
should "start a vm in a suspended state" do should "start a vm in a suspended state" do
saved_state_expectation(true) saved_state_expectation(true)
start_expectation start_expectation
Hobo::VM.resume Hobo::VM.resume
@ -209,12 +209,12 @@ class VMTest < Test::Unit::TestCase
# TODO research the matter of mocking exit # TODO research the matter of mocking exit
Hobo::VM.expects(:error_and_exit) Hobo::VM.expects(:error_and_exit)
Hobo::VM.resume Hobo::VM.resume
end end
def saved_state_expectation(saved) def saved_state_expectation(saved)
@persisted_vm.expects(:saved?).returns(saved) @persisted_vm.expects(:saved?).returns(saved)
end end
def save_expectation def save_expectation
@persisted_vm.expects(:save_state).with(true) @persisted_vm.expects(:save_state).with(true)
end end

View File

@ -37,11 +37,12 @@ class Test::Unit::TestCase
config.ssh.uname = "foo" config.ssh.uname = "foo"
config.ssh.pass = "bar" config.ssh.pass = "bar"
config.ssh.host = "baz" config.ssh.host = "baz"
config.ssh.port = "bak" config.ssh.forwarded_port_key = "ssh"
config.ssh.max_tries = 10 config.ssh.max_tries = 10
config.vm.base = "foo" config.vm.base = "foo"
config.vm.base_mac = "42" config.vm.base_mac = "42"
config.vm.forward_port("ssh", 22, 2222)
end end
Hobo::Config.execute! Hobo::Config.execute!