Changeset 87
- Timestamp:
- 10/02/07 16:37:56 (1 year ago)
- Files:
-
- projects/AsynCluster/trunk/asyncluster/master/control.py (modified) (2 diffs)
- projects/AsynCluster/trunk/asyncluster/ndm/client.py (modified) (1 diff)
- projects/AsynCluster/trunk/asyncluster/ndm/main.py (modified) (4 diffs)
- projects/AsynCluster/trunk/console.py (added)
- projects/AsynCluster/trunk/ndm (modified) (1 diff)
- projects/AsynCluster/trunk/setup.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
projects/AsynCluster/trunk/asyncluster/master/control.py
r79 r87 279 279 if action == 'password': 280 280 d = t.password(userID, actionArg) 281 if action == 'disable':281 elif action == 'disable': 282 282 d = t.enabled(userID, False) 283 283 elif action == 'enable': 284 284 d = t.enabled(userID, True) 285 if action == 'restrict':285 elif action == 'restrict': 286 286 d = t.restricted(userID, True) 287 287 elif action == 'unrestrict': … … 291 291 elif action == 'kick': 292 292 d = self.ctl.userRemote(userID, 'kick') 293 else: 294 return "INVALID COMMAND '%s'" % action 295 d.addCallbacks(lambda _: "OK", lambda _: "FAIL") 293 296 return d 294 297 projects/AsynCluster/trunk/asyncluster/ndm/client.py
r76 r87 47 47 class ClientRoot(jobs.ChildRoot): 48 48 """ 49 I am the root resource for one cluster node. 49 I am the root resource for one cluster node, with the remote-callable 50 methods of a child worker plus a few extra for NDM purposes. 50 51 """ 51 52 def __init__(self, main, serverPassword): projects/AsynCluster/trunk/asyncluster/ndm/main.py
r16 r87 29 29 """ 30 30 31 # Start PyQt4 with Twisted integration32 if True:33 #try:34 from twisted_goodies.qtwisted import qt4reactor35 from PyQt4.QtGui import QApplication36 app = QApplication([])37 qt4reactor.install(app)38 import gui39 #except:40 # print "Console mode"41 from twisted.internet import reactor42 43 # Other imports44 31 import os 45 32 import configobj … … 53 40 54 41 55 class MainManager(object):42 class BaseManager(object): 56 43 """ 57 I am the main objectfor the node client, GUI or console.44 I am a base class for the node client, GUI or console. 58 45 59 46 @ivar d: A deferred that fires when the client connects to the … … 63 50 64 51 """ 65 def __init__(self, configPath, guiApp=None): 66 self.app = guiApp 67 self.config = configobj.ConfigObj(configPath) 52 def __init__(self): 53 # The Twisted reactor, gui-integrated or not 54 from twisted.internet import reactor 55 reactor.callWhenRunning(self.startup) 56 self.reactor = reactor 57 # Generic setup 58 self.config = configobj.ConfigObj(CONFIG_PATH) 68 59 self.client = client.Client(self) 69 self.d = defer.Deferred()70 60 self.activeUser = None 71 reactor.callWhenRunning(self.startup) 61 # Go! 62 reactor.run() 63 64 def gotConnected(self, sessionMgr): 65 """ 66 Connected callback for console clients. 67 """ 68 self.sessionMgr = sessionMgr 72 69 73 70 def startup(self): 74 def connected(sessionMgr): 75 self.sessionMgr = sessionMgr 76 if self.app: 77 self.loginWindow() 78 else: 79 print "Connected to AsynCluster server" 80 self.d.callback(None) 81 82 self.client.connect().addCallback(connected) 71 self.client.connect().addCallback(self.gotConnected) 83 72 84 73 def shutdown(self): 85 74 d = self.client.disconnect() 86 d.addCallback(lambda _: reactor.stop())75 d.addCallback(lambda _: self.reactor.stop()) 87 76 return d 88 77 89 def loginWindow(self):78 def gotSessionAnswer(self, approved): 90 79 """ 91 Creates and displays a L{gui.LoginWindow}.80 Session begin callback for all clients. 92 81 """ 93 self.loginWindow = gui.LoginWindow(self) 82 if approved: 83 self.activeUser = user 84 d = self.sessionMgr.callRemote('timeLeft') 85 d.addCallback(self.sessionUpdate) 86 return d 94 87 95 88 def sessionBegin(self, user, password): 96 89 """ 97 Requests a session for the specified I{user}, authenticated with the98 supplied I{password}.90 For all clients, requests a session for the specified I{user}, 91 authenticated with the supplied I{password}. 99 92 """ 100 def gotAnswer(approved):101 if approved:102 if self.app:103 self.loginWindow.hide()104 self.sessionWindow = gui.SessionWindow(self, user)105 self.sessionWindow.show()106 else:107 print "Console session started for '%s'" % user108 self.activeUser = user109 d = self.sessionMgr.callRemote('timeLeft')110 d.addCallback(self.sessionUpdate)111 return d112 # Denied!113 if not self.app:114 print "Session denied for '%s'" % user115 116 93 d = self.sessionMgr.callRemote('begin', user, password) 117 d.addCallback( gotAnswer)94 d.addCallback(self.gotSessionAnswer) 118 95 return d 119 96 120 97 def sessionUpdate(self, hoursLeft): 121 98 """ 99 For all clients, updates the session. 122 100 """ 123 101 if self.activeUser is None: 124 102 return 125 103 if hoursLeft > 0.0: 126 if self.app: 127 if hasattr(self, 'sessionWindow'): 128 self.sessionWindow.update(hoursLeft) 129 else: 130 print "Hours left:", hoursLeft 104 if hasattr(self, 'sessionWindow'): 105 self.sessionWindow.update(hoursLeft) 131 106 else: 132 107 self.sessionEnd(callServer=False) … … 134 109 def sessionEnd(self, callServer=True): 135 110 """ 111 For all clients, ends the session. 136 112 """ 137 113 self.activeUser = None 138 if self.app:139 self.loginWindow.show()140 self.loginWindow.repaint()141 if hasattr(self, 'sessionWindow'):142 self.sessionWindow.wmStop()143 self.sessionWindow.close()144 del self.sessionWindow145 else:146 print "Console session ended"147 114 if callServer: 148 115 return self.sessionMgr.callRemote('end') 149 116 150 117 151 def runConsole(user, password):118 class GuiManager(BaseManager): 152 119 """ 153 Runs a console-only client.154 120 """ 155 mgr = MainManager(CONFIG_PATH) 156 mgr.d.addCallback(lambda _: mgr.sessionBegin(user, password)) 157 reactor.run() 121 def __init__(self): 122 # Start PyQt4 with Twisted integration 123 from twisted_goodies.qtwisted import qt4reactor 124 from PyQt4.QtGui import QApplication 125 self.app = QApplication([]) 126 qt4reactor.install(self.app) 127 # The gui module... 128 import gui; self.gui = gui 129 # Now do the rest... 130 BaseManager.__init__(self) 131 132 def gotConnected(self, sessionMgr): 133 """ 134 Connected callback for GUI clients. 135 """ 136 self.sessionMgr = sessionMgr 137 self.loginWindow = self.gui.LoginWindow(self) 138 139 def gotSessionAnswer(self, approved): 140 """ 141 Session begin callback for GUI clients. 142 """ 143 if approved: 144 self.loginWindow.hide() 145 self.sessionWindow = self.gui.SessionWindow(self, user) 146 self.sessionWindow.show() 147 return BaseManager.gotSessionAnswer(self, approved) 148 149 def sessionEnd(self, callServer=True): 150 """ 151 Ends the session for GUI clients. 152 """ 153 self.loginWindow.show() 154 self.loginWindow.repaint() 155 if hasattr(self, 'sessionWindow'): 156 self.sessionWindow.wmStop() 157 self.sessionWindow.close() 158 del self.sessionWindow 159 return BaseManager.sessionEnd(self, callServer) 158 160 159 161 160 def runGUI(): 161 """ 162 Runs the NDM application in a fixed-sized, unmanaged window with the 163 overall event loop under Twisted control. 164 """ 165 mgr = MainManager(CONFIG_PATH, app) 166 reactor.run() 162 if __name__ == '__main__': 163 from optparse import OptionParser 164 parser = OptionParser() 165 parser.add_option( 166 "-g", "--gui", 167 action="store_true", dest="gui", 168 help="Run the NDM application in a fixed-sized, unmanaged window") 169 opts, args = parser.parse_args() 170 171 if opts.gui: 172 # Run the NDM application in a fixed-sized, unmanaged window with the 173 # overall event loop under Twisted control. 174 GuiManager() 175 else: 176 # Run a console-only client with no user session. 177 BaseManager() 178 179 projects/AsynCluster/trunk/ndm
r16 r87 39 39 then 40 40 # Starts the Python interpreter as Xinit's sole X client 41 exec python -c \42 "from asyncluster.ndm import main; main. runGUI()" \41 exec python -c 42 "from asyncluster.ndm import main; main.GuiManager()" \ 43 43 2>/dev/null 44 44 projects/AsynCluster/trunk/setup.py
r82 r87 49 49 'install_requires':required, 50 50 'packages':find_packages(exclude=["*.test"]), 51 'scripts':['ndm' ],51 'scripts':['ndm', 'console'], 52 52 53 53 'zip_safe':True
