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 #new convert procedures, temporary could be use not to be automatically deleted
47 temp = tempfile.NamedTemporaryFile(suffix='.cfg', delete=False)
48 #temp = tempfile.NamedTemporaryFile(suffix='.cfg')
50 convertEnvFileToConfigFile(filename, temp.name)
51 self.__setEnvironmentFromConfigFile(temp.name)
52 except ConfigParser.ParsingError, e:
53 self.getLogger().warning("Invalid token found when parsing file: %s\n"%(filename))
57 # Automatically cleans up the file
60 self.getLogger().warning("Unrecognized extension for configuration file: %s", filename)
64 # Run this module as a script, in order to use appropriate Python interpreter
65 # according to current path (initialized from environment files).
66 absoluteAppliPath = os.getenv('ABSOLUTE_APPLI_PATH','')
67 proc = subprocess.Popen(['python', absoluteAppliPath+'/bin/salome/salomeRunner.py', pickle.dumps(self), pickle.dumps(args)], shell=False, close_fds=True)
71 """Append value to PATH environment variable"""
72 def addToPath(self, value):
73 self.__addToReserved('PATH', value)
76 """Append value to LD_LIBRARY_PATH environment variable"""
77 def addToLdLibraryPath(self, value):
78 self.__addToReserved('LD_LIBRARY_PATH', value)
81 """Append value to PYTHONPATH environment variable"""
82 def addToPythonPath(self, value):
83 self.__addToReserved('PYTHONPATH', value)
86 """Set environment variable to value"""
87 def setEnviron(self, name, value, overwrite=False):
88 env = os.getenv(name, '')
89 if env and not overwrite:
90 self.getLogger().warning("Environment variable already existing and not overwritten: %s", name)
94 self.getLogger().info("Overwriting environment variable: %s", name)
96 value = os.path.expandvars(value) # expand environment variables
97 self.getLogger().debug("Set environment variable: %s=%s", name, value)
98 os.environ[name] = value
101 """Unset environment variable"""
102 def unsetEnviron(self, name):
103 if os.environ.has_key(name):
107 ###################################
108 # This begins the private section #
109 ###################################
111 def _usage(self, unused=[]):
112 exeName = os.path.splitext(os.path.basename(__file__))[0]
115 Usage: %s [command] [options] [--config=file1,...,filen]
118 start Launches SALOME virtual application [DEFAULT]
119 shell Executes a script under SALOME application environment
120 connect Connects a Python console to the active SALOME session
121 killall Kill all SALOME running sessions
122 info Display some information about SALOME
123 help Show this message
124 coffee Yes! SALOME can also make coffee!!"\
131 def __parseArguments(self, args):
132 if len(args) == 0 or args[0].startswith("-"):
138 availableCommands = {
139 'start' : '_runAppli',
140 'shell' : '_runSession',
141 'connect' : '_runConsole',
142 'killall': '_killAll',
145 'coffee' : '_makeCoffee'
148 if not command in availableCommands.keys():
149 self.getLogger().error("Unrecognized command: %s.", command)
153 return availableCommands[command], options
158 Args consist in a mandatory command followed by optionnal parameters.
159 See usage for details on commands.
161 def _getStarted(self, args):
162 command, options = self.__parseArguments(args)
166 if args and args[0] in ["-h","--help","help"]:
169 # try to default to "start" command
170 command = "_runAppli"
173 getattr(self, command)(options) # run appropriate method
174 except AttributeError:
175 self.getLogger().error("Method %s is not implemented.", command)
178 self.getLogger().error("Unexpected error:")
180 traceback.print_exc()
184 def __setEnvironmentFromConfigFile(self, filename):
185 unsetVars, configVars, reservedDict = parseConfigFile(filename, reserved=['PATH', 'LD_LIBRARY_PATH', 'PYTHONPATH'])
188 for var in unsetVars:
189 self.unsetEnviron(var)
192 for reserved in reservedDict:
193 a = filter(None, reservedDict[reserved]) # remove empty elements
194 reformattedVals = ':'.join(a)
195 self.__addToReserved(reserved, reformattedVals)
198 for key,val in configVars:
199 self.setEnviron(key, val, overwrite=True)
202 sys.path[:0] = os.getenv('PYTHONPATH','').split(':')
205 def __addToReserved(self, name, value):
209 value = os.path.expandvars(value) # expand environment variables
210 self.getLogger().debug("Add to %s: %s", name, value)
211 env = os.getenv(name, None)
213 os.environ[name] = value
215 os.environ[name] = value + os.pathsep + env
218 def _runAppli(self, args=[]):
219 # Initialize SALOME environment
220 sys.argv = ['runSalome'] + args
225 runSalome.runSalome()
228 def _runSession(self, args=[]):
229 sys.argv = ['runSession'] + args
231 runSession.configureSession(args)
238 # if exe does not contain any slashes (/), search in PATH
239 # if exe contains slashes:
240 # if exe begins with a slash, use this absolute path
241 # else build absolute path relative to current working directory
242 if (os.sep in exe) and (exe[0] is not os.sep):
243 args[0] = os.getcwd() + os.sep + exe
245 proc = subprocess.Popen(args, shell=False, close_fds=True)
248 absoluteAppliPath = os.getenv('ABSOLUTE_APPLI_PATH','')
249 cmd = ["/bin/bash", "--rcfile", absoluteAppliPath + "/.bashrc" ]
250 proc = subprocess.Popen(cmd, shell=False, close_fds=True)
254 def _runConsole(self, args=[]):
255 # Initialize SALOME environment
256 sys.argv = ['runConsole'] + args
264 def _killAll(self, args=[]):
265 #self._runAppli(['-k'] + args)
266 from killSalome import killAllPorts
270 def _showInfo(self, args=[]):
271 print "Running with python", platform.python_version()
272 self._runAppli(["--version"])
275 def _makeCoffee(self, args=[]):
278 print " ___...(-------)-....___"
279 print " .-\"\" ) ( \"\"-."
280 print " .-\'``\'|-._ ) _.-|"
281 print " / .--.| `\"\"---...........---\"\"` |"
289 print " _..---\"\"` \\ /`\"\"---.._"
290 print " .-\' \\ / \'-."
291 print " : `-.__ __.-\' :"
292 print " : ) \"\"---...---\"\" ( :"
293 print " \'._ `\"--...___...--\"` _.\'"
294 print " \\\"\"--..__ __..--\"\"/"
295 print " \'._ \"\"\"----.....______.....----\"\"\" _.\'"
296 print " `\"\"--..,,_____ _____,,..--\"\"`"
297 print " `\"\"\"----\"\"\"`"
301 # Add the following two methods since logger is not pickable
302 # Ref: http://stackoverflow.com/questions/2999638/how-to-stop-attributes-from-being-pickled-in-python
303 def __getstate__(self):
304 d = dict(self.__dict__)
305 if hasattr(self, '_logger'):
309 def __setstate__(self, d):
310 self.__dict__.update(d) # I *think* this is a safe way to do it
312 # Excluding self._logger from pickle operation imply using the following method to access logger
314 if not hasattr(self, '_logger'):
315 self._logger = logging.getLogger(__name__)
316 #self._logger.setLevel(logging.DEBUG)
322 if __name__ == "__main__":
323 if len(sys.argv) == 3:
324 runner = pickle.loads(sys.argv[1])
325 args = pickle.loads(sys.argv[2])
326 runner._getStarted(args)
328 SalomeRunner()._usage()