Class: Aptible::CLI::Helpers::Tunnel
- Inherits:
-
Object
- Object
- Aptible::CLI::Helpers::Tunnel
- Defined in:
- lib/aptible/cli/helpers/tunnel.rb
Instance Method Summary collapse
-
#initialize(env, ssh_cmd, socket_path) ⇒ Tunnel
constructor
A new instance of Tunnel.
- #port ⇒ Object
- #start(desired_port = 0) ⇒ Object
- #stop ⇒ Object
- #wait ⇒ Object
Constructor Details
#initialize(env, ssh_cmd, socket_path) ⇒ Tunnel
Returns a new instance of Tunnel.
28 29 30 31 32 |
# File 'lib/aptible/cli/helpers/tunnel.rb', line 28 def initialize(env, ssh_cmd, socket_path) @env = env @ssh_cmd = ssh_cmd @socket_path = socket_path end |
Instance Method Details
#port ⇒ Object
100 101 102 103 |
# File 'lib/aptible/cli/helpers/tunnel.rb', line 100 def port raise 'You must call #start before calling #port!' if @local_port.nil? @local_port end |
#start(desired_port = 0) ⇒ Object
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/aptible/cli/helpers/tunnel.rb', line 34 def start(desired_port = 0) @local_port = desired_port @local_port = random_local_port if @local_port.zero? tunnel_cmd = @ssh_cmd + [ '-L', "#{@local_port}:#{@socket_path}", '-o', 'ExitOnForwardFailure=yes' ] out_read, out_write = IO.pipe err_read, err_write = IO.pipe @pid = Process.spawn(@env, *tunnel_cmd, SPAWN_OPTS .merge(in: :close, out: out_write, err: err_write)) # Wait for the tunnel to come up before returning. The other end # will send a message on stdout to indicate that the tunnel is ready. [out_write, err_write].map(&:close) begin out_read.readline rescue EOFError stop raise UserError, "Tunnel did not come up: #{err_read.read}" ensure [out_read, err_read].map(&:close) end end |
#stop ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/aptible/cli/helpers/tunnel.rb', line 62 def stop raise 'You must call #start before calling #stop' if @pid.nil? begin Process.kill(STOP_SIGNAL, @pid) rescue Errno::ESRCH # Already dead. return end begin STOP_TIMEOUT.times do return if Process.wait(@pid, Process::WNOHANG) sleep 1 end Process.kill(:SIGKILL, @pid) rescue Errno::ECHILD, Errno::ESRCH # Died at some point, that's fine. end end |
#wait ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/aptible/cli/helpers/tunnel.rb', line 83 def wait # NOTE: Ruby is kind enough to retry when EINTR is thrown, so we # don't need to retry or anything here. _, status = Process.wait2(@pid) code = status.exitstatus case code when 0 # No-op: we're happy with this. when 124 raise Thor::Error, 'Tunnel timed out' else raise Thor::Error, "Tunnel crashed (#{code})" end end |