source: trunk/src/testing/bin/appLauncher/admin.py @ 4

Revision 4, 11.5 KB checked in by ajaworski, 13 years ago (diff)

Added modified SAGE sources

Line 
1############################################################################
2#
3# AppLauncher - Application Launcher for SAGE
4# Copyright (C) 2006 Electronic Visualization Laboratory,
5# University of Illinois at Chicago
6#
7# All rights reserved.
8#
9# Redistribution and use in source and binary forms, with or without
10# modification, are permitted provided that the following conditions are met:
11#
12#  * Redistributions of source code must retain the above copyright
13#    notice, this list of conditions and the following disclaimer.
14#  * Redistributions in binary form must reproduce the above
15#    copyright notice, this list of conditions and the following disclaimer
16#    in the documentation and/or other materials provided with the distribution.
17#  * Neither the name of the University of Illinois at Chicago nor
18#    the names of its contributors may be used to endorse or promote
19#    products derived from this software without specific prior written permission.
20#
21# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
25# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32#
33# Direct questions, comments etc about AppLauncher to www.evl.uic.edu/cavern/forum
34#
35# Author: Ratko Jagodic
36#
37############################################################################
38
39
40
41import wx, xmlrpclib, string, socket
42import traceback as tb
43
44
45
46
47class App:
48    """ describes the app that's currently running and that has been executed by an appLauncher"""
49    def __init__(self, name, appId, command, machine, launcher):
50        self.name = name
51        self.appId = appId
52        self.command = command
53        self.machine = machine
54        self.launcher = launcher  #the appLauncherId that started this app
55
56    def getName(self):
57        return self.name
58
59    def getId(self):
60        return self.appId
61
62    def getCommand(self):
63        return self.command
64
65    def getRenderMachine(self):
66        return self.machine
67
68    def getLauncher(self):
69        return self.launcher
70
71    def getStringForm(self):
72        info = "APPLICATION NAME: " + self.name
73        info = info + "\n------------------------------------------------"
74        info = info + "\nEXECUTION COMMAND: " + str(self.command)
75        info = info + "\nRENDERING MACHINE:\t"+str(self.machine)
76        return info
77   
78
79class AppLauncher:
80
81    def __init__(self, launcherId, name, ip, port, appList):
82        self.port = port
83        self.appList = appList
84        self.ip = ip
85        self.launcherId = launcherId
86        self.name = name
87        self.connected = False
88
89
90    def connect(self):
91        if not self.connected:
92            socket.setdefaulttimeout(3)  #set the timeout to 3 seconds so that we dont wait forever
93            self.server = xmlrpclib.ServerProxy("http://" + self.ip + ":" + str(self.port))
94            try:
95                self.server.test() #just use this as a way of testing whether the server is running or not
96                self.connected = True
97            except socket.error:
98                return False
99            except:
100                tb.print_exc()
101                return False
102        return True
103
104
105    def stopApp(self, appId):
106        try:
107            self.connect()  #connect if necessary
108            return self.server.stopApp(appId)
109        except socket.error:
110            wx.MessageBox("No connection to the appLauncher: "+str(self.launcherId), "Failed")
111            self.connected = False
112        except:
113            wx.MessageBox("There was an error stopping application:\n\n"+
114                          str("".join(tb.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))),
115                          "Failed")
116           
117    def appStatus(self):
118        try:
119            self.connect()  #connect if necessary
120            return self.server.appStatus()
121        except socket.error:
122            wx.MessageBox("No connection to the appLauncher: "+str(self.launcherId), "Failed")
123            self.connected = False
124        except:
125            wx.MessageBox("There was an error getting application list:\n\n"+
126                          str("".join(tb.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))),
127                          "Failed")
128        return {}
129
130
131    def killLauncher(self):
132        try:
133            self.connect()  #connect if necessary
134            self.server.killLauncher()
135        except socket.error:
136            wx.MessageBox("No connection to the appLauncher: "+str(self.launcherId), "Failed")
137            self.connected = False
138        except:
139            wx.MessageBox("There was an error killing application launcher:\n\n"+
140                          str("".join(tb.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))),
141                          "Failed")
142
143
144
145    def getId(self):
146        return self.launcherId
147
148    def getIP(self):
149        return self.ip
150
151    def getAppList(self):
152        return self.appList
153
154    def setAppList(self, appList):
155        self.appList = appList
156
157    def getPort(self):
158        return self.port
159
160    def getName(self):
161        return self.name
162
163
164
165
166
167class MainFrame(wx.Frame):
168
169    def __init__(self, serverIP, serverPort=8009):
170        wx.Frame.__init__(self, None, -1, "AppLauncher Admin", pos = (100,100), size=(550,300))
171        self.server = xmlrpclib.ServerProxy("http://"+serverIP+":"+str(serverPort))
172        self.CreateControls()
173        self.updateLauncherList()
174        self.SetBackgroundColour(wx.Colour(51, 102, 102))
175        self.Show(True)
176
177       
178    ### connects to the sage server and retrieves the list of all app launchers running
179    def updateLauncherList(self):
180        self.launcherList.Clear()  #clear the ListBox
181        try:
182            # a hash comes back (key=launcherId, value=appList - that's another hash of appNames and configs)
183            launcherHash = self.server.GetRegisteredLaunchers()
184        except socket.error:
185            wx.MessageBox("No connection to the sage server.", "No connection")
186        except:
187            tb.print_exc()
188        else:
189            for launcherString, appList in launcherHash.iteritems():
190                (name, launcherId) = launcherString.split(":",1)
191                (ip, port) = launcherId.split(":",1)
192                self.launcherList.Insert(name, 0, AppLauncher(launcherId, name, ip, port, appList))
193               
194       
195    def CreateControls(self):
196        self.launcherLabel = wx.StaticText(self, -1, "Registered AppLaunchers", style=wx.ALIGN_CENTER)
197        self.appLabel = wx.StaticText(self, -1, "Apps Running On: ", style=wx.ALIGN_CENTER)
198        self.appInfoLabel = wx.StaticText(self, -1, "Details for: ", style=wx.ALIGN_CENTER)
199
200        self.launcherLabel.SetForegroundColour(wx.WHITE)
201        self.appLabel.SetForegroundColour(wx.WHITE)
202        self.appInfoLabel.SetForegroundColour(wx.WHITE)
203
204        self.launcherList = wx.ListBox(self, -1, style=wx.LB_SINGLE)
205        self.launcherList.SetMinSize((100,100))
206        self.appList = wx.ListBox(self, -1, style=wx.LB_SINGLE)
207        self.appList.SetMinSize((200,100))
208        self.appInfo = wx.TextCtrl(self, -1, "", style=wx.TE_READONLY | wx.TE_MULTILINE | wx.TE_DONTWRAP)
209        self.appInfo.SetMinSize((300,100))
210       
211        self.killAppBtn = wx.Button(self, -1, "Kill App")
212        self.killLauncherBtn = wx.Button(self, -1, "Kill Launcher")
213        self.refreshBtn = wx.Button(self, -1, "Refresh")
214
215
216        # registering event handlers
217        self.launcherList.Bind(wx.EVT_LISTBOX, self.OnLauncherListSelect)
218        self.appList.Bind(wx.EVT_LISTBOX, self.OnAppListSelect)
219        self.killAppBtn.Bind(wx.EVT_BUTTON, self.OnKillAppBtn)
220        self.killLauncherBtn.Bind(wx.EVT_BUTTON, self.OnKillLauncherBtn)
221        self.refreshBtn.Bind(wx.EVT_BUTTON, self.UpdateLists)
222       
223        # placement of the controls
224        gridSizer = wx.FlexGridSizer(2,3,0,20)
225        gridSizer.Add(self.launcherLabel, 0, wx.ALIGN_CENTER | wx.TOP | wx.LEFT | wx.EXPAND, border=15)
226        gridSizer.Add(self.appLabel, 0, wx.ALIGN_CENTER | wx.TOP, border=15)
227        gridSizer.Add(self.appInfoLabel, 0, wx.ALIGN_CENTER | wx.TOP, border=15)
228
229        gridSizer.Add(self.launcherList, 1, wx.EXPAND | wx.ALL, border=10)
230        gridSizer.Add(self.appList, 1, wx.EXPAND | wx.ALL, border=10)
231        gridSizer.Add(self.appInfo, 1, wx.EXPAND | wx.ALL, border=10)
232
233        gridSizer.Add(self.killLauncherBtn, 0, wx.ALIGN_CENTER | wx.BOTTOM, border=15)
234        gridSizer.Add(self.killAppBtn, 0, wx.ALIGN_CENTER | wx.BOTTOM, border=15)
235        gridSizer.Add(self.refreshBtn, 0, wx.ALIGN_RIGHT | wx.BOTTOM | wx.RIGHT, border=15)
236
237
238        gridSizer.AddGrowableRow(1)
239        gridSizer.AddGrowableCol(2)
240       
241        self.SetSizer(gridSizer)
242        gridSizer.Fit(self)
243
244       
245    def OnLauncherListSelect(self, event=None):
246        selection = self.launcherList.GetStringSelection()
247        self.appList.Clear()
248        self.appLabel.SetLabel("Apps Running On: " + str(selection))
249        self.appInfo.Clear()
250        self.appInfoLabel.SetLabel("Details for: ")
251        appLauncher = event.GetClientData()
252        for appId, (appName, command, machine) in appLauncher.appStatus().iteritems():
253            self.appList.Insert(appName, 0, App(appName, int(appId), command, machine, appLauncher))
254        self.GetSizer().Layout()
255
256
257    def OnAppListSelect(self, event=None):
258        selection = self.appList.GetStringSelection()
259        self.appInfo.Clear()
260        self.appInfoLabel.SetLabel("Details for: " + str(selection))
261        self.appInfo.WriteText(event.GetClientData().getStringForm())
262        self.GetSizer().Layout()
263       
264
265    def UpdateLists(self, event=None):
266        self.updateLauncherList()
267        self.appList.Clear()
268        self.appLabel.SetLabel("Apps Running On: ")
269        self.appInfo.Clear()
270        self.appInfoLabel.SetLabel("Details for: ")
271        self.GetSizer().Layout()
272
273
274    def OnKillAppBtn(self, event):
275        selection = self.appList.GetSelection()
276        if not selection == wx.NOT_FOUND:
277            app = self.appList.GetClientData(selection)
278            app.getLauncher().stopApp(app.getId())
279            self.UpdateLists()
280
281
282    def OnKillLauncherBtn(self, event):
283        selection = self.launcherList.GetSelection()
284        if not selection == wx.NOT_FOUND:
285            msg = "Really stop this application launcher? You may be interfering with someone else's work."
286            dlg = wx.MessageDialog(None, msg, "Confirm kill", style = wx.OK | wx.CANCEL)
287            if dlg.ShowModal() == wx.ID_OK:
288                appLauncher = self.launcherList.GetClientData(selection)
289                appLauncher.killLauncher()
290                self.UpdateLists()
291
292
293
294
295
296class MyApp(wx.App):
297    def __init__(self):
298        wx.App.__init__(self, redirect=False)
299
300    def OnInit(self):
301        return True
302
303
304
305
306       
307
308def main(argv):
309    name, ext  = os.path.splitext(argv[1])
310
311    if len(argv) == 2:
312        serverIP = "sage.sl.startap.net"
313        serverPort = 8009
314    elif len(argv) == 3:
315        serverIP = argv[2]
316        serverPort = 8009
317    else:
318        print "Usage: python admin.py [SERVER_IP]\n"
319        sys.exit(0)
320
321    app = MyApp()
322    frame = MainFrame(serverIP, serverPort)
323    app.SetTopWindow(frame)
324    app.MainLoop()
325
326
327
328if __name__ == '__main__':
329    import sys, os
330    main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
Note: See TracBrowser for help on using the repository browser.