Using a remote tunnel in a capistrano task

768 views
Skip to first unread message

Hal Black

unread,
Sep 6, 2008, 4:51:23 PM9/6/08
to Capistrano
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?

Jamis Buck

unread,
Sep 6, 2008, 5:20:51 PM9/6/08
to capis...@googlegroups.com
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
> -~----------~----~----~----~------~----~------~--~---
>

Hal Black

unread,
Sep 7, 2008, 11:55:37 PM9/7/08
to Capistrano
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
Reply all
Reply to author
Forward
0 new messages