Class: Capistrano::Gateway
- Inherits:
-
Object
- Object
- Capistrano::Gateway
- Defined in:
- lib/capistrano/gateway.rb
Overview
Black magic. It uses threads and Net::SSH to set up a connection to a gateway server, through which connections to other servers may be tunnelled.
It is used internally by Capistrano, but may be useful on its own, as well.
Usage:
gateway = Capistrano::Gateway.new(Capistrano::ServerDefinition.new('gateway.example.com'))
sess1 = gateway.connect_to(Capistrano::ServerDefinition.new('hidden.example.com'))
sess2 = gateway.connect_to(Capistrano::ServerDefinition.new('other.example.com'))
Constant Summary collapse
- MAX_PORT =
65535
- MIN_PORT =
1024
Instance Attribute Summary collapse
-
#session ⇒ Object
readonly
The Net::SSH session representing the gateway connection.
-
#thread ⇒ Object
readonly
The Thread instance driving the gateway connection.
Instance Method Summary collapse
-
#connect_to(server) ⇒ Object
Connects to the given server by opening a forwarded port from the local host to the server, via the gateway, and then opens and returns a new Net::SSH connection via that port.
-
#initialize(server, options = {}) ⇒ Gateway
constructor
:nodoc:.
-
#shutdown! ⇒ Object
Shuts down all forwarded connections and terminates the gateway.
Constructor Details
#initialize(server, options = {}) ⇒ Gateway
:nodoc:
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/capistrano/gateway.rb', line 43 def initialize(server, ={}) #:nodoc: @options = @next_port = MAX_PORT @terminate_thread = false @port_guard = Mutex.new mutex = Mutex.new waiter = ConditionVariable.new mutex.synchronize do @thread = Thread.new do logger.trace "starting connection to gateway `#{server}'" if logger SSH.connect(server, @options) do |@session| logger.trace "gateway connection established" if logger mutex.synchronize { waiter.signal } @session.loop do !@terminate_thread end end end waiter.wait(mutex) end end |
Instance Attribute Details
#session ⇒ Object (readonly)
The Net::SSH session representing the gateway connection.
38 39 40 |
# File 'lib/capistrano/gateway.rb', line 38 def session @session end |
#thread ⇒ Object (readonly)
The Thread instance driving the gateway connection.
35 36 37 |
# File 'lib/capistrano/gateway.rb', line 35 def thread @thread end |
Instance Method Details
#connect_to(server) ⇒ Object
Connects to the given server by opening a forwarded port from the local host to the server, via the gateway, and then opens and returns a new Net::SSH connection via that port.
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/capistrano/gateway.rb', line 85 def connect_to(server) connection = nil logger.debug "establishing connection to `#{server}' via gateway" if logger local_port = next_port thread = Thread.new do begin local_host = ServerDefinition.new("127.0.0.1", :user => server.user, :port => local_port) session.forward.local(local_port, server.host, server.port || 22) connection = SSH.connect(local_host, @options) connection.xserver = server logger.trace "connected: `#{server}' (via gateway)" if logger rescue Errno::EADDRINUSE local_port = next_port retry rescue Exception => e warn "#{e.class}: #{e.}" warn e.backtrace.join("\n") end end thread.join if connection.nil? error = ConnectionError.new("could not establish connection to `#{server}'") error.hosts = [server] raise error end connection end |
#shutdown! ⇒ Object
Shuts down all forwarded connections and terminates the gateway.
69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/capistrano/gateway.rb', line 69 def shutdown! # cancel all active forward channels session.forward.active_locals.each do |lport, host, port| session.forward.cancel_local(lport) end # terminate the gateway thread @terminate_thread = true # wait for the gateway thread to stop thread.join end |