Salome HOME
Merge branch 'eap/23514'
[modules/kernel.git] / bin / salomeContext.py
index 7c034fd9b6530b20b8a7b8c27a4a13411438b66e..b67209092e82ac095f26d1542f5f7af2d06a5fed 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2013-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2013-2017  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -84,30 +84,30 @@ class SalomeContext:
   """
   def __init__(self, configFileNames=0):
     self.getLogger().setLevel(logging.INFO)
-    #it could be None explicitely (if user use multiples setVariable...for standalone)
+    #it could be None explicitly (if user use multiples setVariable...for standalone)
     if configFileNames is None:
        return
     configFileNames = configFileNames or []
     if len(configFileNames) == 0:
       raise SalomeContextException("No configuration files given")
 
-    reserved=['PATH', 'DYLD_FALLBACK_LIBRARY_PATH', 'DYLD_LIBRARY_PATH', 'LD_LIBRARY_PATH', 'PYTHONPATH', 'MANPATH', 'PV_PLUGIN_PATH', 'INCLUDE', 'LIBPATH', 'SALOME_PLUGINS_PATH']
+    reserved=['PATH', 'DYLD_FALLBACK_LIBRARY_PATH', 'DYLD_LIBRARY_PATH', 'LD_LIBRARY_PATH', 'PYTHONPATH', 'MANPATH', 'PV_PLUGIN_PATH', 'INCLUDE', 'LIBPATH', 'SALOME_PLUGINS_PATH', 'LIBRARY_PATH', 'QT_PLUGIN_PATH']
     for filename in configFileNames:
       basename, extension = os.path.splitext(filename)
       if extension == ".cfg":
         self.__setContextFromConfigFile(filename, reserved)
       else:
-        self.getLogger().warning("Unrecognized extension for configuration file: %s", filename)
+        self.getLogger().error("Unrecognized extension for configuration file: %s", filename)
   #
 
-  def __loadMPI(self, module_name):
-    print "Trying to load MPI module: %s..."%module_name,
+  def __loadEnvModules(self, env_modules):
+    print("Trying to load env modules: %s..." % ' '.join(env_modules))
     try:
-      out, err = subprocess.Popen(["modulecmd", "python", "load", module_name], stdout=subprocess.PIPE).communicate()
-      exec out # define specific environment variables
-      print " OK"
+      out, err = subprocess.Popen(["modulecmd", "python", "load"] + env_modules, stdout=subprocess.PIPE).communicate()
+      exec(out) # define specific environment variables
+      print("OK")
     except:
-      print " ** Failed **"
+      print("** Failed **")
       pass
   #
 
@@ -115,16 +115,16 @@ class SalomeContext:
     import os
     # Run this module as a script, in order to use appropriate Python interpreter
     # according to current path (initialized from context files).
-    mpi_module_option = "--with-mpi-module="
-    mpi_module = [x for x in args if x.startswith(mpi_module_option)]
-    if mpi_module:
-      mpi_module = mpi_module[0][len(mpi_module_option):]
-      self.__loadMPI(mpi_module)
-      args = [x for x in args if not x.startswith(mpi_module_option)]
+    env_modules_option = "--with-env-modules="
+    env_modules_l = [x for x in args if x.startswith(env_modules_option)]
+    if env_modules_l:
+      env_modules = env_modules_l[-1][len(env_modules_option):].split(',')
+      self.__loadEnvModules(env_modules)
+      args = [x for x in args if not x.startswith(env_modules_option)]
     else:
-      mpi_module = os.getenv("SALOME_MPI_MODULE_NAME", None)
-      if mpi_module:
-        self.__loadMPI(mpi_module)
+      env_modules = os.getenv("SALOME_ENV_MODULES", None)
+      if env_modules:
+        self.__loadEnvModules(env_modules.split(','))
 
     absoluteAppliPath = os.getenv('ABSOLUTE_APPLI_PATH','')
     env_copy = os.environ.copy()
@@ -165,11 +165,11 @@ class SalomeContext:
   def setVariable(self, name, value, overwrite=False):
     env = os.getenv(name, '')
     if env and not overwrite:
-      self.getLogger().warning("Environment variable already existing (and not overwritten): %s=%s", name, value)
+      self.getLogger().error("Environment variable already existing (and not overwritten): %s=%s", name, value)
       return
 
     if env:
-      self.getLogger().warning("Overwriting environment variable: %s=%s", name, value)
+      self.getLogger().debug("Overwriting environment variable: %s=%s", name, value)
 
     value = os.path.expandvars(value) # expand environment variables
     self.getLogger().debug("Set environment variable: %s=%s", name, value)
@@ -231,7 +231,7 @@ class SalomeContext:
 
   """
   Run SALOME!
