6 from parseConfigFile import parseConfigFile
7 from parseConfigFile import convertEnvFileToConfigFile
14 from salomeLauncherUtils import SalomeRunnerException
15 from salomeLauncherUtils import getScriptsAndArgs, formatScriptsAndArgs
18 #exeName = os.path.splitext(os.path.basename(__file__))[0]
21 Usage: salome [command] [options] [--config=file1,...,filen]
24 start Launches SALOME virtual application [DEFAULT]
25 shell Executes a script under SALOME application environment
26 connect Connects a Python console to the active SALOME session
27 killall Kill all SALOME running sessions
28 info Display some information about SALOME
29 help Show this message
30 coffee Yes! SALOME can also make coffee!!"
32 Use salome start --help or salome shell --help
33 to show help on start and shell commands.
40 The SalomeRunner class in an API to configure SALOME environment then
41 start SALOME using a single python command.
46 Initialize environment from a list of configuration files
47 identified by their names.
48 These files should be in appropriate (new .cfg) format.
49 However you can give old .sh environment files; in this case,
50 the SalomeRunner class will try to automatically convert them
51 to .cfg format before setting the environment.
53 def __init__(self, configFileNames=[]):
54 #it could be None explicitely (if user use multiples setEnviron...for standalone)
55 if configFileNames==None:
58 if len(configFileNames) == 0:
59 raise SalomeRunnerException("No configuration files given")
61 for filename in configFileNames:
62 basename, extension = os.path.splitext(filename)
63 if extension == ".cfg":
64 self.__setEnvironmentFromConfigFile(filename)
65 elif extension == ".sh":
66 #new convert procedures, temporary could be use not to be automatically deleted
67 #temp = tempfile.NamedTemporaryFile(suffix='.cfg', delete=False)
68 temp = tempfile.NamedTemporaryFile(suffix='.cfg')
70 convertEnvFileToConfigFile(filename, temp.name)
71 self.__setEnvironmentFromConfigFile(temp.name)
72 except ConfigParser.ParsingError, e:
73 self.getLogger().warning("Invalid token found when parsing file: %s\n"%(filename))
77 # Automatically cleans up the file
80 self.getLogger().warning("Unrecognized extension for configuration file: %s", filename)
84 # Run this module as a script, in order to use appropriate Python interpreter
85 # according to current path (initialized from environment files).
86 absoluteAppliPath = os.getenv('ABSOLUTE_APPLI_PATH','')
87 proc = subprocess.Popen(['python', absoluteAppliPath+'/bin/salome/salomeRunner.py', pickle.dumps(self), pickle.dumps(args)], shell=False, close_fds=True)
91 """Append value to PATH environment variable"""
92 def addToPath(self, value):
93 self.__addToReserved('PATH', value)
96 """Append value to LD_LIBRARY_PATH environment variable"""
97 def addToLdLibraryPath(self, value):
98 self.__addToReserved('LD_LIBRARY_PATH', value)
101 """Append value to PYTHONPATH environment variable"""
102 def addToPythonPath(self, value):
103 self.__addToReserved('PYTHONPATH', value)
106 """Append value to TCLLIBPATH environment variable"""
107 def addToTclLibPath(self, value):
108 self.__addToReservedTclTk('TCLLIBPATH', value)
111 """Append value to TKLIBPATH environment variable"""
112 def addToTkLibPath(self, value):
113 self.__addToReservedTclTk('TKLIBPATH', value)
116 """Set environment variable to value"""
117 def setEnviron(self, name, value, overwrite=False):
118 env = os.getenv(name, '')
119 if env and not overwrite:
120 self.getLogger().warning("Environment variable already existing (and not overwritten): %s=%s", name, value)
124 self.getLogger().warning("Overwriting environment variable: %s=%s", name, value)
126 value = os.path.expandvars(value) # expand environment variables
127 self.getLogger().debug("Set environment variable: %s=%s", name, value)
128 os.environ[name] = value
131 """Unset environment variable"""
132 def unsetEnviron(self, name):
133 if os.environ.has_key(name):
137 ###################################
138 # This begins the private section #
139 ###################################
141 def __parseArguments(self, args):
142 if len(args) == 0 or args[0].startswith("-"):
148 availableCommands = {
149 'start' : '_runAppli',
150 'shell' : '_runSession',
151 'connect' : '_runConsole',
152 'killall': '_killAll',
155 'coffee' : '_makeCoffee'
158 if not command in availableCommands.keys():
162 return availableCommands[command], options
167 Args consist in a mandatory command followed by optionnal parameters.
168 See usage for details on commands.
170 def _getStarted(self, args):
171 command, options = self.__parseArguments(args)
175 if args and args[0] in ["-h","--help","help"]:
178 # try to default to "start" command
179 command = "_runAppli"
182 res = getattr(self, command)(options) # run appropriate method
183 return res or (None, None)
184 except SystemExit, exc:
186 sys.exit(0) #catch sys.exit(0) happy end no warning
188 self.getLogger().warning("SystemExit 1 in method %s.", command)
190 except StandardError:
191 self.getLogger().error("Unexpected error:")
193 traceback.print_exc()
195 except SalomeRunnerException, e:
196 self.getLogger().error(e)
200 def __setEnvironmentFromConfigFile(self, filename):
201 unsetVars, configVars, reservedDict = parseConfigFile(filename, reserved=['PATH', 'LD_LIBRARY_PATH', 'PYTHONPATH'])
204 for var in unsetVars:
205 self.unsetEnviron(var)
208 for reserved in reservedDict:
209 a = filter(None, reservedDict[reserved]) # remove empty elements
210 reformattedVals = ':'.join(a)
211 self.__addToReserved(reserved, reformattedVals)
214 for key,val in configVars:
215 self.setEnviron(key, val, overwrite=True)
218 sys.path[:0] = os.getenv('PYTHONPATH','').split(':')
221 def __addToReserved(self, name, value):
225 value = os.path.expandvars(value) # expand environment variables
226 self.getLogger().debug("Add to %s: %s", name, value)
227 env = os.getenv(name, None)
229 os.environ[name] = value
231 os.environ[name] = value + os.pathsep + env
234 def __addToReservedTclTk(self, name, value):
238 value = os.path.expandvars(value) # expand environment variables
239 self.getLogger().debug("Add to %s: %s", name, value)
240 env = os.getenv(name, None)
241 #http://computer-programming-forum.com/57-tcl/1dfddc136afccb94.htm
242 #Tcl treats the contents of that variable as a list. Be happy, for you can now use drive letters on windows.
244 os.environ[name] = value
246 os.environ[name] = value + " " + env #explicitely whitespace
249 def _runAppli(self, args=[]):
250 # Initialize SALOME environment
251 sys.argv = ['runSalome'] + args
256 runSalome.runSalome()
259 def _runSession(self, args=[]):
260 sys.argv = ['runSession'] + args
262 runSession.configureSession(args)
267 scriptArgs = getScriptsAndArgs(args)
268 command = formatScriptsAndArgs(scriptArgs)
270 proc = subprocess.Popen(command, shell=True, close_fds=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
271 return proc.communicate()
273 absoluteAppliPath = os.getenv('ABSOLUTE_APPLI_PATH','')
274 cmd = ["/bin/bash", "--rcfile", absoluteAppliPath + "/.bashrc" ]
275 proc = subprocess.Popen(cmd, shell=False, close_fds=True)
279 def _runConsole(self, args=[]):
280 # Initialize SALOME environment
281 sys.argv = ['runConsole'] + args
289 def _killAll(self, args=[]):
290 from killSalome import killAllPorts
294 def _showInfo(self, args=[]):
295 print "Running with python", platform.python_version()
296 self._runAppli(["--version"])
299 def _usage(self, unused=[]):
303 def _makeCoffee(self, args=[]):
306 print " ___...(-------)-....___"
307 print " .-\"\" ) ( \"\"-."
308 print " .-\'``\'|-._ ) _.-|"
309 print " / .--.| `\"\"---...........---\"\"` |"
317 print " _..---\"\"` \\ /`\"\"---.._"
318 print " .-\' \\ / \'-."
319 print " : `-.__ __.-\' :"
320 print " : ) \"\"---...---\"\" ( :"
321 print " \'._ `\"--...___...--\"` _.\'"
322 print " \\\"\"--..__ __..--\"\"/"
323 print " \'._ \"\"\"----.....______.....----\"\"\" _.\'"
324 print " `\"\"--..,,_____ _____,,..--\"\"`"
325 print " `\"\"\"----\"\"\"`"
329 # Add the following two methods since logger is not pickable
330 # Ref: http://stackoverflow.com/questions/2999638/how-to-stop-attributes-from-being-pickled-in-python
331 def __getstate__(self):
332 d = dict(self.__dict__)
333 if hasattr(self, '_logger'):
337 def __setstate__(self, d):
338 self.__dict__.update(d) # I *think* this is a safe way to do it
340 # Excluding self._logger from pickle operation imply using the following method to access logger
342 if not hasattr(self, '_logger'):
343 self._logger = logging.getLogger(__name__)
344 #self._logger.setLevel(logging.DEBUG)
345 self._logger.setLevel(logging.ERROR)
351 if __name__ == "__main__":
352 if len(sys.argv) == 3:
353 runner = pickle.loads(sys.argv[1])
354 args = pickle.loads(sys.argv[2])
355 (out, err) = runner._getStarted(args)
357 sys.stdout.write(out)
359 sys.stderr.write(err)