5 from parseConfigFile import parseConfigFile
6 from parseConfigFile import convertEnvFileToConfigFile
15 Define a specific exception class to manage exceptions related to SalomeRunner
17 class SalomeRunnerException(Exception):
18 """Report error messages to the user interface of SalomeRunner."""
23 The SalomeRunner class in an API to configure SALOME environment then
24 start SALOME using a single python command.
29 Initialize environment from a list of configuration files
30 identified by their names.
31 These files should be in appropriate (new .cfg) format.
32 However you can give old .sh environment files; in this case,
33 the SalomeRunner class will try to automatically convert them
34 to .cfg format before setting the environment.
36 def __init__(self, configFileNames=[]):
37 if len(configFileNames) == 0:
38 raise SalomeRunnerException("No configuration files given")
40 for filename in configFileNames:
41 basename, extension = os.path.splitext(filename)
42 if extension == ".cfg":
43 self.__setEnvironmentFromConfigFile(filename)
44 elif extension == ".sh":
45 temp = tempfile.NamedTemporaryFile(suffix='.cfg')
47 convertEnvFileToConfigFile(filename, temp.name)
48 self.__setEnvironmentFromConfigFile(temp.name)
50 # Automatically cleans up the file
53 self.getLogger().warning("Unrecognized extension for configuration file: %s", filename)
57 # Run this module as a script, in order to use appropriate Python interpreter
58 # according to current path (initialized from environment files).
59 absoluteAppliPath = os.getenv('ABSOLUTE_APPLI_PATH','')
60 proc = subprocess.Popen(['python', absoluteAppliPath+'/bin/salome/salomeRunner.py', pickle.dumps(self), pickle.dumps(args)], shell=False, close_fds=True)
64 """Append value to PATH environment variable"""
65 def addToPath(self, value):
66 self.__addToReserved('PATH', value)
69 """Append value to LD_LIBRARY_PATH environment variable"""
70 def addToLdLibraryPath(self, value):
71 self.__addToReserved('LD_LIBRARY_PATH', value)
74 """Append value to PYTHONPATH environment variable"""
75 def addToPythonPath(self, value):
76 self.__addToReserved('PYTHONPATH', value)
79 """Set environment variable to value"""
80 def setEnviron(self, name, value, overwrite=False):
81 env = os.getenv(name, '')
82 if env and not overwrite:
83 self.getLogger().warning("Environment variable already existing and not overwritten: %s", name)
87 self.getLogger().info("Overwriting environment variable: %s", name)
89 value = os.path.expandvars(value) # expand environment variables
90 self.getLogger().debug("Set environment variable: %s=%s", name, value)
91 os.environ[name] = value
94 ###################################
95 # This begins the private section #
96 ###################################
98 def _usage(self, unused=[]):
99 exeName = os.path.splitext(os.path.basename(__file__))[0]
102 Usage: %s [command] [options] [--config=file1,...,filen]
105 start Launches SALOME virtual application [DEFAULT]
106 shell Executes a script under SALOME application environment
107 connect Connects a Python console to the active SALOME session
108 killall Kill all SALOME running sessions
109 info Display some information about SALOME
110 help Show this message
111 coffee Yes! SALOME can also make coffee!!"\
118 def __parseArguments(self, args):
119 if len(args) == 0 or args[0].startswith("-"):
125 availableCommands = {
126 'start' : '_runAppli',
127 'shell' : '_runSession',
128 'connect' : '_runConsole',
129 'killall': '_killAll',
132 'coffee' : '_makeCoffee'
135 if not command in availableCommands.keys():
136 self.getLogger().error("Unrecognized command: %s.", command)
140 return availableCommands[command], options
145 Args consist in a mandatory command followed by optionnal parameters.
146 See usage for details on commands.
148 def _getStarted(self, args):
149 command, options = self.__parseArguments(args)
153 if args and args[0] in ["-h","--help","help"]:
156 # try to default to "start" command
157 command = "_runAppli"
160 getattr(self, command)(options) # run appropriate method
161 except AttributeError:
162 self.getLogger().error("Method %s is not implemented.", command)
166 def __setEnvironmentFromConfigFile(self, filename):
167 configVars, reservedDict = parseConfigFile(filename, reserved=['PATH', 'LD_LIBRARY_PATH', 'PYTHONPATH'])
170 for reserved in reservedDict:
171 a = filter(None, reservedDict[reserved]) # remove empty elements
172 reformattedVals = ':'.join(a)
173 self.__addToReserved(reserved, reformattedVals)
176 for key,val in configVars:
177 self.setEnviron(key, val, overwrite=True)
180 sys.path[:0] = os.getenv('PYTHONPATH','').split(':')
183 def __addToReserved(self, name, value):
187 value = os.path.expandvars(value) # expand environment variables
188 self.getLogger().debug("Add to %s: %s", name, value)
189 env = os.getenv(name, None)
191 os.environ[name] = value
193 os.environ[name] = value + os.pathsep + env
196 def _runAppli(self, args=[]):
197 # Initialize SALOME environment
198 sys.argv = ['runSalome'] + args
203 runSalome.runSalome()
206 def _runSession(self, args=[]):
207 sys.argv = ['runSession'] + args
209 runSession.configureSession(args)
216 # if exe does not contain any slashes (/), search in PATH
217 # if exe contains slashes:
218 # if exe begins with a slash, use this absolute path
219 # else build absolute path relative to current working directory
220 if (os.sep in exe) and (exe[0] is not os.sep):
221 args[0] = os.getcwd() + os.sep + exe
223 proc = subprocess.Popen(args, shell=False, close_fds=True)
226 absoluteAppliPath = os.getenv('ABSOLUTE_APPLI_PATH','')
227 cmd = ["/bin/bash", "--rcfile", absoluteAppliPath + "/.bashrc" ]
228 proc = subprocess.Popen(cmd, shell=False, close_fds=True)
232 def _runConsole(self, args=[]):
233 # Initialize SALOME environment
234 sys.argv = ['runConsole'] + args
242 def _killAll(self, args=[]):
243 #self._runAppli(['-k'] + args)
244 from killSalome import killAllPorts
248 def _showInfo(self, args=[]):
249 print "Running with python", platform.python_version()
250 self._runAppli(["--version"])
253 def _makeCoffee(self, args=[]):
256 print " ___...(-------)-....___"
257 print " .-\"\" ) ( \"\"-."
258 print " .-\'``\'|-._ ) _.-|"
259 print " / .--.| `\"\"---...........---\"\"` |"
267 print " _..---\"\"` \\ /`\"\"---.._"
268 print " .-\' \\ / \'-."
269 print " : `-.__ __.-\' :"
270 print " : ) \"\"---...---\"\" ( :"
271 print " \'._ `\"--...___...--\"` _.\'"
272 print " \\\"\"--..__ __..--\"\"/"
273 print " \'._ \"\"\"----.....______.....----\"\"\" _.\'"
274 print " `\"\"--..,,_____ _____,,..--\"\"`"
275 print " `\"\"\"----\"\"\"`"
279 # Add the following two methods since logger is not pickable
280 # Ref: http://stackoverflow.com/questions/2999638/how-to-stop-attributes-from-being-pickled-in-python
281 def __getstate__(self):
282 d = dict(self.__dict__)
283 if hasattr(self, '_logger'):
287 def __setstate__(self, d):
288 self.__dict__.update(d) # I *think* this is a safe way to do it
290 # Excluding self._logger from pickle operation imply using the following method to access logger
292 if not hasattr(self, '_logger'):
293 self._logger = logging.getLogger(__name__)
294 #self._logger.setLevel(logging.DEBUG)
300 if __name__ == "__main__":
301 if len(sys.argv) == 3:
302 runner = pickle.loads(sys.argv[1])
303 args = pickle.loads(sys.argv[2])
304 runner._getStarted(args)
306 SalomeRunner()._usage()