6 from parseConfigFile import parseConfigFile
7 from parseConfigFile import convertEnvFileToConfigFile
16 Define a specific exception class to manage exceptions related to SalomeRunner
18 class SalomeRunnerException(Exception):
19 """Report error messages to the user interface of SalomeRunner."""
24 The SalomeRunner class in an API to configure SALOME environment then
25 start SALOME using a single python command.
30 Initialize environment from a list of configuration files
31 identified by their names.
32 These files should be in appropriate (new .cfg) format.
33 However you can give old .sh environment files; in this case,
34 the SalomeRunner class will try to automatically convert them
35 to .cfg format before setting the environment.
37 def __init__(self, configFileNames=[]):
38 if len(configFileNames) == 0:
39 raise SalomeRunnerException("No configuration files given")
41 for filename in configFileNames:
42 basename, extension = os.path.splitext(filename)
43 if extension == ".cfg":
44 self.__setEnvironmentFromConfigFile(filename)
45 elif extension == ".sh":
46 #temp = tempfile.NamedTemporaryFile(suffix='.cfg', delete=False)
47 temp = tempfile.NamedTemporaryFile(suffix='.cfg')
49 convertEnvFileToConfigFile(filename, temp.name)
50 self.__setEnvironmentFromConfigFile(temp.name)
51 except ConfigParser.ParsingError, e:
52 self.getLogger().warning("Invalid token found when parsing file: %s\n"%(filename))
56 # Automatically cleans up the file
59 self.getLogger().warning("Unrecognized extension for configuration file: %s", filename)
63 # Run this module as a script, in order to use appropriate Python interpreter
64 # according to current path (initialized from environment files).
65 absoluteAppliPath = os.getenv('ABSOLUTE_APPLI_PATH','')
66 proc = subprocess.Popen(['python', absoluteAppliPath+'/bin/salome/salomeRunner.py', pickle.dumps(self), pickle.dumps(args)], shell=False, close_fds=True)
70 """Append value to PATH environment variable"""
71 def addToPath(self, value):
72 self.__addToReserved('PATH', value)
75 """Append value to LD_LIBRARY_PATH environment variable"""
76 def addToLdLibraryPath(self, value):
77 self.__addToReserved('LD_LIBRARY_PATH', value)
80 """Append value to PYTHONPATH environment variable"""
81 def addToPythonPath(self, value):
82 self.__addToReserved('PYTHONPATH', value)
85 """Set environment variable to value"""
86 def setEnviron(self, name, value, overwrite=False):
87 env = os.getenv(name, '')
88 if env and not overwrite:
89 self.getLogger().warning("Environment variable already existing and not overwritten: %s", name)
93 self.getLogger().info("Overwriting environment variable: %s", name)
95 value = os.path.expandvars(value) # expand environment variables
96 self.getLogger().debug("Set environment variable: %s=%s", name, value)
97 os.environ[name] = value
100 """Unset environment variable"""
101 def unsetEnviron(self, name):
102 if os.environ.has_key(name):
106 ###################################
107 # This begins the private section #
108 ###################################
110 def _usage(self, unused=[]):
111 exeName = os.path.splitext(os.path.basename(__file__))[0]
114 Usage: %s [command] [options] [--config=file1,...,filen]
117 start Launches SALOME virtual application [DEFAULT]
118 shell Executes a script under SALOME application environment
119 connect Connects a Python console to the active SALOME session
120 killall Kill all SALOME running sessions
121 info Display some information about SALOME
122 help Show this message
123 coffee Yes! SALOME can also make coffee!!"\
130 def __parseArguments(self, args):
131 if len(args) == 0 or args[0].startswith("-"):
137 availableCommands = {
138 'start' : '_runAppli',
139 'shell' : '_runSession',
140 'connect' : '_runConsole',
141 'killall': '_killAll',
144 'coffee' : '_makeCoffee'
147 if not command in availableCommands.keys():
148 self.getLogger().error("Unrecognized command: %s.", command)
152 return availableCommands[command], options
157 Args consist in a mandatory command followed by optionnal parameters.
158 See usage for details on commands.
160 def _getStarted(self, args):
161 command, options = self.__parseArguments(args)
165 if args and args[0] in ["-h","--help","help"]:
168 # try to default to "start" command
169 command = "_runAppli"
172 getattr(self, command)(options) # run appropriate method
173 except AttributeError:
174 self.getLogger().error("Method %s is not implemented.", command)
177 self.getLogger().error("Unexpected error:")
179 traceback.print_exc()
183 def __setEnvironmentFromConfigFile(self, filename):
184 unsetVars, configVars, reservedDict = parseConfigFile(filename, reserved=['PATH', 'LD_LIBRARY_PATH', 'PYTHONPATH'])
187 for var in unsetVars:
188 self.unsetEnviron(var)
191 for reserved in reservedDict:
192 a = filter(None, reservedDict[reserved]) # remove empty elements
193 reformattedVals = ':'.join(a)
194 self.__addToReserved(reserved, reformattedVals)
197 for key,val in configVars:
198 self.setEnviron(key, val, overwrite=True)
201 sys.path[:0] = os.getenv('PYTHONPATH','').split(':')
204 def __addToReserved(self, name, value):
208 value = os.path.expandvars(value) # expand environment variables
209 self.getLogger().debug("Add to %s: %s", name, value)
210 env = os.getenv(name, None)
212 os.environ[name] = value
214 os.environ[name] = value + os.pathsep + env
217 def _runAppli(self, args=[]):
218 # Initialize SALOME environment
219 sys.argv = ['runSalome'] + args
224 runSalome.runSalome()
227 def _runSession(self, args=[]):
228 sys.argv = ['runSession'] + args
230 runSession.configureSession(args)
237 # if exe does not contain any slashes (/), search in PATH
238 # if exe contains slashes:
239 # if exe begins with a slash, use this absolute path
240 # else build absolute path relative to current working directory
241 if (os.sep in exe) and (exe[0] is not os.sep):
242 args[0] = os.getcwd() + os.sep + exe
244 proc = subprocess.Popen(args, shell=False, close_fds=True)
247 absoluteAppliPath = os.getenv('ABSOLUTE_APPLI_PATH','')
248 cmd = ["/bin/bash", "--rcfile", absoluteAppliPath + "/.bashrc" ]
249 proc = subprocess.Popen(cmd, shell=False, close_fds=True)
253 def _runConsole(self, args=[]):
254 # Initialize SALOME environment
255 sys.argv = ['runConsole'] + args
263 def _killAll(self, args=[]):
264 #self._runAppli(['-k'] + args)
265 from killSalome import killAllPorts
269 def _showInfo(self, args=[]):
270 print "Running with python", platform.python_version()
271 self._runAppli(["--version"])
274 def _makeCoffee(self, args=[]):
277 print " ___...(-------)-....___"
278 print " .-\"\" ) ( \"\"-."
279 print " .-\'``\'|-._ ) _.-|"
280 print " / .--.| `\"\"---...........---\"\"` |"
288 print " _..---\"\"` \\ /`\"\"---.._"
289 print " .-\' \\ / \'-."
290 print " : `-.__ __.-\' :"
291 print " : ) \"\"---...---\"\" ( :"
292 print " \'._ `\"--...___...--\"` _.\'"
293 print " \\\"\"--..__ __..--\"\"/"
294 print " \'._ \"\"\"----.....______.....----\"\"\" _.\'"
295 print " `\"\"--..,,_____ _____,,..--\"\"`"
296 print " `\"\"\"----\"\"\"`"
300 # Add the following two methods since logger is not pickable
301 # Ref: http://stackoverflow.com/questions/2999638/how-to-stop-attributes-from-being-pickled-in-python
302 def __getstate__(self):
303 d = dict(self.__dict__)
304 if hasattr(self, '_logger'):
308 def __setstate__(self, d):
309 self.__dict__.update(d) # I *think* this is a safe way to do it
311 # Excluding self._logger from pickle operation imply using the following method to access logger
313 if not hasattr(self, '_logger'):
314 self._logger = logging.getLogger(__name__)
315 #self._logger.setLevel(logging.DEBUG)
321 if __name__ == "__main__":
322 if len(sys.argv) == 3:
323 runner = pickle.loads(sys.argv[1])
324 args = pickle.loads(sys.argv[2])
325 runner._getStarted(args)
327 SalomeRunner()._usage()