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','')
271 ports = PortManager.getBusyPorts()
273 from multiprocessing import Process
274 from killSalomeWithPort import killMyPort
278 with tempfile.NamedTemporaryFile():
279 p = Process(target = killMyPort, args=(port,))
285 p = Process(target = killMyPort, args=(2809,))
291 def _showInfo(self, args=[]):
292 print "Running with python", platform.python_version()
293 self._runAppli(["--version"])
296 def _usage(self, unused=[]):
300 def _makeCoffee(self, args=[]):
303 print " ___...(-------)-....___"
304 print " .-\"\" ) ( \"\"-."
305 print " .-\'``\'|-._ ) _.-|"
306 print " / .--.| `\"\"---...........---\"\"` |"
314 print " _..---\"\"` \\ /`\"\"---.._"
315 print " .-\' \\ / \'-."
316 print " : `-.__ __.-\' :"
317 print " : ) \"\"---...---\"\" ( :"
318 print " \'._ `\"--...___...--\"` _.\'"
319 print " \\\"\"--..__ __..--\"\"/"
320 print " \'._ \"\"\"----.....______.....----\"\"\" _.\'"
321 print " `\"\"--..,,_____ _____,,..--\"\"`"
322 print " `\"\"\"----\"\"\"`"
326 # Add the following two methods since logger is not pickable
327 # Ref: http://stackoverflow.com/questions/2999638/how-to-stop-attributes-from-being-pickled-in-python
328 def __getstate__(self):
329 d = dict(self.__dict__)
330 if hasattr(self, '_logger'):
334 def __setstate__(self, d):
335 self.__dict__.update(d) # I *think* this is a safe way to do it
337 # Excluding self._logger from pickle operation imply using the following method to access logger
339 if not hasattr(self, '_logger'):
340 self._logger = logging.getLogger(__name__)
341 #self._logger.setLevel(logging.DEBUG)
342 self._logger.setLevel(logging.ERROR)
348 if __name__ == "__main__":
349 if len(sys.argv) == 3:
350 runner = pickle.loads(sys.argv[1])
351 args = pickle.loads(sys.argv[2])
352 (out, err) = runner._getStarted(args)
354 sys.stdout.write(out)
356 sys.stderr.write(err)