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 reserved=['PATH', 'LD_LIBRARY_PATH', 'PYTHONPATH', 'MANPATH', 'PV_PLUGIN_PATH']
62 for filename in configFileNames:
63 basename, extension = os.path.splitext(filename)
64 if extension == ".cfg":
65 self.__setEnvironmentFromConfigFile(filename, reserved)
66 elif extension == ".sh":
67 #new convert procedures, temporary could be use not to be automatically deleted
68 #temp = tempfile.NamedTemporaryFile(suffix='.cfg', delete=False)
69 temp = tempfile.NamedTemporaryFile(suffix='.cfg')
71 convertEnvFileToConfigFile(filename, temp.name, reserved)
72 self.__setEnvironmentFromConfigFile(temp.name, reserved)
73 except ConfigParser.ParsingError, e:
74 self.getLogger().warning("Invalid token found when parsing file: %s\n"%(filename))
78 # Automatically cleans up the file
81 self.getLogger().warning("Unrecognized extension for configuration file: %s", filename)
85 # Run this module as a script, in order to use appropriate Python interpreter
86 # according to current path (initialized from environment files).
87 absoluteAppliPath = os.getenv('ABSOLUTE_APPLI_PATH','')
88 proc = subprocess.Popen(['python', os.path.join(absoluteAppliPath,"bin","salome","salomeRunner.py"), pickle.dumps(self), pickle.dumps(args)], shell=False, close_fds=True)
92 """Append value to PATH environment variable"""
93 def addToPath(self, value):
94 self.addToEnviron('PATH', value)
97 """Append value to LD_LIBRARY_PATH environment variable"""
98 def addToLdLibraryPath(self, value):
99 self.addToEnviron('LD_LIBRARY_PATH', value)
102 """Append value to PYTHONPATH environment variable"""
103 def addToPythonPath(self, value):
104 self.addToEnviron('PYTHONPATH', value)
107 """Set environment variable to value"""
108 def setEnviron(self, name, value, overwrite=False):
109 env = os.getenv(name, '')
110 if env and not overwrite:
111 self.getLogger().warning("Environment variable already existing (and not overwritten): %s=%s", name, value)
115 self.getLogger().warning("Overwriting environment variable: %s=%s", name, value)
117 value = os.path.expandvars(value) # expand environment variables
118 self.getLogger().debug("Set environment variable: %s=%s", name, value)
119 os.environ[name] = value
122 """Unset environment variable"""
123 def unsetEnviron(self, name):
124 if os.environ.has_key(name):
128 """Append value to environment variable"""
129 def addToEnviron(self, name, value, separator=os.pathsep):
133 value = os.path.expandvars(value) # expand environment variables
134 self.getLogger().debug("Add to %s: %s", name, value)
135 env = os.getenv(name, None)
137 os.environ[name] = value
139 os.environ[name] = value + separator + env
142 ###################################
143 # This begins the private section #
144 ###################################
146 def __parseArguments(self, args):
147 if len(args) == 0 or args[0].startswith("-"):
153 availableCommands = {
154 'start' : '_runAppli',
155 'shell' : '_runSession',
156 'connect' : '_runConsole',
157 'killall': '_killAll',
160 'coffee' : '_makeCoffee'
163 if not command in availableCommands.keys():
167 return availableCommands[command], options
172 Args consist in a mandatory command followed by optionnal parameters.
173 See usage for details on commands.
175 def _getStarted(self, args):
176 command, options = self.__parseArguments(args)
180 if args and args[0] in ["-h","--help","help"]:
183 # try to default to "start" command
184 command = "_runAppli"
187 res = getattr(self, command)(options) # run appropriate method
188 return res or (None, None)
189 except SystemExit, exc:
191 sys.exit(0) #catch sys.exit(0) happy end no warning
193 self.getLogger().warning("SystemExit 1 in method %s.", command)
195 except StandardError:
196 self.getLogger().error("Unexpected error:")
198 traceback.print_exc()
200 except SalomeRunnerException, e:
201 self.getLogger().error(e)
205 def __setEnvironmentFromConfigFile(self, filename, reserved=[]):
206 unsetVars, configVars, reservedDict = parseConfigFile(filename, reserved)
209 for var in unsetVars:
210 self.unsetEnviron(var)
213 for reserved in reservedDict:
214 a = filter(None, reservedDict[reserved]) # remove empty elements
215 reformattedVals = ':'.join(a)
216 self.addToEnviron(reserved, reformattedVals)
219 for key,val in configVars:
220 self.setEnviron(key, val, overwrite=True)
223 sys.path[:0] = os.getenv('PYTHONPATH','').split(':')
226 def _runAppli(self, args=[]):
227 # Initialize SALOME environment
228 sys.argv = ['runSalome'] + args
233 runSalome.runSalome()
236 def _runSession(self, args=[]):
237 sys.argv = ['runSession'] + args
239 runSession.configureSession(args)
244 scriptArgs = getScriptsAndArgs(args)
245 command = formatScriptsAndArgs(scriptArgs)
247 command = command.split(' ')
248 proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
249 return proc.communicate()
251 absoluteAppliPath = os.getenv('ABSOLUTE_APPLI_PATH','')
252 cmd = ["/bin/bash", "--rcfile", absoluteAppliPath + "/.bashrc" ]
253 proc = subprocess.Popen(cmd, shell=False, close_fds=True)
257 def _runConsole(self, args=[]):
258 # Initialize SALOME environment
259 sys.argv = ['runConsole'] + args
267 def _killAll(self, args=[]):
268 absoluteAppliPath = os.getenv('ABSOLUTE_APPLI_PATH','')
270 import PortManager # mandatory
271 from multiprocessing import Process
272 from killSalomeWithPort import killMyPort
273 ports = PortManager.getBusyPorts()
278 with tempfile.NamedTemporaryFile():
279 p = Process(target = killMyPort, args=(port,))
283 p = Process(target = killMyPort, args=(2809,))
287 from killSalome import killAllPorts
293 def _showInfo(self, args=[]):
294 print "Running with python", platform.python_version()
295 self._runAppli(["--version"])
298 def _usage(self, unused=[]):
302 def _makeCoffee(self, args=[]):
305 print " ___...(-------)-....___"
306 print " .-\"\" ) ( \"\"-."
307 print " .-\'``\'|-._ ) _.-|"
308 print " / .--.| `\"\"---...........---\"\"` |"
316 print " _..---\"\"` \\ /`\"\"---.._"
317 print " .-\' \\ / \'-."
318 print " : `-.__ __.-\' :"
319 print " : ) \"\"---...---\"\" ( :"
320 print " \'._ `\"--...___...--\"` _.\'"
321 print " \\\"\"--..__ __..--\"\"/"
322 print " \'._ \"\"\"----.....______.....----\"\"\" _.\'"
323 print " `\"\"--..,,_____ _____,,..--\"\"`"
324 print " `\"\"\"----\"\"\"`"
328 # Add the following two methods since logger is not pickable
329 # Ref: http://stackoverflow.com/questions/2999638/how-to-stop-attributes-from-being-pickled-in-python
330 def __getstate__(self):
331 d = dict(self.__dict__)
332 if hasattr(self, '_logger'):
336 def __setstate__(self, d):
337 self.__dict__.update(d) # I *think* this is a safe way to do it
339 # Excluding self._logger from pickle operation imply using the following method to access logger
341 if not hasattr(self, '_logger'):
342 self._logger = logging.getLogger(__name__)
343 #self._logger.setLevel(logging.DEBUG)
344 self._logger.setLevel(logging.ERROR)
350 if __name__ == "__main__":
351 if len(sys.argv) == 3:
352 runner = pickle.loads(sys.argv[1])
353 args = pickle.loads(sys.argv[2])
354 (out, err) = runner._getStarted(args)
356 sys.stdout.write(out)
358 sys.stderr.write(err)