Salome HOME
#17978 [CEA] SALOME windows minor corrections : fix for problem 1 of 5
[modules/yacs.git] / bin / salomeContext.py
old mode 100644 (file)
new mode 100755 (executable)
index 0d12eca..36961f8
@@ -1,4 +1,5 @@
-# Copyright (C) 2013-2017  CEA/DEN, EDF R&D, OPEN CASCADE
+#! /usr/bin/env python3
+# Copyright (C) 2013-2019  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
@@ -27,7 +28,7 @@ from parseConfigFile import parseConfigFile
 import tempfile
 import pickle
 import subprocess
-import platform
+import sys
 
 from salomeContextUtils import SalomeContextException
 
@@ -44,6 +45,7 @@ Commands:
                     User works in a Shell terminal. SALOME environment is set but
                     application is not started.
     connect         Connect a Python console to the active SALOME instance.
+    remote          run command in SALOME environment from remote call, ssh or rsh.
     kill <port(s)>  Terminate SALOME instances running on given ports for current user.
                     Port numbers must be separated by blank characters.
     killall         Terminate *all* SALOME running instances for current user.
@@ -64,7 +66,7 @@ Command options:
 --config=<file,folder,...>
 ==========================
     Initialize SALOME context from a list of context files and/or a list
-    of folders containing context files. The list is comma-separated, whithout
+    of folders containing context files. The list is comma-separated, without
     any blank characters.
 '''
 
@@ -84,7 +86,7 @@ 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 []
@@ -100,14 +102,16 @@ class SalomeContext:
         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):
+    modulecmd = os.getenv('LMOD_CMD')
+    if not modulecmd:
+      raise SalomeContextException("Module environment not present")
+      return
     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
     except:
-      print(" ** Failed **")
+      raise SalomeContextException("Failed to load env modules: %s ..." % ' '.join(env_modules))
       pass
   #
 
@@ -115,22 +119,22 @@ 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()
-    selfBytes= pickle.dumps(self,protocol=0)
-    argsBytes= pickle.dumps(args,protocol=0)
-    proc = subprocess.Popen(['python', os.path.join(absoluteAppliPath,"bin","salome","salomeContext.py"), selfBytes.decode(), argsBytes.decode()], shell=False, close_fds=True, env=env_copy)
+    selfBytes= pickle.dumps(self, protocol=0)
+    argsBytes= pickle.dumps(args, protocol=0)
+    proc = subprocess.Popen(['python3', os.path.join(absoluteAppliPath,"bin","salome","salomeContext.py"), selfBytes.decode(), argsBytes.decode()], shell=False, close_fds=True, env=env_copy)
     out, err = proc.communicate()
     return out, err, proc.returncode
   #
@@ -142,9 +146,9 @@ class SalomeContext:
 
   """Append value to LD_LIBRARY_PATH environment variable"""
   def addToLdLibraryPath(self, value):
-    if platform.system() == 'Windows':
+    if sys.platform == 'win32':
       self.addToVariable('PATH', value)
-    elif platform.system() == 'Darwin':
+    elif  sys.platform == 'darwin':
       if "LAPACK" in value:
         self.addToVariable('DYLD_FALLBACK_LIBRARY_PATH', value)
       else:
@@ -213,6 +217,7 @@ class SalomeContext:
       'start'   : '_runAppli',
       'context' : '_setContext',
       'shell'   : '_runSession',
+      'remote'  : '_runRemote',
       'connect' : '_runConsole',
       'kill'    : '_kill',
       'killall' : '_killAll',
@@ -233,7 +238,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):
@@ -263,18 +268,18 @@ class SalomeContext:
     try:
       res = getattr(self, command)(options) # run appropriate method
       return res or 0
-    except SystemExit as returncode:
-      if returncode != 0:
-        self.getLogger().error("SystemExit %s in method %s.", returncode, command)
-      return returncode
+    except SystemExit as ex:
+      if ex.code != 0:
+        self.getLogger().error("SystemExit %s in method %s.", ex.code, command)
+      return ex.code
+    except SalomeContextException as e:
+      self.getLogger().error(e)
+      return 1
     except Exception:
       self.getLogger().error("Unexpected error:")
       import traceback
       traceback.print_exc()
       return 1
-    except SalomeContextException as e:
-      self.getLogger().error(e)
-      return 1
   #
 
   def __setContextFromConfigFile(self, filename, reserved=None):
@@ -339,10 +344,13 @@ class SalomeContext:
     print("*** Enter 'exit' (only once!) to leave SALOME context.")
     print("***")
 
-    cmd = ["/bin/bash"]
+    if sys.platform == 'win32':
+      cmd = ['cmd.exe']
+    else:
+      cmd = ["/bin/bash"]
     proc = subprocess.Popen(cmd, shell=False, close_fds=True)
     proc.communicate()
-    return proc.returncode()
+    return proc.returncode
   #
 
   def _runSession(self, args=None):
@@ -359,6 +367,18 @@ class SalomeContext:
     return runSession.runSession(params, args)
   #
 
+  def _runRemote(self, args=None):
+    if args is None:
+      args = []
+#   complete salome environment 
+    sys.argv = ['runRemote']
+    import setenv
+    setenv.main(True)
+
+    import runRemote
+    return runRemote.runRemote(args)
+  #
+
   def _runConsole(self, args=None):
     if args is None:
       args = []
@@ -379,31 +399,34 @@ class SalomeContext:
       print("Port number(s) not provided to command: salome kill <port(s)>")
       return 1
 
-    from multiprocessing import Process
-    from killSalomeWithPort import killMyPort
-    import tempfile
+    import subprocess
+    sys.argv = ['kill']
+    import setenv
+    setenv.main(True)
+    if os.getenv("NSHOST") == "no_host":
+      os.unsetenv("NSHOST")
     for port in ports:
-      with tempfile.NamedTemporaryFile():
-        p = Process(target = killMyPort, args=(port,))
-        p.start()
-        p.join()
+      proc = subprocess.Popen(["killSalomeWithPort.py", port])
+      proc.communicate()
+
     return 0
   #
 
   def _killAll(self, unused=None):
+    sys.argv = ['killAll']
+    import setenv
+    setenv.main(True)
+    if os.getenv("NSHOST") == "no_host":
+      os.unsetenv("NSHOST")
     try:
       import PortManager # mandatory
-      from multiprocessing import Process
-      from killSalomeWithPort import killMyPort
+      import subprocess
       ports = PortManager.getBusyPorts()['this']
 
       if ports:
-        import tempfile
         for port in ports:
-          with tempfile.NamedTemporaryFile():
-            p = Process(target = killMyPort, args=(port,))
-            p.start()
-            p.join()
+          proc = subprocess.Popen(["killSalomeWithPort.py", str(port)])
+          proc.communicate()
     except ImportError:
       # :TODO: should be declared obsolete
       from killSalome import killAllPorts
@@ -442,12 +465,12 @@ class SalomeContext:
       pass
     if softwares:
       for soft in softwares:
-        if versions.has_key(soft.upper()):
+        if soft.upper() in versions:
           print(soft.upper().rjust(max_len), versions[soft.upper()])
     else:
       import collections
       od = collections.OrderedDict(sorted(versions.items()))
-      for name, version in od.iteritems():
+      for name, version in od.items():
         print(name.rjust(max_len), versions[name])
     pass