Salome HOME
Add 'SALOME DEFAULT VALUES' section to the configuration file.
[modules/yacs.git] / bin / salomeContext.py
old mode 100644 (file)
new mode 100755 (executable)
index 91fe2a8..99fcd11
@@ -1,4 +1,5 @@
-# Copyright (C) 2013-2017  CEA/DEN, EDF R&D, OPEN CASCADE
+#! /usr/bin/env python3
+# Copyright (C) 2013-2020  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
 import os
 import sys
 import logging
-import ConfigParser
+import configparser
 
 from parseConfigFile import parseConfigFile
 
 import tempfile
 import pickle
 import subprocess
+import sys
 import platform
 
 from salomeContextUtils import SalomeContextException
@@ -44,6 +46,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,11 +67,11 @@ 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.
 '''
 
-  print msg
+  print(msg)
 #
 
 """
@@ -84,14 +87,14 @@ 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', 'LIBRARY_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":
@@ -101,13 +104,15 @@ class SalomeContext:
   #
 
   def __loadEnvModules(self, env_modules):
-    print("Trying to load env modules: %s..." % ' '.join(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"] + env_modules, 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
   #
 
@@ -128,7 +133,9 @@ class SalomeContext:
 
     absoluteAppliPath = os.getenv('ABSOLUTE_APPLI_PATH','')
     env_copy = os.environ.copy()
-    proc = subprocess.Popen(['python', os.path.join(absoluteAppliPath,"bin","salome","salomeContext.py"), pickle.dumps(self), pickle.dumps(args)], 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('latin1'), argsBytes.decode('latin1')], shell=False, close_fds=True, env=env_copy)
     out, err = proc.communicate()
     return out, err, proc.returncode
   #
@@ -140,9 +147,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:
@@ -176,6 +183,14 @@ class SalomeContext:
     os.environ[name] = value
   #
 
+  def setDefaultValue(self, name, value):
+    """ Set environment variable only if it is undefined."""
+    env = os.getenv(name, '')
+    if not env:
+      value = os.path.expandvars(value) # expand environment variables
+      self.getLogger().debug("Set environment variable: %s=%s", name, value)
+      os.environ[name] = value
+
   """Unset environment variable"""
   def unsetVariable(self, name):
     if os.environ.has_key(name):
@@ -211,6 +226,7 @@ class SalomeContext:
       'start'   : '_runAppli',
       'context' : '_setContext',
       'shell'   : '_runSession',
+      'remote'  : '_runRemote',
       'connect' : '_runConsole',
       'kill'    : '_kill',
       'killall' : '_killAll',
@@ -222,7 +238,7 @@ class SalomeContext:
       'car'     : '_getCar',
       }
 
-    if not command in availableCommands.keys():
+    if command not in availableCommands:
       command = "start"
       options = args
 
@@ -231,7 +247,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):
@@ -260,27 +276,31 @@ class SalomeContext:
 
     try:
       res = getattr(self, command)(options) # run appropriate method
-      return res or (None, None)
-    except SystemExit, returncode:
-      if returncode != 0:
-        self.getLogger().error("SystemExit %s in method %s.", returncode, command)
-      return returncode
-    except StandardError:
+      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 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, e:
-      self.getLogger().error(e)
-      return 1
   #
 
   def __setContextFromConfigFile(self, filename, reserved=None):
     if reserved is None:
       reserved = []
     try:
-      unsetVars, configVars, reservedDict = parseConfigFile(filename, reserved)
-    except SalomeContextException, e:
+      configInfo = parseConfigFile(filename, reserved)
+      unsetVars = configInfo.unsetVariables
+      configVars = configInfo.outputVariables
+      reservedDict = configInfo.reservedValues
+      defaultValues = configInfo.defaultValues
+    except SalomeContextException as e:
       msg = "%s"%e
       self.getLogger().error(msg)
       return 1
@@ -291,7 +311,7 @@ class SalomeContext:
 
     # set context
     for reserved in reservedDict:
-      a = filter(None, reservedDict[reserved]) # remove empty elements
+      a = [_f for _f in reservedDict[reserved] if _f] # remove empty elements
       a = [ os.path.realpath(x) for x in a ]
       reformattedVals = os.pathsep.join(a)
       if reserved in ["INCLUDE", "LIBPATH"]:
@@ -304,6 +324,10 @@ class SalomeContext:
       self.setVariable(key, val, overwrite=True)
       pass
 
+    for key,val in defaultValues:
+      self.setDefaultValue(key, val)
+      pass
+
     pythonpath = os.getenv('PYTHONPATH','').split(os.pathsep)
     pythonpath = [ os.path.realpath(x) for x in pythonpath ]
     sys.path[:0] = pythonpath
@@ -319,26 +343,31 @@ class SalomeContext:
 
     import runSalome
     runSalome.runSalome()
+    return 0
   #
 
   def _setContext(self, args=None):
     salome_context_set = os.getenv("SALOME_CONTEXT_SET")
     if salome_context_set:
-      print "***"
-      print "*** SALOME context has already been set."
-      print "*** Enter 'exit' (only once!) to leave SALOME context."
-      print "***"
-      return
+      print("***")
+      print("*** SALOME context has already been set.")
+      print("*** Enter 'exit' (only once!) to leave SALOME context.")
+      print("***")
+      return 0
 
     os.environ["SALOME_CONTEXT_SET"] = "yes"
-    print "***"
-    print "*** SALOME context is now set."
-    print "*** Enter 'exit' (only once!) to leave SALOME context."
-    print "***"
+    print("***")
+    print("*** SALOME context is now set.")
+    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)
-    return proc.communicate()
+    proc.communicate()
+    return proc.returncode
   #
 
   def _runSession(self, args=None):
@@ -355,6 +384,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 = []
@@ -372,39 +413,43 @@ class SalomeContext:
       args = []
     ports = args
     if not ports:
-      print "Port number(s) not provided to command: salome kill <port(s)>"
-      return
+      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()
-    pass
+      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
       killAllPorts()
       pass
+    return 0
   #
 
   def _runTests(self, args=None):
@@ -419,7 +464,7 @@ class SalomeContext:
   #
 
   def _showSoftwareVersions(self, softwares=None):
-    config = ConfigParser.SafeConfigParser()
+    config = configparser.SafeConfigParser()
     absoluteAppliPath = os.getenv('ABSOLUTE_APPLI_PATH')
     filename = os.path.join(absoluteAppliPath, "sha1_collections.txt")
     versions = {}
@@ -437,13 +482,13 @@ class SalomeContext:
       pass
     if softwares:
       for soft in softwares:
-        if versions.has_key(soft.upper()):
-          print soft.upper().rjust(max_len), versions[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():
-        print name.rjust(max_len), versions[name]
+      for name, version in od.items():
+        print(name.rjust(max_len), versions[name])
     pass
 
   def _showInfo(self, args=None):
@@ -465,8 +510,8 @@ Available options are:
       args = ["--version"]
 
     if "-h" in args or "--help" in args:
-      print usage + epilog
-      return
+      print(usage + epilog)
+      return 0
 
     if "-p" in args or "--ports" in args:
       import PortManager
@@ -474,17 +519,17 @@ Available options are:
       this_ports = ports['this']
       other_ports = ports['other']
       if this_ports or other_ports:
-          print "SALOME instances are running on the following ports:"
+          print("SALOME instances are running on the following ports:")
           if this_ports:
-              print "   This application:", this_ports
+              print("   This application:", this_ports)
           else:
-              print "   No SALOME instances of this application"
+              print("   No SALOME instances of this application")
           if other_ports:
-              print "   Other applications:", other_ports
+              print("   Other applications:", other_ports)
           else:
-              print "   No SALOME instances of other applications"
+              print("   No SALOME instances of other applications")
       else:
-          print "No SALOME instances are running"
+          print("No SALOME instances are running")
 
     if "-s" in args or "--softwares" in args:
       if "-s" in args:
@@ -497,8 +542,10 @@ Available options are:
       self._showSoftwareVersions(softwares=args[index+1:indexEnd])
 
     if "-v" in args or "--version" in args:
-      print "Running with python", platform.python_version()
-      self._runAppli(["--version"])
+      print("Running with python", platform.python_version())
+      return self._runAppli(["--version"])
+
+    return 0
   #
 
   def _showDoc(self, args=None):
@@ -507,8 +554,8 @@ Available options are:
 
     modules = args
     if not modules:
-      print "Module(s) not provided to command: salome doc <module(s)>"
-      return
+      print("Module(s) not provided to command: salome doc <module(s)>")
+      return 1
 
     appliPath = os.getenv("ABSOLUTE_APPLI_PATH")
     if not appliPath:
@@ -523,71 +570,71 @@ Available options are:
       if os.path.isfile(docfile):
         out, err = subprocess.Popen(["xdg-open", docfile]).communicate()
       else:
-        print "Online documentation is not accessible for module:", module
+        print("Online documentation is not accessible for module:", module)
 
   def _usage(self, unused=None):
     usage()
   #
 
   def _makeCoffee(self, unused=None):
-    print "                        ("
-    print "                          )     ("
-    print "                   ___...(-------)-....___"
-    print "               .-\"\"       )    (          \"\"-."
-    print "         .-\'``\'|-._             )         _.-|"
-    print "        /  .--.|   `\"\"---...........---\"\"`   |"
-    print "       /  /    |                             |"
-    print "       |  |    |                             |"
-    print "        \\  \\   |                             |"
-    print "         `\\ `\\ |                             |"
-    print "           `\\ `|            SALOME           |"
-    print "           _/ /\\            4 EVER           /"
-    print "          (__/  \\             <3            /"
-    print "       _..---\"\"` \\                         /`\"\"---.._"
-    print "    .-\'           \\                       /          \'-."
-    print "   :               `-.__             __.-\'              :"
-    print "   :                  ) \"\"---...---\"\" (                 :"
-    print "    \'._               `\"--...___...--\"`              _.\'"
-    print "      \\\"\"--..__                              __..--\"\"/"
-    print "       \'._     \"\"\"----.....______.....----\"\"\"     _.\'"
-    print "          `\"\"--..,,_____            _____,,..--\"\"`"
-    print "                        `\"\"\"----\"\"\"`"
-    print ""
-    print "                    SALOME is working for you; what else?"
-    print ""
+    print("                        (")
+    print("                          )     (")
+    print("                   ___...(-------)-....___")
+    print("               .-\"\"       )    (          \"\"-.")
+    print("         .-\'``\'|-._             )         _.-|")
+    print("        /  .--.|   `\"\"---...........---\"\"`   |")
+    print("       /  /    |                             |")
+    print("       |  |    |                             |")
+    print("        \\  \\   |                             |")
+    print("         `\\ `\\ |                             |")
+    print("           `\\ `|            SALOME           |")
+    print("           _/ /\\            4 EVER           /")
+    print("          (__/  \\             <3            /")
+    print("       _..---\"\"` \\                         /`\"\"---.._")
+    print("    .-\'           \\                       /          \'-.")
+    print("   :               `-.__             __.-\'              :")
+    print("   :                  ) \"\"---...---\"\" (                 :")
+    print("    \'._               `\"--...___...--\"`              _.\'")
+    print("      \\\"\"--..__                              __..--\"\"/")
+    print("       \'._     \"\"\"----.....______.....----\"\"\"     _.\'")
+    print("          `\"\"--..,,_____            _____,,..--\"\"`")
+    print("                        `\"\"\"----\"\"\"`")
+    print("")
+    print("                    SALOME is working for you; what else?")
+    print("")
   #
 
   def _getCar(self, unused=None):
-    print "                                              _____________"
-    print "                                  ..---:::::::-----------. ::::;;."
-    print "                               .\'\"\"\"\"\"\"                  ;;   \\  \":."
-    print "                            .\'\'                          ;     \\   \"\\__."
-    print "                          .\'                            ;;      ;   \\\\\";"
-    print "                        .\'                              ;   _____;   \\\\/"
-    print "                      .\'                               :; ;\"     \\ ___:\'."
-    print "                    .\'--...........................    : =   ____:\"    \\ \\"
-    print "               ..-\"\"                               \"\"\"\'  o\"\"\"     ;     ; :"
-    print "          .--\"\"  .----- ..----...    _.-    --.  ..-\"     ;       ;     ; ;"
-    print "       .\"\"_-     \"--\"\"-----\'\"\"    _-\"        .-\"\"         ;        ;    .-."
-    print "    .\'  .\'   SALOME             .\"         .\"              ;       ;   /. |"
-    print "   /-./\'         4 EVER <3    .\"          /           _..  ;       ;   ;;;|"
-    print "  :  ;-.______               /       _________==.    /_  \\ ;       ;   ;;;;"
-    print "  ;  / |      \"\"\"\"\"\"\"\"\"\"\".---.\"\"\"\"\"\"\"          :    /\" \". |;       ; _; ;;;"
-    print " /\"-/  |                /   /                  /   /     ;|;      ;-\" | ;\';"
-    print ":-  :   \"\"\"----______  /   /              ____.   .  .\"\'. ;;   .-\"..T\"   ."
-    print "\'. \"  ___            \"\":   \'\"\"\"\"\"\"\"\"\"\"\"\"\"\"    .   ; ;    ;; ;.\" .\"   \'--\""
-    print " \",   __ \"\"\"  \"\"---... :- - - - - - - - - \' \'  ; ;  ;    ;;\"  .\""
-    print "  /. ;  \"\"\"---___                             ;  ; ;     ;|.\"\""
-    print " :  \":           \"\"\"----.    .-------.       ;   ; ;     ;:"
-    print "  \\  \'--__               \\   \\        \\     /    | ;     ;;"
-    print "   \'-..   \"\"\"\"---___      :   .______..\\ __/..-\"\"|  ;   ; ;"
-    print "       \"\"--..       \"\"\"--\"        m l s         .   \". . ;"
-    print "             \"\"------...                  ..--\"\"      \" :"
-    print "                        \"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"    \\        /"
-    print "                                               \"------\""
-    print ""
-    print "                                Drive your simulation properly with SALOME!"
-    print ""
+    print("                                              _____________")
+    print("                                  ..---:::::::-----------. ::::;;.")
+    print("                               .\'\"\"\"\"\"\"                  ;;   \\  \":.")
+    print("                            .\'\'                          ;     \\   \"\\__.")
+    print("                          .\'                            ;;      ;   \\\\\";")
+    print("                        .\'                              ;   _____;   \\\\/")
+    print("                      .\'                               :; ;\"     \\ ___:\'.")
+    print("                    .\'--...........................    : =   ____:\"    \\ \\")
+    print("               ..-\"\"                               \"\"\"\'  o\"\"\"     ;     ; :")
+    print("          .--\"\"  .----- ..----...    _.-    --.  ..-\"     ;       ;     ; ;")
+    print("       .\"\"_-     \"--\"\"-----\'\"\"    _-\"        .-\"\"         ;        ;    .-.")
+    print("    .\'  .\'   SALOME             .\"         .\"              ;       ;   /. |")
+    print("   /-./\'         4 EVER <3    .\"          /           _..  ;       ;   ;;;|")
+    print("  :  ;-.______               /       _________==.    /_  \\ ;       ;   ;;;;")
+    print("  ;  / |      \"\"\"\"\"\"\"\"\"\"\".---.\"\"\"\"\"\"\"          :    /\" \". |;       ; _; ;;;")
+    print(" /\"-/  |                /   /                  /   /     ;|;      ;-\" | ;\';")
+    print(":-  :   \"\"\"----______  /   /              ____.   .  .\"\'. ;;   .-\"..T\"   .")
+    print("\'. \"  ___            \"\":   \'\"\"\"\"\"\"\"\"\"\"\"\"\"\"    .   ; ;    ;; ;.\" .\"   \'--\"")
+    print(" \",   __ \"\"\"  \"\"---... :- - - - - - - - - \' \'  ; ;  ;    ;;\"  .\"")
+    print("  /. ;  \"\"\"---___                             ;  ; ;     ;|.\"\"")
+    print(" :  \":           \"\"\"----.    .-------.       ;   ; ;     ;:")
+    print("  \\  \'--__               \\   \\        \\     /    | ;     ;;")
+    print("   \'-..   \"\"\"\"---___      :   .______..\\ __/..-\"\"|  ;   ; ;")
+    print("       \"\"--..       \"\"\"--\"        m l s         .   \". . ;")
+    print("             \"\"------...                  ..--\"\"      \" :")
+    print("                        \"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"    \\        /")
+    print("                                               \"------\"")
+    print("")
+    print("                                Drive your simulation properly with SALOME!")
+    print("")
   #
 
   # Add the following two methods since logger is not pickable
@@ -613,10 +660,11 @@ Available options are:
 
 if __name__ == "__main__":
   if len(sys.argv) == 3:
-    context = pickle.loads(sys.argv[1])
-    args = pickle.loads(sys.argv[2])
+    context = pickle.loads(sys.argv[1].encode('latin1'))
+    args = pickle.loads(sys.argv[2].encode('latin1'))
 
-    context._startSalome(args)
+    status = context._startSalome(args)
+    sys.exit(status)
   else:
     usage()
 #