-  Args consist in a mandatory command followed by optionnal parameters.
+  Args consist in a mandatory command followed by optional parameters.
   See usage for details on commands.
   """
   def _startSalome(self, args):
@@ -254,25 +254,25 @@ class SalomeContext:
     if command is None:
       if args and args[0] in ["-h","--help","help"]:
         usage()
-        sys.exit(0)
+        return 0
       # try to default to "start" command
       command = "_runAppli"
 
     try:
       res = getattr(self, command)(options) # run appropriate method
-      return res or (None, None)
-    except SystemExit, returncode:
-      if returncode != 0:
-        self.getLogger().warning("SystemExit %s in method %s.", returncode, command)
-      sys.exit(returncode)
+      return res or 0
+    except SystemExit as ex:
+      if ex.code != 0:
+        self.getLogger().error("SystemExit %s in method %s.", ex.code, command)
+      return ex.code
     except StandardError:
       self.getLogger().error("Unexpected error:")
       import traceback
       traceback.print_exc()
-      sys.exit(1)
+      return 1
     except SalomeContextException, e:
       self.getLogger().error(e)
-      sys.exit(1)
+      return 1
   #
 
   def __setContextFromConfigFile(self, filename, reserved=None):
@@ -283,7 +283,7 @@ class SalomeContext:
     except SalomeContextException, e:
       msg = "%s"%e
       self.getLogger().error(msg)
-      sys.exit(1)
+      return 1
 
     # unset variables
     for var in unsetVars:
@@ -319,6 +319,7 @@ class SalomeContext:
 
     import runSalome
     runSalome.runSalome()
+    return 0
   #
 
   def _setContext(self, args=None):
@@ -328,7 +329,7 @@ class SalomeContext:
       print "*** SALOME context has already been set."
       print "*** Enter 'exit' (only once!) to leave SALOME context."
       print "***"
-      return
+      return 0
 
     os.environ["SALOME_CONTEXT_SET"] = "yes"
     print "***"
@@ -338,7 +339,8 @@ class SalomeContext:
 
     cmd = ["/bin/bash"]
     proc = subprocess.Popen(cmd, shell=False, close_fds=True)
-    return proc.communicate()
+    proc.communicate()
+    return proc.returncode
   #
 
   def _runSession(self, args=None):
@@ -373,7 +375,7 @@ class SalomeContext:
     ports = args
     if not ports:
       print "Port number(s) not provided to command: salome kill <port(s)>"
-      return
+      return 1
 
     from multiprocessing import Process
     from killSalomeWithPort import killMyPort
@@ -383,7 +385,7 @@ class SalomeContext:
         p = Process(target = killMyPort, args=(port,))
         p.start()
         p.join()
-    pass
+    return 0
   #
 
   def _killAll(self, unused=None):
@@ -391,7 +393,7 @@ class SalomeContext:
       import PortManager # mandatory
       from multiprocessing import Process
       from killSalomeWithPort import killMyPort
-      ports = PortManager.getBusyPorts()
+      ports = PortManager.getBusyPorts()['this']
 
       if ports:
         import tempfile
@@ -405,6 +407,7 @@ class SalomeContext:
       from killSalome import killAllPorts
       killAllPorts()
       pass
+    return 0
   #
 
   def _runTests(self, args=None):
@@ -440,7 +443,9 @@ class SalomeContext:
         if versions.has_key(soft.upper()):
           print soft.upper().rjust(max_len), versions[soft.upper()]
     else:
-      for name, version in versions.items():
+      import collections
+      od = collections.OrderedDict(sorted(versions.items()))
+      for name, version in od.iteritems():
         print name.rjust(max_len), versions[name]
     pass
 
@@ -464,14 +469,25 @@ Available options are:
 
     if "-h" in args or "--help" in args:
       print usage + epilog
-      return
+      return 0
 
     if "-p" in args or "--ports" in args:
       import PortManager
       ports = PortManager.getBusyPorts()
-      print "SALOME instances are running on ports:", ports
-      if ports:
-        print "Last started instance on port %s"%ports[-1]
+      this_ports = ports['this']
+      other_ports = ports['other']
+      if this_ports or other_ports:
+          print "SALOME instances are running on the following ports:"
+          if this_ports:
+              print "   This application:", this_ports
+          else:
+              print "   No SALOME instances of this application"
+          if other_ports:
+              print "   Other applications:", other_ports
+          else:
+              print "   No SALOME instances of other applications"
+      else:
+          print "No SALOME instances are running"
 
     if "-s" in args or "--softwares" in args:
       if "-s" in args:
@@ -485,7 +501,9 @@ Available options are:
 
     if "-v" in args or "--version" in args:
       print "Running with python", platform.python_version()
-      self._runAppli(["--version"])
+      return self._runAppli(["--version"])
+
+    return 0
   #
 
   def _showDoc(self, args=None):
@@ -495,7 +513,7 @@ Available options are:
     modules = args
     if not modules:
       print "Module(s) not provided to command: salome doc <module(s)>"
-      return
+      return 1
 
     appliPath = os.getenv("ABSOLUTE_APPLI_PATH")
     if not appliPath:
@@ -542,7 +560,6 @@ Available options are:
     print ""
     print "                    SALOME is working for you; what else?"
     print ""
-    sys.exit(0)
   #
 
   def _getCar(self, unused=None):
@@ -576,7 +593,6 @@ Available options are:
     print ""
     print "                                Drive your simulation properly with SALOME!"
     print ""
-    sys.exit(0)
   #
 
   # Add the following two methods since logger is not pickable
@@ -605,11 +621,8 @@ if __name__ == "__main__":
     context = pickle.loads(sys.argv[1])
     args = pickle.loads(sys.argv[2])
 
-    (out, err) = context._startSalome(args)
-    if out:
-      sys.stdout.write(out)
-    if err:
-      sys.stderr.write(err)
+    status = context._startSalome(args)
+    sys.exit(status)
   else:
     usage()
 #