On 6 Aug, 03:47 pm, [email protected] wrote: >I 19ve got an app written that runs as a service using >twisted.application.service that I need to tunnel through SSH. Right >now, I >use a script that makes use of Paramiko (and runs separate from my app) >to >set up a tunnel. That more or less works, but I 19ve had some problems >with >the tunnel just going away and would like to integrate the tunneling >into >the app, using conch. I 19ve found an example of tunneling via conch, at >http://twistedmatrix.com/pipermail/twisted- >python/2009-February/019196.html, >that I think I can use as a base to add the code to my app. > >Right now my app is basically: > >class DataPuller(service.Service): > ...Code for my app... > ... The app pulls data from a database and I can only connect to the >server via SSH... > >application = service.Application( 18Data_puller 19) >dpService = DataPuller() >dpService.setServiceParent(application) > >My main problems are that I 19m not sure whether or not the example >linked to >above is a good one for tunneling with conch and, if it is, how do I >merge >the example tunneling code with my app code. From the example, where >the >code is:
The example you linked to sets up the traditional port forwarding behavior. A local port is opened and connections to it are tunneled over the SSH connection, where data is then delivered to some address accessible from the server on the other end of the SSH connection. This is fine and should work, and probably very closely mirrors what you're doing with Paramiko, so if you're happy with that, you should go for it. However, it's also possible for you to do this tunneling without opening the extra local port. Since your application and the SSH client code are all in the same process, you don't need the TCP connection to a local port to do this IPC to interact wiht the tunnel. You can set up the tunnel part of things, but instead of binding a local port to accept connections on, you can just open a connection over the tunnel and write bytes into it with API calls. I *don't* have an example of doing things this way, and I don't even know exactly what it involves. ;) However, the example you linked to gives a clue about where to start on this approach: when it binds the local port, it uses the forwarding.SSHListenForwardingFactory factory, so I'd start by looking at that class and see what it does. The rest is just mimicking its behavior without actually using reactor.listenTCP. >class Connection(connection.SSHConnection): > . > . > . > def serviceStarted(self): > >Do I instantiate my DataPuller class there, in serviceStarted (and not >subclass from service.Service)? If so, how do I wrap the tunneling code >so >that I can make it a service? If not, do I need put the tunneling code >inside my DataPuller class? What would that look like? If you want things to happen when your program starts or when it is about to stop, then using service.Service is still a good idea. That's the easy way to hook into startup and shutdown events. However, you may not want to do anything other than set up (or tear down) the SSH connection in your service.Service subclass. Creating your new non-Service DataPuller in the Connection's serviceStarted (or maybe even a little later - after you actually set up the connection over the tunnel over the connection) then makes sense. Jean-Paul _______________________________________________ Twisted-Python mailing list [email protected] http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
