[Twisted-Python] Discovering Twisted : reactor.stop()
Hello, I discovered Python recently and even more recently the Twisted module. I have a problem with the Twisted reactor and I would like to understand for which reason my program freezes. Here the code which should loop forever : from twisted.internet import reactor from twisted.internet import task class reactorProb(object): def __init__(self): self.count = 5 self._callback = task.LoopingCall(self.Heartbeat) self._callback.start(1, now = False) def Heartbeat(self): print "Top" self.count -= 1 if (self.count == 0): print "Exit" self._callback.stop() del self._callback reactor.stop() while (True): rp = reactorProb() print "Enter into reactor.run()" reactor.run() print "Leave from reactor.run()" I got this: Enter into reactor.run() Top Top Top Top Top Exit Leave from reactor.run() Enter into reactor.run() Top Top Top Top Top Exit Thus I start first once the reactor, I stop it then I start again and it freezes instead of stopping it the reactor. Could somebody explain me it why? Thank you in advance. smu
On Thu, 27 Sep 2007 12:25:02 +0200, Steve MULLER <thoma.hauc@gmail.com> wrote:
Hello,
I discovered Python recently and even more recently the Twisted module.
I have a problem with the Twisted reactor and I would like to understand for which reason my program freezes.
[snip]
Thus I start first once the reactor, I stop it then I start again and it freezes instead of stopping it the reactor.
Could somebody explain me it why?
None of the reactors implemented in Twisted are restartable. You can call each of start and stop at most once. Jean-Paul
2007/9/27, Jean-Paul Calderone <exarkun@divmod.com>:
On Thu, 27 Sep 2007 12:25:02 +0200, Steve MULLER <thoma.hauc@gmail.com> wrote:
Hello,
I discovered Python recently and even more recently the Twisted module.
I have a problem with the Twisted reactor and I would like to understand for which reason my program freezes.
[snip]
Thus I start first once the reactor, I stop it then I start again and it freezes instead of stopping it the reactor.
Could somebody explain me it why?
None of the reactors implemented in Twisted are restartable. You can call each of start and stop at most once.
Jean-Paul
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
Is there any other way to do so kind of job ? smu
On Thu, 27 Sep 2007 14:37:53 +0200, Steve MULLER <thoma.hauc@gmail.com> wrote:
[snip]
Is there any other way to do so kind of job ?
The only interesting thing your example did was try to start the reactor more than once. There's no way to do that. ;) If you want to do more than one thing, then just do more than one thing. You don't need to stop the reactor until the entire program has completed and you are ready for the process to exit. If you're trying to figure out how to organize your code so that you can do one thing after another thing has finished, then you should look at Deferreds, since that is precisely what they are good for. Your example included a Deferred, in fact - LoopingCall.start() returns one which is called back when the stop() method is called on that LoopingCall instance. Jean-Paul
After much wrangling and a small miracle I have managed to write an object that fetches the output of three commands in the order given through an SSH connection. How come I cannot switch users? Some of the information I need can only be fetched through a root account and security is such that I cannot log in remotely from a root account but must switch once logged in from an account with less than root privileges. Here's the line that instaniates my SSH object (also repeated at the end of my code): myssh = SSH("my.host.com", "myusername", "mypasswd", ["id; su - root; myrootpasswd; id", "pwd", "ls -l"]) The last argument above is a list of three commands. Inside one command ";" separates the piece parts. I am not even able to su to accounts that don't require a password. ###========= CODE STARTS ================### from twisted.conch import error from twisted.conch.ssh import transport, connection, keys, userauth, channel, common from twisted.internet import defer, protocol, reactor import sys, getpass, os, string class ClientCommandTransport(transport.SSHClientTransport): def __init__(self, username, password, cmds, caller): self.username = username self.password = password self.cmds = cmds self.caller = caller def verifyHostKey(self, pubKey, fingerprint): # in a real app, you should verify that the fingerprint matches # the one you expected to get from this server return defer.succeed(True) def connectionSecure(self): self.requestService(PasswordAuth(self.username, self.password, ClientConnection(self.cmds, self.caller))) class PasswordAuth(userauth.SSHUserAuthClient): def __init__(self, user, password, connection): userauth.SSHUserAuthClient.__init__(self, user, connection) self.password = password def getPassword(self, prompt=None): return defer.succeed(self.password) class ClientConnection(connection.SSHConnection): def __init__(self, cmds, caller, *args, **kwargs): connection.SSHConnection.__init__(self) self.cmds = cmds self.caller = caller #====================== def serviceStarted(self): self.d = defer.Deferred() self.d.addCallback(self._cbFirst) self.d.addErrback(self._ebFirst) self.openChannel(CommandChannel(self.cmds[0], lastcmd=0, conn=self)) def _cbFirst(self, result): #print 'CALLBACK Result 1:', result self.caller.responses.append(result.rstrip()) self.d = defer.Deferred() self.d.addCallback(self._cbSecond) self.d.addErrback(self._ebSecond) self.openChannel(CommandChannel(self.cmds[1], lastcmd=0, conn=self)) def _ebFirst(self, f): self.caller.responses.append(None) print "Error 1" self.d = defer.Deferred() self.d.addCallback(self._cbSecond) self.d.addErrback(self._ebSecond) self.openChannel(CommandChannel(self.cmds[1], lastcmd=0, conn=self)) #log.err() def _cbSecond(self, result): #print 'CALLBACK Result 2:', result self.caller.responses.append(result.rstrip()) self.d = defer.Deferred() self.d.addCallback(self._cbThird) self.d.addErrback(self._ebThird) self.openChannel(CommandChannel(self.cmds[2], lastcmd=1, conn=self)) def _ebSecond(self, f): self.caller.responses.append(None) self.d = defer.Deferred() self.d.addCallback(self._cbThird) self.d.addErrback(self._ebThird) self.openChannel(CommandChannel(self.cmds[2], lastcmd=1, conn=self)) #log.err() def _cbThird(self, result): self.caller.responses.append(result.rstrip()) #print 'CALLBACK Result 3:', result reactor.stop() def _ebThird(self, f): self.caller.responses.append(None) log.err() reactor.stop() #====================== class CommandChannel(channel.SSHChannel): name = 'session' def __init__(self, command, lastcmd, *args, **kwargs): channel.SSHChannel.__init__(self, *args, **kwargs) self.command = command self.lastcmd = lastcmd self.data = "" def channelOpen(self, data): self.conn.sendRequest(self, 'exec', common.NS(self.command), wantReply=True).addCallback(self._gotResponse) def _gotResponse(self, _): #print "RESPONSE" self.conn.sendEOF(self) def dataReceived(self, data): #print "Data Received:", data self.data += data def closed(self): self.conn.d.callback(self.data) self.loseConnection() ## if self.lastcmd: ## print "closing reactor." ## reactor.stop() class ClientCommandFactory(protocol.ClientFactory): def __init__(self, username, password, cmds, caller): self.username = username self.password = password self.cmds = cmds self.caller = caller def buildProtocol(self, addr): protocol = ClientCommandTransport(self.username, self.password, self.cmds, self.caller) return protocol class SSH(): """ Contains a SSH connection, runs commands, and stores results. """ def __init__(self, host, username, password, cmds): self.host = host self.username = username self.password = password self.cmds = cmds self.responses = [] self.run_commands() def run_commands(self): factory = ClientCommandFactory(self.username, self.password, self.cmds, self) reactor.connectTCP(self.host, 22, factory) reactor.run() myssh = SSH("my.host.com", "myacct", "mypasswd", ["id; su - root; myrootpasswd; id", "pwd", "ls -l"]) print "=" * 25 for i, response in enumerate(myssh.responses): print i, response print "=" * 25 print "\nDone."
On Thu, 27 Sep 2007 15:00:14 -0500, paul_s_johnson@mnb.uscourts.gov wrote:
After much wrangling and a small miracle I have managed to write an object that fetches the output of three commands in the order given through an SSH connection. How come I cannot switch users? Some of the information I need can only be fetched through a root account and security is such that I cannot log in remotely from a root account but must switch once logged in from an account with less than root privileges.
Here's the line that instaniates my SSH object (also repeated at the end of my code):
myssh = SSH("my.host.com", "myusername", "mypasswd", ["id; su - root; myrootpasswd; id", "pwd", "ls -l"])
I suspect the list element which includes "su - root; myrootpasswd;" won't achieve the desired affect. Even if su weren't careful to try to read from a pty, "myrootpasswd" won't be sent to its stdin, it'll be executed by the shell after "su - root" exits, which it probably won't since nothing is going to write a password to it. Instead, you probably need to send the password over the connection after "su - root" has started and is waiting for the password. I'm not exactly sure what the steps to this in detail are, though. Jean-Paul
On 9/28/07, Jean-Paul Calderone <exarkun@divmod.com> wrote:
On Thu, 27 Sep 2007 15:00:14 -0500, paul_s_johnson@mnb.uscourts.gov wrote:
Here's the line that instaniates my SSH object (also repeated at the end of my code):
myssh = SSH("my.host.com", "myusername", "mypasswd", ["id; su - root; myrootpasswd; id", "pwd", "ls -l"])
I suspect the list element which includes "su - root; myrootpasswd;" won't achieve the desired affect. Even if su weren't careful to try to read from a pty, "myrootpasswd" won't be sent to its stdin, it'll be executed by the shell after "su - root" exits, which it probably won't since nothing is going to write a password to it.
What you'll do is on the channel object which runs these commands, you'll use the .write() method to send the root password to su. -p -- Paul Swartz paulswartz at gmail dot com http://z3p.livejournal.com/ AIM: z3penguin
participants (4)
-
Jean-Paul Calderone
-
Paul Swartz
-
Paul_S_Johnson@mnb.uscourts.gov
-
Steve MULLER