Changeset 87

Show
Ignore:
Timestamp:
10/02/07 16:37:56 (1 year ago)
Author:
edsuom
Message:

Got a rudimentary control console working

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • projects/AsynCluster/trunk/asyncluster/master/control.py

    r79 r87  
    279279        if action == 'password': 
    280280            d = t.password(userID, actionArg) 
    281         if action == 'disable': 
     281        elif action == 'disable': 
    282282            d = t.enabled(userID, False) 
    283283        elif action == 'enable': 
    284284            d = t.enabled(userID, True) 
    285         if action == 'restrict': 
     285        elif action == 'restrict': 
    286286            d = t.restricted(userID, True) 
    287287        elif action == 'unrestrict': 
     
    291291        elif action == 'kick': 
    292292            d = self.ctl.userRemote(userID, 'kick') 
     293        else: 
     294            return "INVALID COMMAND '%s'" % action 
     295        d.addCallbacks(lambda _: "OK", lambda _: "FAIL") 
    293296        return d 
    294297 
  • projects/AsynCluster/trunk/asyncluster/ndm/client.py

    r76 r87  
    4747class ClientRoot(jobs.ChildRoot): 
    4848    """ 
    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. 
    5051    """ 
    5152    def __init__(self, main, serverPassword): 
  • projects/AsynCluster/trunk/asyncluster/ndm/main.py

    r16 r87  
    2929""" 
    3030 
    31 # Start PyQt4 with Twisted integration 
    32 if True: 
    33 #try: 
    34     from twisted_goodies.qtwisted import qt4reactor 
    35     from PyQt4.QtGui import QApplication 
    36     app = QApplication([]) 
    37     qt4reactor.install(app) 
    38     import gui 
    39 #except: 
    40 #    print "Console mode" 
    41 from twisted.internet import reactor 
    42  
    43 # Other imports 
    4431import os 
    4532import configobj 
     
    5340 
    5441 
    55 class MainManager(object): 
     42class BaseManager(object): 
    5643    """ 
    57     I am the main object for the node client, GUI or console. 
     44    I am a base class for the node client, GUI or console. 
    5845 
    5946    @ivar d: A deferred that fires when the client connects to the 
     
    6350     
    6451    """ 
    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) 
    6859        self.client = client.Client(self) 
    69         self.d = defer.Deferred() 
    7060        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 
    7269 
    7370    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) 
    8372     
    8473    def shutdown(self): 
    8574        d = self.client.disconnect() 
    86         d.addCallback(lambda _: reactor.stop()) 
     75        d.addCallback(lambda _: self.reactor.stop()) 
    8776        return d 
    8877 
    89     def loginWindow(self): 
     78    def gotSessionAnswer(self, approved): 
    9079        """ 
    91         Creates and displays a L{gui.LoginWindow}
     80        Session begin callback for all clients
    9281        """ 
    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 
    9487 
    9588    def sessionBegin(self, user, password): 
    9689        """ 
    97         Requests a session for the specified I{user}, authenticated with the 
    98         supplied I{password}. 
     90        For all clients, requests a session for the specified I{user}, 
     91        authenticated with the supplied I{password}. 
    9992        """ 
    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'" % user 
    108                 self.activeUser = user 
    109                 d = self.sessionMgr.callRemote('timeLeft') 
    110                 d.addCallback(self.sessionUpdate) 
    111                 return d 
    112             # Denied! 
    113             if not self.app: 
    114                 print "Session denied for '%s'" % user 
    115          
    11693        d = self.sessionMgr.callRemote('begin', user, password) 
    117         d.addCallback(gotAnswer) 
     94        d.addCallback(self.gotSessionAnswer) 
    11895        return d 
    11996         
    12097    def sessionUpdate(self, hoursLeft): 
    12198        """ 
     99        For all clients, updates the session. 
    122100        """ 
    123101        if self.activeUser is None: 
    124102            return 
    125103        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) 
    131106        else: 
    132107            self.sessionEnd(callServer=False) 
     
    134109    def sessionEnd(self, callServer=True): 
    135110        """ 
     111        For all clients, ends the session. 
    136112        """ 
    137113        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.sessionWindow 
    145         else: 
    146             print "Console session ended" 
    147114        if callServer: 
    148115            return self.sessionMgr.callRemote('end') 
    149116 
    150117 
    151 def runConsole(user, password): 
     118class GuiManager(BaseManager): 
    152119    """ 
    153     Runs a console-only client. 
    154120    """ 
    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) 
    158160 
    159161 
    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() 
     162if __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  
    3939    then 
    4040    # 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()" \ 
    4343        2>/dev/null 
    4444 
  • projects/AsynCluster/trunk/setup.py

    r82 r87  
    4949      'install_requires':required, 
    5050      'packages':find_packages(exclude=["*.test"]), 
    51       'scripts':['ndm'], 
     51      'scripts':['ndm', 'console'], 
    5252       
    5353      'zip_safe':True