Using a remote tunnel in a capistrano task

Showing 1-3 of 3 messages
Using a remote tunnel in a capistrano task Hal Black 9/6/08 1:51 PM
Versions:
net-ssh-2.0.4
capistrano-2.5.0
ruby 1.8.7 (2008-06-20 patchlevel 22)

I'm trying to use a remote tunnel in a capistrano task, so that the
remote port will be reflected back to localhost for the duration of a
command.  I've got something like this:

  desc "Tunnel test"
  task :test_tunnel do
    port=90
    loopback="127.0.0.1"
    Net::SSH.start("example.com", "root") do |ssh|
      ssh.forward.remote(port, "localhost", port)
      ssh.loop { !ssh.forward.active_remotes.include?([port,
loopback]) }
      Thread.new {
        run "some_command"
        ssh.forward.cancel_remote(port, loopback)
      }
      ssh.loop { ssh.forward.active_remotes.include?([port,
loopback]) }
    end
  end

And I never get out of that last ssh.loop.  But I have to be in that
last loop or the tunnel freezes.
Other things I tried:
 o Not putting the run command in its own thread: freezes the tunnel.
 o Doing a join on the thread instead of looping and cancel_remote:
freezes the tunnel.

Any ideas?
Re: [Capistrano] Using a remote tunnel in a capistrano task Jamis Buck 9/6/08 2:20 PM
Hal,

You might want to look at the net-ssh-gateway library to see how it  
works. It runs the forwarded ports in a separate Net::SSH instance, in  
a separate thread. Currently it only supports locally forwarded ports,  
but perhaps it could be extended to work with remote forwarded ports  
too?

- Jamis

> --~--~---------~--~----~------------~-------~--~----~
> To unsubscribe from this group, send email to capistrano-...@googlegroups.com
> For more options, visit this group at http://groups.google.com/group/capistrano
> -~----------~----~----~----~------~----~------~--~---
>

Re: Using a remote tunnel in a capistrano task Hal Black 9/7/08 8:55 PM
Jamis,
   Thank you so much for your suggestion.  I extended gateway to work
with remote ports and it works perfectly.

If anyone wants it, here's what I did.  It's nothing earth-shattering,
I just copied the local forwarding methods and adapted them for
forward.remote.

class Net::SSH::Gateway
  # Opens a SSH tunnel from a port on a remote host to a given host
and port
  # on the local side
  # (equivalent to openssh -R parameter)
  def open_remote(port, host, remote_port, remote_host = "127.0.0.1")
    ensure_open!

    @session_mutex.synchronize do
      @session.forward.remote(port, host, remote_port, remote_host)
    end

    if block_given?
      begin
        yield [remote_port, remote_host]
      ensure
        close_remote(remote_port, remote_host)
      end
    else
      return [remote_port, remote_host]
    end
  rescue Errno::EADDRINUSE
    retry
  end


  # Cancels port-forwarding over an open port that was previously
opened via
  # #open_remote.
  def close_remote(port, host = "127.0.0.1")
    ensure_open!

    @session_mutex.synchronize do
      @session.forward.cancel_remote(port, host)
    end
  end
end
>  smime.p7s
> 3KViewDownload