root/projects/AsynCluster/trunk/asyncluster/ndm/node.py

Revision 175, 4.6 kB (checked in by edsuom, 7 months ago)

Got D-Kernel PMC running with what I hope is Rao-Blackwellization

Line 
1 # AsynCluster: Node Display Manager (NDM)
2 # A simple X display manager for cluster nodes that also serve as
3 # access-restricted workstations.
4 #
5 # An NDM client runs on each node and communicates via Twisted's Perspective
6 # Broker to the Aysncluster server, which regulates when and how much each user
7 # can use his account on any of the workstations. The NDM server also
8 # dispatches cluster operations to the nodes via the NDM clients, unbeknownst
9 # to the workstation users.
10 #
11 # Copyright (C) 2006-2008 by Edwin A. Suominen, http://www.eepatents.com
12 #
13 # This program is free software; you can redistribute it and/or modify it under
14 # the terms of the GNU General Public License as published by the Free Software
15 # Foundation; either version 2 of the License, or (at your option) any later
16 # version.
17 #
18 # This program is distributed in the hope that it will be useful, but WITHOUT
19 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20 # FOR A PARTICULAR PURPOSE.  See the file COPYING for more details.
21 #
22 # You should have received a copy of the GNU General Public License along with
23 # this program; if not, write to the Free Software Foundation, Inc., 51
24 # Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25
26 """
27 The main module for node workers.
28
29 """
30
31
32 CONFIG_PATH = "/etc/asyncluster.conf"
33
34
35 class Manager(object):
36     """
37     I manage a node client. Instantiate me with I{headless} set C{True} if
38     there will be no GUI for user logins or display management.
39     
40     @ivar config: A L{configobj} config object loaded from the config file.
41     
42     """
43     def __init__(self, headless=False, duration=None):
44         import configobj
45         self.config = configobj.ConfigObj(CONFIG_PATH)
46         if headless:
47             self.gui = None
48         else:
49             import gui
50             self.gui = gui
51         # Regular reactor import comes after possible Qt reactor integration in
52         # gui module
53         from twisted.internet import reactor
54         reactor.callWhenRunning(self.startup)
55         if isinstance(duration, (float, int)):
56             reactor.callLater(float(duration), reactor.stop)
57         reactor.run()
58
59     def startup(self):
60         """
61         Instantiates a session-capable client and connects it to the server.
62         """
63         def gotSessionMgr(sessionMgr):
64             self.sessionMgr = sessionMgr
65             if self.gui:
66                 self.loginWindow = self.gui.LoginWindow(self)       
67
68         import client
69         self.client = client.Client(self, session=True)
70         d = self.client.connect()
71         d.addCallback(lambda p: p.callRemote('getSessionManager'))
72         d.addCallback(gotSessionMgr)
73         return d
74
75     def sessionBegin(self, user, password):
76         """
77         Requests a session for the specified I{user}, authenticated with the
78         supplied I{password}.
79         """
80         def gotSessionAnswer(approved):
81             if approved:
82                 if hasattr(self, 'loginWindow'):
83                     self.loginWindow.hide()
84                     self.sessionWindow = self.gui.SessionWindow(self, user)
85                     self.sessionWindow.show()
86                 self.activeUser = user
87                 d = self.sessionMgr.callRemote('timeLeft')
88                 d.addCallback(self.sessionUpdate)
89                 return d
90        
91         d = self.sessionMgr.callRemote('begin', user, password)
92         d.addCallback(gotSessionAnswer)
93         return d
94        
95     def sessionUpdate(self, hoursLeft):
96         """
97         Updates the session.
98         """
99         if self.activeUser is None:
100             return
101         if hoursLeft > 0.0:
102             if hasattr(self, 'sessionWindow'):
103                 self.sessionWindow.update(hoursLeft)
104         else:
105             self.sessionEnd(callServer=False)
106
107     def sessionEnd(self, callServer=True):
108         """
109         Ends the session, returning a deferred that fires when I'm ready for a
110         new session.
111         """
112         if hasattr(self, 'loginWindow'):
113             self.loginWindow.show()
114             self.loginWindow.repaint()
115         if hasattr(self, 'sessionWindow'):
116             self.sessionWindow.wmStop()
117             self.sessionWindow.close()
118             del self.sessionWindow
119         self.activeUser = None
120         if callServer:
121             return self.sessionMgr.callRemote('end')
122         from twisted.internet import defer
123         return defer.succeed(None)
124
125     def message(self, msg):
126         """
127         If there is a session underway, displays the message on it.
128         """
129         if hasattr(self, 'sessionWindow'):
130             self.sessionWindow.status(msg)
131
132
133 def run():
134     Manager()
135
136 def runHeadless(duration=None):
137     Manager(headless=True, duration=duration)
Note: See TracBrowser for help on using the browser.