I have the following Port Forwarding created with Net::SSH:
def connectToCustomerSystem
Net::SSH.start("localhost", 'myuser', :password => "password") do |ssh|
logger.debug ssh.exec!("hostname")
ssh.forward.local(1234, "www.capify.org", 80)
#ssh.loop { true } #dont use loop to directly render director/index
end
render :controller => "director", :action => "index"
end
Now i will cancel this Connection via “ssh.forward.cancel_local(1234)” in a new, other method.
def disconnectForwarding
ssh.forward.cancel_local(1234)
end
But, of course, “ssh” isnt valid in this context. How could i search all available Objects with Type “Net::SSH”? Or are there any other ways how i could quit a specific Forwarding (because in the end, there will be much Forwards for some different Users, and i dont want to kill all, just a specific one).
Thanks in advance.
I see you’re trying to keep stateful Ruby objects around while interacting with Rails. This doesn’t play well with the Rails “shared nothing” approach to servers. Not only will ssh not be in scope because of the block being out of scope for your method, you will be talking to a different worker process next time.
What you need is separate longer running ruby processes in the background to manage the ssh connection. A simple way to do this is launch a ruby script and connect to the object managing ssh using DRb. You can then reconnect to the Ruby process managing the connection each time a request is handled and give it commands over DRb. The ssh variable might work as an instance variable inside the object you speak with over DRb in this case (it looks like you can set this to loop so it sticks around).
There are some terrible approaches to getting out of the scope box, like setting the variable as a thread-local variable, or searching the ObjectSpace.each_object, but those approaches are pretty bad in principal.