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

Revision 4, 17.9 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
40import string, os, copy, os.path, sys
41import traceback as tb
42from myprint import *   # handles the printing or logging
43
44opj = os.path.join
45sys.path.append( opj(os.environ["SAGE_DIRECTORY"], "bin" ) )
46from sagePath import getUserPath, SAGE_DIR
47
48## # read the master IP from the fsManager.conf
49## f = open(os.environ["SAGE_DIRECTORY"]+"/bin/fsManager.conf", "r")
50
51## FS_IP = f.readline().split()[2].strip()    #fsManager IP
52## FS_PORT = f.readline().split()[1].strip()  #system port
53## f.close()
54
55     
56
57class OneConfig:
58    ''' describes one configuration for an app '''
59   
60    def __init__(self, name, appName, dynamic=False):
61        self._configName = name
62        self._dynamic = dynamic     # dynamic config???
63        self._appName = appName
64        self._configFilename = getUserPath("applications", appName+".conf")
65        self._launcherId = ""
66
67        self._binDir = "$SAGE_DIRECTORY/bin/"  # where the binary resides - this is where the config is copied to
68        self._nodeNum = 1
69        self._position = (100, 100)        # initial position of the window on SAGE
70        self._size = (-1, -1)          # initial size of the window on SAGE
71        self._command = ""                 # the actual command used to start the application
72        self._targetMachine = ""           # the render machine where the app will be started
73        self._protocol = "TCP"
74        self._masterIP = None              # the master machine of a parallel application
75        self._fsIP = None                  # which SAGE will the app connect to (if not using sageBridge)
76        self._fsPort = None                # which SAGE will the app connect to (if not using sageBridge)
77        self._useBridge = False            # if True the app will connect to sageBridge instead of fsManager
78        self._bridgeIP = ""                # the machine for sage bridge
79        self._bridgePort = ""              # the machine for sage bridge
80
81        self._additionalParams = ""        # any additional parameters you want to specify... used for testing
82
83        # audio stuff
84        self._audioFile = ""
85        self._framePerBuffer = 512
86             
87        self._nwID = 1
88        self._msgPort = 23010
89        self._syncPort = 13010
90        self._nodeNum = 1
91        self._appId = 0                    # the port number for the app on the render machine
92        self._blockSize = (64,64)
93        self._blockThreshold = 0
94        self._streamType = "SAGE_BLOCK_HARD_SYNC"    # sync mode
95        self._staticApp = False             # static applications dont refresh their windows so sage needs to keep the last frame
96        self._runOnNodes = False    # if an app has to connect to the outside world or requires
97                                    #an SDL/GLUT window for rendering then it can't run on the nodes
98       
99
100    def getName(self): return self._configName
101    def getAppName(self): return self._appName
102    def isDynamic(self): return self._dynamic
103    def getConfigFilename(self): return self._configFilename
104
105    # audio stuff
106    def setAudioFile(self, f):
107        self._audioFile = f
108    def getAudioFile(self):
109        return self._audioFile
110    def setFramePerBuffer(self, fpb):
111        self._framePerBuffer = fpb
112    def getFramePerBuffer(self):
113        return self._framePerBuffer
114   
115 
116    def getLauncherId(self):
117        return self._launcherId
118    def setLauncherId(self, launcherId):
119        self._launcherId = launcherId
120
121    def setBinDir(self, d):
122        self._binDir = d
123    def getBinDir(self):
124        return self._binDir
125
126    def setNodeNum(self, num): self._nodeNum = num
127    def getNodeNum(self): return self._nodeNum
128
129    def setPosition(self, pos): self._position = pos
130    def getPosition(self): return self._position
131
132    def setSize(self, size): self._size = size
133    def getSize(self): return self._size
134
135    def setCommand(self, command): self._command = command
136    def getCommand(self): return self._command
137
138    def setTargetMachine(self, target): self._targetMachine = target
139    def getTargetMachine(self): return self._targetMachine
140
141    def setProtocol(self, protocol):
142        if protocol == "tvTcpModule.so" or protocol=="TCP":
143            self._protocol = "TCP"
144        else:
145            self._protocol = "UDP"
146    def getProtocol(self): return self._protocol
147
148    def setMasterIP(self, ip):
149        self._masterIP = ip
150    def getMasterIP(self):
151        return self._masterIP
152
153    def setFSIP(self, ip):
154        self._fsIP = ip
155    def getFSIP(self):
156        return self._fsIP
157   
158    def setFSPort(self, port):
159        self._fsPort = port
160    def getFSPort(self):
161        return self._fsPort
162
163    def setBridgeIP(self, ip):
164        self._bridgeIP = ip
165    def getBridgeIP(self):
166        return self._bridgeIP
167
168    def setBridgePort(self, port):
169        self._bridgePort = port
170    def getBridgePort(self):
171        return self._bridgePort
172
173    def setUseBridge(self, doUse):
174        self._useBridge = doUse
175    def getUseBridge(self):
176        return self._useBridge
177
178    def setNWId(self, id):
179        self._nwID = id
180    def getNWId(self):
181        return self._nwID
182
183    def setMsgPort(self, port):
184        self._msgPort = port
185    def getMsgPort(self):
186        return self._msgPort
187
188    def setSyncPort(self, port):
189        self._syncPort = port
190    def getSyncPort(self):
191        return self._syncPort
192
193    def setAppId(self, id):
194        self._appId = id
195    def getAppId(self):
196        return self._appId
197
198    def setBlockSize(self, size):
199        self._blockSize = size
200    def getBlockSize(self):
201        return self._blockSize
202
203    def setBlockThreshold(self, threshold):
204        self._blockThreshold = threshold
205    def getBlockThreshold(self):
206        return self._blockThreshold
207
208    def setStreamType(self, mode):
209        self._streamType = mode
210    def getStreamType(self):
211        return self._streamType
212
213    def setStaticApp(self, do):
214        self._staticApp = do
215    def getStaticApp(self):
216        return self._staticApp
217
218    def setRunOnNodes(self, run):
219        self._runOnNodes = run
220    def getRunOnNodes(self):
221        return self._runOnNodes
222
223    def setAdditionalParams(self, param):
224        self._additionalParams += param + "\n"
225    def getAdditionalParams(self):
226        return self._additionalParams
227
228    def writeToFile(self):
229        s = ""
230
231        # sage bridge stuff
232        if self.getUseBridge():      # using sageBridge
233            s += 'bridgeOn true\n'
234            s += 'bridgeIP %s\n'% self.getBridgeIP()
235            s += 'bridgePort %s\n'% self.getBridgePort()
236        else:                        # not using sageBridge
237            s += 'bridgeOn false\n'
238           
239        s += 'fsIP %s\n'% self.getFSIP()
240        s += 'fsPort %s\n'% self.getFSPort()
241        s += 'masterIP %s\n'% self.getMasterIP()
242        s += 'nwID %d\n' % self.getNWId()
243        s += 'msgPort %d\n' % self.getMsgPort()
244        s += 'syncPort %d\n' % self.getSyncPort()
245        s += 'nodeNum %d\n' % self.getNodeNum()
246        s += 'appID %d\n' % self.getAppId()
247        s += 'launcherID %s\n' % self.getLauncherId()
248        s += 'pixelBlockSize %d %d\n' % (self.getBlockSize()[0], self.getBlockSize()[1])
249        s += 'blockThreshold %d\n' % self.getBlockThreshold()
250        s += 'winX %d\n' % self.getPosition()[0]
251        s += 'winY %d\n' % self.getPosition()[1]
252        s += 'winWidth %d\n' % self.getSize()[0]
253        s += 'winHeight %d\n' % self.getSize()[1]
254        s += 'streamType %s\n' % self.getStreamType()
255        s += 'nwProtocol %s\n' % self.getProtocol()
256
257        # audio
258        if self.getAudioFile():
259            s += 'audioOn true\n'
260            s += 'audioFile %s\n' % self.getAudioFile()
261            s += 'audioType read\ndeviceNum -1\n'
262            s += 'framePerBuffer %d\n' % self.getFramePerBuffer()
263           
264        # static app
265        if self.getStaticApp():
266            s += 'asyncUpdate true\n'
267        else:
268            s += 'asyncUpdate false\n'
269
270        # additional params
271        s += self.getAdditionalParams()
272           
273        f = open(self._configFilename, "w")
274        f.write(s)
275        f.close()
276
277
278    def getConfigString(self):
279        """ returns a tuple of strings: (configName, optionalArgs that the app was started with) """
280        return (self.getName(), self.getCommand().split(" ", 1)[1].strip())
281   
282
283
284
285class AppConfig:
286    ''' a collection of all the configurations for an app '''
287   
288    def __init__(self, appName):
289        self._configs = {}   #key=configName, value=OneConfig object
290        self._appName = appName
291
292    def getAppName(self):
293        return self._appName
294
295    def addConfig(self, oneConfig):
296        self._configs[oneConfig.getName()] = oneConfig
297
298    def getConfig(self, configName):
299        return self._configs[configName]
300   
301    def getDefaultConfig(self):
302        return self._configs.values()[0]  #return an arbitrary config file
303
304    def getAllConfigs(self):
305        return self._configs
306   
307    def getAllConfigNames(self):
308        return self._configs.keys()
309   
310    def makeConfigFile(self, configName):
311        config = self.getConfig(configName)
312        config.writeToFile()
313
314
315
316   
317
318class Configurations:
319    ''' a collection of all applications and their configurations '''
320   
321    def __init__(self, configFile):
322        self._configFile = configFile
323        self._lastModTime = None  #last modification time to the config file
324        # sageBridge stuff
325        self._bridgeIP = None
326        self._bridgePort = None
327
328        self._appConfigs = {}   #key=appName, value=AppConfig object
329        self._readConfig()
330        #self._printConfig()
331
332
333        # so that we can change the config file without restarting the appLauncher
334        # checks the last modification time so that we don't reload unnecessarily
335    def reloadConfigFile(self):
336        try:
337            lastModTime = os.path.getmtime(self._configFile)
338            if lastModTime != self._lastModTime:
339                self._appConfigs = {}  #empty out the hash
340                self._readConfig()
341                self._lastModTime = lastModTime
342        except:
343            WriteLog( "".join(tb.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2])) )
344           
345       
346    def getConfig(self, appName, configName):   #returns a copy so that it can be safely modified without the destroying what's in the config file
347        return copy.deepcopy( self._appConfigs[appName].getConfig(configName) )
348
349    def getDefaultConfig(self, appName):   #returns a copy so that it can be safely modified without destroying what's in the config file
350        return copy.deepcopy( self._appConfigs[appName].getDefaultConfig() )   
351
352    def getApp(self, appName):
353        return self._appConfigs[appName]
354
355    def getAppList(self):   # returns just the names of the apps
356        return self._appConfigs.keys()
357
358    def getBridgeIP(self):
359        return self._bridgeIP
360
361    def getBridgePort(self):
362        return self._bridgePort
363
364    def _printConfig(self):
365        for name, app in self._appConfigs.iteritems():
366            print "\n----------------------------------------"
367            print "Config For: ", name
368            for name, config in app.getAllConfigs().iteritems():
369                print "Config: ", name
370                print "nodeNum = ", config.getNodeNum()
371                print "pos = ", config.getPosition()
372                print "size = ", config.getSize()
373                print "command = ", config.getCommand()
374                print "target = ", config.getTargetMachine()
375                print "protocol = ", config.getProtocol()
376                print "runOnNodes = ", config.getRunOnNodes()
377
378        print "\n----------------------------------------"
379        print "bridgePort = ", self._bridgePort
380        print "bridgeIP = ", self._bridgeIP
381
382
383    def getConfigHash(self):
384        """ returns a hash of all the configurations without the objects... just tuples of strings and ints """
385        strHash = {}   #keyed by appName, value = a list of configNames
386        for appName, app in self._appConfigs.iteritems():
387            strHash[appName] = app.getAllConfigNames()
388        return strHash
389   
390               
391    def _readConfig(self):
392        f = open(self._configFile, "r")
393        lines = f.readlines()
394        f.close()
395
396        self.appconfig = None
397        self.oneconfig = None
398        self.lineCounter = 0
399       
400        for line in lines:
401            self.lineCounter += 1
402
403            # allow comments with #
404            if '#' in line:
405                line = line.split('#')[0].strip()
406               
407               
408            if '{' in line:
409                appName = line.replace('{', ' ').strip()
410                self.appconfig = AppConfig(appName)
411               
412            elif 'configName' in line:
413                if self.oneconfig:
414                    self.appconfig.addConfig(self.oneconfig)
415                self.oneconfig = OneConfig(line.lstrip('configName').strip(), self.appconfig.getAppName())
416
417            elif 'nodeNum' in line:
418                self.oneconfig.setNodeNum(int(line.lstrip('nodeNum').strip()))
419
420            elif 'Init' in line:
421                lineTokens = line.split()
422                pos = (int(lineTokens[1]), int(lineTokens[2]))
423                size = (int(lineTokens[3]), int(lineTokens[4]))
424                self.oneconfig.setPosition(pos)
425                self.oneconfig.setSize(size)
426
427            elif 'exec' in line:
428                bla, target, command = line.split(' ', 2)
429                self.oneconfig.setTargetMachine(target.strip())
430                if not self.oneconfig.getMasterIP():   #if it has been set, dont overwrite it
431                    self.oneconfig.setMasterIP(target.strip())
432                self.oneconfig.setCommand(command.strip())
433
434            elif 'nwProtocol' in line:
435                self.oneconfig.setProtocol(line.lstrip('nwProtocol').strip())
436
437            elif 'bridgeIP' in line:
438                self.oneconfig.setBridgeIP(line.split()[1].strip())
439
440            elif 'bridgePort' in line:
441                self.oneconfig.setBridgePort(line.split()[1].strip())
442
443            elif 'runOnNodes' in line:
444                self.oneconfig.setRunOnNodes(True)
445
446            elif 'staticApp' in line:
447                self.oneconfig.setStaticApp(True)
448
449            elif 'pixelBlockSize' in line:
450                s = line.split()
451                self.oneconfig.setBlockSize( (int(s[1].strip()), int(s[2].strip()))  )
452
453            elif 'binDir' in line:
454                p = line.split()[1].strip()
455                if not p.endswith("/"):
456                    p += "/"
457                self.oneconfig.setBinDir(p)
458
459            elif 'masterIP' in line:
460                self.oneconfig.setMasterIP(line.split()[1].strip())
461
462            elif 'audioFile' in line:
463                self.oneconfig.setAudioFile(line.split()[1].strip())
464
465            elif 'framePerBuffer' in line:
466                self.oneconfig.setFramePerBuffer(int(line.split()[1].strip()))
467
468            elif 'sync' in line:
469                mode = line.split()[1].strip()
470                if not mode.startswith("SAGE_BLOCK_"):
471                    mode = "SAGE_BLOCK_" + mode
472                   
473                if mode == "SAGE_BLOCK_NO_SYNC" or \
474                   mode == "SAGE_BLOCK_SOFT_SYNC" or \
475                   mode == "SAGE_BLOCK_HARD_SYNC":
476                    self.oneconfig.setStreamType(mode)
477                else:
478                    WriteLog("\n*** Invalid streamType mode on line: "+str(self.lineCounter)+". Defaulting to NO_SYNC")
479
480            elif '}' in line:
481                self.appconfig.addConfig(self.oneconfig)   #save the last config
482                self._appConfigs[self.appconfig.getAppName()] = self.appconfig   #save the appConfig
483                self.appconfig = None   #reinitialize everything
484                self.oneconfig = None
485
486
487            elif 'defaultBridgeIP' in line:
488                self._bridgeIP = line.split()[1].strip()
489
490            elif 'defaultBridgePort' in line:
491                self._bridgePort = line.split()[1].strip()
492
493
494            elif line in string.whitespace:
495                pass
496           
497            else:    # if line is not recognized
498                self.oneconfig.setAdditionalParams(line.strip())
499             
500
501
502
503
504       
505                                 
506   
Note: See TracBrowser for help on using the repository browser.