]> SALOME platform Git repositories - modules/kernel.git/commitdiff
Salome HOME
[bos #32522][EDF] SALOME on Demand. Added functions and refactored to support adding...
authorKonstantin Leontev <konstantin.leontev@opencascade.com>
Tue, 10 Jan 2023 13:11:56 +0000 (16:11 +0300)
committerKonstantin LEONTEV <konstantin.leontev@opencascade.com>
Wed, 8 Mar 2023 12:46:28 +0000 (13:46 +0100)
bin/SalomeOnDemandTK/extension_unpacker.py
bin/SalomeOnDemandTK/extension_utilities.py
bin/runSalomeOnDemand.py

index 47355b7722b08ea84b3d662cb28cfe59efaaa872..57a5fe38223a81ca5a45f872f9294ecf80cba7f4 100644 (file)
@@ -38,8 +38,9 @@ import json
 from traceback import format_exc
 
 from .extension_utilities import logger, \
-    DFILE_EXT, ARCFILE_EXT, EXTDEPENDSON_KEY, \
-    isvalid_filename, isvalid_dirname
+    DFILE_EXT, ARCFILE_EXT, EXTDEPENDSON_KEY, EXTCOMPONENT_KEY, \
+    isvalid_filename, isvalid_dirname, ext_info_bykey, set_selext_env, get_app_root
+
 
 def unpack_salomex(salome_root, salomex):
     """
@@ -50,7 +51,7 @@ def unpack_salomex(salome_root, salomex):
         salomex - a given salomex file to unpack.
 
     Returns:
-        None.
+        True if an ext was successfully unpacked.
     """
 
     logger.debug('Starting unpack a salome extension file')
@@ -58,7 +59,7 @@ def unpack_salomex(salome_root, salomex):
     # Check if provided filenames are valid
     if  not isvalid_dirname(salome_root) or \
         not isvalid_filename(salomex, ARCFILE_EXT):
-        return
+        return False
 
     try:
         with tarfile.open(salomex) as ext:
@@ -80,7 +81,7 @@ def unpack_salomex(salome_root, salomex):
                     if not os.path.isfile(depends_filename):
                         logger.error('Cannot find %s for a module that extension depends on!',
                             depends_filename)
-                        return
+                        return False
 
             # Unpack archive in the salome_root
             logger.debug('Extract all the files into %s...', salome_root)
@@ -90,12 +91,53 @@ def unpack_salomex(salome_root, salomex):
 
     except (OSError, KeyError):
         logger.error(format_exc())
+        return False
+
+    return True
+
+
+def install_salomex(salomex):
+    """
+    Install a given salome extension into SALOME_APPLICATION_DIR.
+
+    Args:
+        salomex - a given salomex file to unpack.
+
+    Returns:
+        A list of components to be activated later.
+    """
+
+    logger.debug('Starting install a salome extension from %s', salomex)
+
+    # Check if we have the salome root path
+    app_root = os.environ.get('SALOME_APPLICATION_DIR', '')
+    if not app_root:
+        # It should be set on the app start, but leave it here to run as a standalone script
+        logger.warning(
+            'Env var SALOME_APPLICATION_DIR is not set! Try to set it going up from cur location.')
+        app_root = get_app_root()
+
+    # Unpack an archive
+    if not unpack_salomex(app_root, salomex):
+        return []
+
+    # Set up an environment
+    # It's not clear at the moment what to do if it fails
+    ext_name, _ = os.path.splitext(os.path.basename(salomex))
+    set_selext_env(app_root, ext_name)
+
+    # Get components to activate later
+    components = ext_info_bykey(app_root, ext_name, EXTCOMPONENT_KEY)
+
+    return components if components else []
 
 
 if __name__ == '__main__':
     if len(sys.argv) == 3:
         arg_1, arg_2 = sys.argv[1:] # pylint: disable=unbalanced-tuple-unpacking
         unpack_salomex(arg_1, arg_2)
+    elif len(sys.argv) == 2:
+        install_salomex(sys.argv[1])
     else:
         logger.error('You must provide all the arguments!')
         logger.info(unpack_salomex.__doc__)
index ae2dc6ccb2e99a64738c3acf5fcfe6ef6773f983..eb60bf30ab0b851583cd4b8f7f41863f01ffa19c 100644 (file)
@@ -33,9 +33,12 @@ Utilities and constants those help to deal with salome extension files.
 """
 
 import os
+import sys
 import logging
 import json
 from traceback import format_exc
+from pathlib import Path
+import importlib.util
 
 # Usually logging verbosity is set inside bin/runSalomeCommon.py when salome is starting.
 # Here we do just the same for a case if we call this package stand alone.
@@ -43,6 +46,12 @@ FORMAT = '%(levelname)s : %(asctime)s : [%(filename)s:%(funcName)s:%(lineno)s] :
 logging.basicConfig(format=FORMAT, level=logging.DEBUG, force=False)
 logger = logging.getLogger()
 
+# SalomeContext sets the logging verbosity level on its own,
+# and we put it here, so it doesn't override the local format above.
+#pylint: disable=wrong-import-position
+import salomeContext
+#pylint: enable=wrong-import-position
+
 SALOME_EXTDIR = '__SALOME_EXT__'
 ARCFILE_EXT = 'salomex'
 BFILE_EXT = 'salomexb'
@@ -124,6 +133,47 @@ def read_salomexd(file_path):
         return {}
 
 
+def value_from_salomexd(file_path, key):
+    """
+    Reads a content of a salomexd file and return a value for the given key.
+
+    Args:
+        file_path - the path to the salomexd file.
+        key - the key to search an assigned value.
+
+    Returns:
+        A value assigned to the given key if exist, otherwise None.
+    """
+
+    file_content = read_salomexd(file_path)
+    if key in file_content and file_content[key]:
+        logger.debug('Key: %s, value: %s', key, file_content[key])
+        return file_content[key]
+
+    logger.warning('Cannot get a value for key %s in salomexd file %s', key, file_path)
+    return None
+
+
+def ext_info_bykey(salome_root, salomex_name, key):
+    """
+    Search a salomexd file by ext name and return a value for the given key.
+
+    Args:
+        install_dir - directory where the given extension is installed.
+        salomex_name - the given extension's name.
+        key - the key to search an assigned value.
+
+    Returns:
+        A value for key in the given ext salomexd file.
+    """
+
+    salomexd = find_salomexd(salome_root, salomex_name)
+    if salomexd:
+        return value_from_salomexd(salomexd, key)
+
+    return None
+
+
 def create_salomexb(name, included):
     """
     Create a salomexb file from a list of included file names.
@@ -453,3 +503,95 @@ def find_envpy(install_dir, salomex_name):
     """
 
     return find_file(install_dir, salomex_name + ENVPYFILE_SUF)
+
+
+def module_from_filename(filename):
+    """
+    Create and execute a module by filename.
+
+    Args:
+        filename - a given python filename.
+
+    Returns:
+        Module.
+    """
+
+    # Get the module from the filename
+    basename = os.path.basename(filename)
+    module_name, _ = os.path.splitext(basename)
+
+    spec = importlib.util.spec_from_file_location(module_name, filename)
+    if not spec:
+        logger.error('Could not get a spec for %s file!')
+        return None
+
+    module = importlib.util.module_from_spec(spec)
+    if not module:
+        logger.error('Could not get a module for %s file!')
+        return None
+
+    sys.modules[module_name] = module
+
+    logger.debug('Execute %s module', module_name)
+    spec.loader.exec_module(module)
+
+    return module
+
+
+def set_selext_env(install_dir, salomex_name, context=None):
+    """
+    Finds and run _env.py file for the given extension.
+
+    Args:
+        install_dir - path to directory to check.
+        salomex_name - extension's name.
+        context - SalomeContext object.
+
+    Returns:
+        True if an envpy file was found and run its init func.
+    """
+
+    logger.debug('Set an env for salome extension: %s...', salomex_name)
+
+    # Set the root dir as env variable
+    if not context:
+        context = salomeContext.SalomeContext(None)
+        context.setVariable('SALOME_APPLICATION_DIR', install_dir, overwrite=False)
+
+    # Find env file
+    ext_envpy = find_envpy(install_dir, salomex_name)
+    if not ext_envpy:
+        return False
+
+    # Get a module
+    envpy_module = module_from_filename(ext_envpy)
+    if not envpy_module:
+        return False
+
+    # Set env if we have something to set
+    ext_root = os.path.join(install_dir, SALOME_EXTDIR)
+    if hasattr(envpy_module, 'init'):
+        envpy_module.init(context, ext_root)
+        return True
+    else:
+        logger.warning('Env file %s doesnt have init func:!', ext_envpy)
+
+    logger.warning('Setting an env for salome extension %s failed!', salomex_name)
+    return False
+
+
+def get_app_root(levels_up=5):
+    """
+    Finds an app root by going up on the given steps.
+
+    Args:
+        levels_up - steps up in dir hierarchy relative to the current file.
+
+    Returns:
+        Path to the app root.
+    """
+
+    app_root = str(Path(__file__).resolve().parents[levels_up - 1])
+    logger.debug('App root: %s', app_root)
+
+    return app_root
index 69d48b00fffb2e64eacba4136f0dafb9abbbc5f1..a54a1ac28e1f7f03a6d112af242ecff6b11ff6db 100755 (executable)
 
 import os
 import sys
-import importlib.util
-from pathlib import Path
 import salomeContext
 from SalomeOnDemandTK.extension_utilities import logger, \
-    DFILE_EXT, SALOME_EXTDIR, \
-    list_files_ext, find_envpy
-
-
-def module_from_filename(filename):
-    """
-    Create and execute a module by filename.
-
-    Args:
-        filename - a given python filename.
-
-    Returns:
-        Module.
-    """
-
-    # Get the module from the filename
-    basename = os.path.basename(filename)
-    module_name, _ = os.path.splitext(basename)
-
-    spec = importlib.util.spec_from_file_location(module_name, filename)
-    if not spec:
-        logger.error('Could not get a spec for %s file!')
-        return None
-
-    module = importlib.util.module_from_spec(spec)
-    if not module:
-        logger.error('Could not get a module for %s file!')
-        return None
-
-    sys.modules[module_name] = module
-
-    logger.debug('Execute %s module', module_name)
-    spec.loader.exec_module(module)
-
-    return module
+    DFILE_EXT, \
+    list_files_ext, set_selext_env, get_app_root
 
 
 def set_ext_env(app_name='', version=''):
@@ -87,9 +52,7 @@ def set_ext_env(app_name='', version=''):
     logger.debug('Set an env for app: %s, version: %s...', app_name, version)
 
     # Get the root directory
-    levels_up = 4
-    app_root = str(Path(__file__).resolve().parents[levels_up - 1])
-    logger.debug('App root: %s', app_root)
+    app_root = get_app_root()
 
     # Find and source all _env.py files for installed extensions
     installed_ext = list_files_ext(app_root, DFILE_EXT)
@@ -103,24 +66,11 @@ def set_ext_env(app_name='', version=''):
     context.setVariable('SALOME_APPLICATION_DIR', app_root, overwrite=True)
 
     # Execute env file as a module
-    ext_root = os.path.join(app_root, SALOME_EXTDIR)
     for salomexd in installed_ext:
         salomexd_name = os.path.basename(salomexd)
         ext_name, _ = os.path.splitext(salomexd_name)
 
-        # Find env file
-        ext_envpy = find_envpy(app_root, ext_name)
-        if not ext_envpy:
-            continue
-
-        # Get a module
-        envpy_module = module_from_filename(ext_envpy)
-        if not envpy_module:
-            continue
-
-        # Set env if we have something to set
-        if hasattr(envpy_module, 'init'):
-            envpy_module.init(context, ext_root)
+        set_selext_env(app_root, ext_name, context)
 
 
 if __name__ == "__main__":