6 from parseConfigFile import parseConfigFile
\r
7 from parseConfigFile import convertEnvFileToConfigFile
\r
14 from salomeLauncherUtils import SalomeRunnerException
\r
15 from salomeLauncherUtils import getScriptsAndArgs, formatScriptsAndArgs
\r
18 #exeName = os.path.splitext(os.path.basename(__file__))[0]
\r
21 Usage: salome [command] [options] [--config=file1,...,filen]
\r
24 start Launches SALOME virtual application [DEFAULT]
\r
25 shell Executes a script under SALOME application environment
\r
26 connect Connects a Python console to the active SALOME session
\r
27 killall Kill all SALOME running sessions
\r
28 info Display some information about SALOME
\r
29 help Show this message
\r
30 coffee Yes! SALOME can also make coffee!!"
\r
32 Use salome start --help or salome shell --help
\r
33 to show help on start and shell commands.
\r
40 The SalomeRunner class in an API to configure SALOME environment then
\r
41 start SALOME using a single python command.
\r
46 Initialize environment from a list of configuration files
\r
47 identified by their names.
\r
48 These files should be in appropriate (new .cfg) format.
\r
49 However you can give old .sh environment files; in this case,
\r
50 the SalomeRunner class will try to automatically convert them
\r
51 to .cfg format before setting the environment.
\r
53 def __init__(self, configFileNames=[]):
\r
54 #it could be None explicitely (if user use multiples setEnviron...for standalone)
\r
55 if configFileNames==None:
\r
58 if len(configFileNames) == 0:
\r
59 raise SalomeRunnerException("No configuration files given")
\r
61 reserved=['PATH', 'LD_LIBRARY_PATH', 'PYTHONPATH', 'MANPATH', 'PV_PLUGIN_PATH']
\r
62 for filename in configFileNames:
\r
63 basename, extension = os.path.splitext(filename)
\r
64 if extension == ".cfg":
\r
65 self.__setEnvironmentFromConfigFile(filename, reserved)
\r
66 elif extension == ".sh":
\r
67 #new convert procedures, temporary could be use not to be automatically deleted
\r
68 #temp = tempfile.NamedTemporaryFile(suffix='.cfg', delete=False)
\r
69 temp = tempfile.NamedTemporaryFile(suffix='.cfg')
\r
71 convertEnvFileToConfigFile(filename, temp.name, reserved)
\r
72 self.__setEnvironmentFromConfigFile(temp.name, reserved)
\r
73 except ConfigParser.ParsingError, e:
\r
74 self.getLogger().warning("Invalid token found when parsing file: %s\n"%(filename))
\r
78 # Automatically cleans up the file
\r
81 self.getLogger().warning("Unrecognized extension for configuration file: %s", filename)
\r
85 # Run this module as a script, in order to use appropriate Python interpreter
\r
86 # according to current path (initialized from environment files).
\r
87 absoluteAppliPath = os.getenv('ABSOLUTE_APPLI_PATH','')
\r
88 proc = subprocess.Popen(['python', os.path.join(absoluteAppliPath,"bin","salome","salomeRunner.py"), pickle.dumps(self), pickle.dumps(args)], shell=False, close_fds=True)
\r
92 """Append value to PATH environment variable"""
\r
93 def addToPath(self, value):
\r
94 self.addToEnviron('PATH', value)
\r
97 """Append value to LD_LIBRARY_PATH environment variable"""
\r
98 def addToLdLibraryPath(self, value):
\r
99 self.addToEnviron('LD_LIBRARY_PATH', value)
\r
102 """Append value to PYTHONPATH environment variable"""
\r
103 def addToPythonPath(self, value):
\r
104 self.addToEnviron('PYTHONPATH', value)
\r
107 """Set environment variable to value"""
\r
108 def setEnviron(self, name, value, overwrite=False):
\r
109 env = os.getenv(name, '')
\r
110 if env and not overwrite:
\r
111 self.getLogger().warning("Environment variable already existing (and not overwritten): %s=%s", name, value)
\r
115 self.getLogger().warning("Overwriting environment variable: %s=%s", name, value)
\r
117 value = os.path.expandvars(value) # expand environment variables
\r
118 self.getLogger().debug("Set environment variable: %s=%s", name, value)
\r
119 os.environ[name] = value
\r
122 """Unset environment variable"""
\r
123 def unsetEnviron(self, name):
\r
124 if os.environ.has_key(name):
\r
125 del os.environ[name]
\r
128 """Append value to environment variable"""
\r
129 def addToEnviron(self, name, value, separator=os.pathsep):
\r
133 value = os.path.expandvars(value) # expand environment variables
\r
134 self.getLogger().debug("Add to %s: %s", name, value)
\r
135 env = os.getenv(name, None)
\r
137 os.environ[name] = value
\r
139 os.environ[name] = value + separator + env
\r
142 ###################################
\r
143 # This begins the private section #
\r
144 ###################################
\r
146 def __parseArguments(self, args):
\r
147 if len(args) == 0 or args[0].startswith("-"):
\r
153 availableCommands = {
\r
154 'start' : '_runAppli',
\r
155 'shell' : '_runSession',
\r
156 'connect' : '_runConsole',
\r
157 'killall': '_killAll',
\r
158 'info': '_showInfo',
\r
160 'coffee' : '_makeCoffee'
\r
163 if not command in availableCommands.keys():
\r
167 return availableCommands[command], options
\r
172 Args consist in a mandatory command followed by optionnal parameters.
\r
173 See usage for details on commands.
\r
175 def _getStarted(self, args):
\r
176 command, options = self.__parseArguments(args)
\r
179 if command is None:
\r
180 if args and args[0] in ["-h","--help","help"]:
\r
183 # try to default to "start" command
\r
184 command = "_runAppli"
\r
187 res = getattr(self, command)(options) # run appropriate method
\r
188 return res or (None, None)
\r
189 except SystemExit, exc:
\r
191 sys.exit(0) #catch sys.exit(0) happy end no warning
\r
193 self.getLogger().warning("SystemExit 1 in method %s.", command)
\r
195 except StandardError:
\r
196 self.getLogger().error("Unexpected error:")
\r
198 traceback.print_exc()
\r
200 except SalomeRunnerException, e:
\r
201 self.getLogger().error(e)
\r
205 def __setEnvironmentFromConfigFile(self, filename, reserved=[]):
\r
206 unsetVars, configVars, reservedDict = parseConfigFile(filename, reserved)
\r
209 for var in unsetVars:
\r
210 self.unsetEnviron(var)
\r
213 for reserved in reservedDict:
\r
214 a = filter(None, reservedDict[reserved]) # remove empty elements
\r
215 reformattedVals = ':'.join(a)
\r
216 self.addToEnviron(reserved, reformattedVals)
\r
219 for key,val in configVars:
\r
220 self.setEnviron(key, val, overwrite=True)
\r
223 sys.path[:0] = os.getenv('PYTHONPATH','').split(':')
\r
226 def _runAppli(self, args=[]):
\r
227 # Initialize SALOME environment
\r
228 sys.argv = ['runSalome'] + args
\r
233 runSalome.runSalome()
\r
236 def _runSession(self, args=[]):
\r
237 sys.argv = ['runSession'] + args
\r
239 runSession.configureSession(args)
\r
244 scriptArgs = getScriptsAndArgs(args)
\r
245 command = formatScriptsAndArgs(scriptArgs)
\r
247 proc = subprocess.Popen(command, shell=True, close_fds=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
\r
248 return proc.communicate()
\r
250 absoluteAppliPath = os.getenv('ABSOLUTE_APPLI_PATH','')
\r
251 cmd = ["/bin/bash", "--rcfile", absoluteAppliPath + "/.bashrc" ]
\r
252 proc = subprocess.Popen(cmd, shell=False, close_fds=True)
\r
256 def _runConsole(self, args=[]):
\r
257 # Initialize SALOME environment
\r
258 sys.argv = ['runConsole'] + args
\r
263 runConsole.connect()
\r
266 def _killAll(self, args=[]):
\r
267 from killSalome import killAllPorts
\r
271 def _showInfo(self, args=[]):
\r
272 print "Running with python", platform.python_version()
\r
273 self._runAppli(["--version"])
\r
276 def _usage(self, unused=[]):
\r
280 def _makeCoffee(self, args=[]):
\r
283 print " ___...(-------)-....___"
\r
284 print " .-\"\" ) ( \"\"-."
\r
285 print " .-\'``\'|-._ ) _.-|"
\r
286 print " / .--.| `\"\"---...........---\"\"` |"
\r
290 print " `\\ `\\ | |"
\r
294 print " _..---\"\"` \\ /`\"\"---.._"
\r
295 print " .-\' \\ / \'-."
\r
296 print " : `-.__ __.-\' :"
\r
297 print " : ) \"\"---...---\"\" ( :"
\r
298 print " \'._ `\"--...___...--\"` _.\'"
\r
299 print " \\\"\"--..__ __..--\"\"/"
\r
300 print " \'._ \"\"\"----.....______.....----\"\"\" _.\'"
\r
301 print " `\"\"--..,,_____ _____,,..--\"\"`"
\r
302 print " `\"\"\"----\"\"\"`"
\r
306 # Add the following two methods since logger is not pickable
\r
307 # Ref: http://stackoverflow.com/questions/2999638/how-to-stop-attributes-from-being-pickled-in-python
\r
308 def __getstate__(self):
\r
309 d = dict(self.__dict__)
\r
310 if hasattr(self, '_logger'):
\r
314 def __setstate__(self, d):
\r
315 self.__dict__.update(d) # I *think* this is a safe way to do it
\r
317 # Excluding self._logger from pickle operation imply using the following method to access logger
\r
318 def getLogger(self):
\r
319 if not hasattr(self, '_logger'):
\r
320 self._logger = logging.getLogger(__name__)
\r
321 #self._logger.setLevel(logging.DEBUG)
\r
322 self._logger.setLevel(logging.ERROR)
\r
323 return self._logger;
\r
328 if __name__ == "__main__":
\r
329 if len(sys.argv) == 3:
\r
330 runner = pickle.loads(sys.argv[1])
\r
331 args = pickle.loads(sys.argv[2])
\r
332 (out, err) = runner._getStarted(args)
\r
334 sys.stdout.write(out)
\r
336 sys.stderr.write(err)
\r