Ejemplo n.º 1
0
def includeExtensionErrors():
    """Merge all the errors of all the extensions into the errors of these modules
    Should be called only at the initialization of DIRAC, so by the parseCommandLine,
    dirac-agent.py, dirac-service.py, dirac-executor.py
    """
    for extension in reversed(extensionsByPriority()):
        if extension == "DIRAC":
            continue
        try:
            ext_derrno = importlib.import_module("%s.Core.Utilities.DErrno" % extension)
        except ImportError:
            pass
        else:
            # The next 3 dictionary MUST be present for consistency
            # Global name of errors
            sys.modules[__name__].__dict__.update(ext_derrno.extra_dErrName)
            # Dictionary with the error codes
            sys.modules[__name__].dErrorCode.update(ext_derrno.extra_dErrorCode)
            # Error description string
            sys.modules[__name__].dStrError.update(ext_derrno.extra_dStrError)

            # extra_compatErrorString is optional
            for err in getattr(ext_derrno, "extra_compatErrorString", []):
                sys.modules[__name__].compatErrorString.setdefault(err, []).extend(
                    ext_derrno.extra_compatErrorString[err]
                )
Ejemplo n.º 2
0
    def addFunctions(clientCls):
        """Add the functions to the decorated class."""
        attrDict = dict(clientCls.__dict__)
        for extension in extensionsByPriority():
            try:
                path = importlib_resources.path(
                    "%s.%sSystem.Service" % (extension, systemName),
                    "%s.py" % handlerModuleName,
                )
                fullHandlerClassPath = "%s.%s" % (extension, handlerClassPath)
                with path as fp:
                    handlerAst = ast.parse(fp.read_text(), str(path))
            except (ImportError, OSError):
                continue

            # loop over all the nodes (classes, functions, imports) in the handlerModule
            for node in ast.iter_child_nodes(handlerAst):
                # find only a class with the name of the handlerClass
                if not (isinstance(node, ast.ClassDef) and node.name == handlerClassName):
                    continue
                for member in ast.iter_child_nodes(node):
                    # only look at functions
                    if not isinstance(member, ast.FunctionDef):
                        continue
                    if not member.name.startswith("export_"):
                        continue
                    funcName = member.name[len("export_") :]
                    if funcName in attrDict:
                        continue
                    arguments = [a.arg for a in member.args.args]
                    # add the implementation of the function to the class attributes
                    attrDict[funcName] = genFunc(funcName, arguments, fullHandlerClassPath, ast.get_docstring(member))

        return type(clientCls.__name__, clientCls.__bases__, attrDict)
Ejemplo n.º 3
0
    def loadModules(self, modulesList, hideExceptions=False):
        """
        Load all modules required in moduleList
        """
        for modName in modulesList:
            gLogger.verbose("Checking %s" % modName)
            # if it's a executor modName name just load it and be done with it
            if "/" in modName:
                gLogger.verbose(
                    "Module %s seems to be a valid name. Try to load it!" %
                    modName)
                result = self.loadModule(modName,
                                         hideExceptions=hideExceptions)
                if not result["OK"]:
                    return result
                continue
            # Check if it's a system name
            # Look in the CS
            system = modName
            # Can this be generated with sectionFinder?
            csPath = "%s/Executors" % PathFinder.getSystemSection(system)
            gLogger.verbose("Exploring %s to discover modules" % csPath)
            result = gConfig.getSections(csPath)
            if result["OK"]:
                # Add all modules in the CS :P
                for modName in result["Value"]:
                    result = self.loadModule("%s/%s" % (system, modName),
                                             hideExceptions=hideExceptions)
                    if not result["OK"]:
                        return result
            # Look what is installed
            parentModule = None
            for rootModule in extensionsByPriority():
                if not system.endswith("System"):
                    system += "System"
                parentImport = "%s.%s.%s" % (rootModule, system,
                                             self.__csSuffix)
                # HERE!
                result = recurseImport(parentImport)
                if not result["OK"]:
                    return result
                parentModule = result["Value"]
                if parentModule:
                    break
            if not parentModule:
                continue
            parentPath = parentModule.__path__[0]
            gLogger.notice("Found modules path at %s" % parentImport)
            for entry in os.listdir(parentPath):
                if entry == "__init__.py" or not entry.endswith(".py"):
                    continue
                if not os.path.isfile(os.path.join(parentPath, entry)):
                    continue
                modName = "%s/%s" % (system, entry[:-3])
                gLogger.verbose("Trying to import %s" % modName)
                result = self.loadModule(modName,
                                         hideExceptions=hideExceptions,
                                         parentModule=parentModule)

        return S_OK()
Ejemplo n.º 4
0
def loadObjects(path, reFilter=None, parentClass=None):
    """
    :param str path: the path to the syetem for example: DIRAC/AccountingSystem
    :param object reFilter: regular expression used to found the class
    :param object parentClass: class instance
    :return: dictionary containing the name of the class and its instance
    """
    if not reFilter:
        reFilter = re.compile(r".*[a-z1-9]\.py$")
    pathList = List.fromChar(path, "/")

    objectsToLoad = {}
    # Find which object files match
    for parentModule in extensionsByPriority():
        if six.PY3:
            objDir = os.path.join(
                os.path.dirname(os.path.dirname(DIRAC.__file__)), parentModule,
                *pathList)
        else:
            objDir = os.path.join(DIRAC.rootPath, parentModule, *pathList)
        if not os.path.isdir(objDir):
            continue
        for objFile in os.listdir(objDir):
            if reFilter.match(objFile):
                pythonClassName = objFile[:-3]
                if pythonClassName not in objectsToLoad:
                    gLogger.info("Adding to load queue %s/%s/%s" %
                                 (parentModule, path, pythonClassName))
                    objectsToLoad[pythonClassName] = parentModule

    # Load them!
    loadedObjects = {}

    for pythonClassName in objectsToLoad:
        parentModule = objectsToLoad[pythonClassName]
        try:
            # Where parentModule can be DIRAC, pathList is something like [ "AccountingSystem", "Client", "Types" ]
            # And the python class name is.. well, the python class name
            objPythonPath = "%s.%s.%s" % (parentModule, ".".join(pathList),
                                          pythonClassName)
            objModule = __import__(objPythonPath, globals(), locals(),
                                   pythonClassName)
            objClass = getattr(objModule, pythonClassName)
        except Exception as e:
            gLogger.error(
                "Can't load type",
                "%s/%s: %s" % (parentModule, pythonClassName, str(e)))
            continue
        if parentClass == objClass:
            continue
        if parentClass and not issubclass(objClass, parentClass):
            gLogger.warn("%s is not a subclass of %s. Skipping" %
                         (objClass, parentClass))
            continue
        gLogger.info("Loaded %s" % objPythonPath)
        loadedObjects[pythonClassName] = objClass

    return loadedObjects
Ejemplo n.º 5
0
def getCSExtensions() -> list:
    """
    Return list of extensions registered in the CS
    They do not include DIRAC
    """
    return [
        ext[:-5] if ext.endswith("DIRAC") else ext
        for ext in extensionsByPriority() if ext != "DIRAC"
    ]
Ejemplo n.º 6
0
def getCurrentVersion():
    """Get a string corresponding to the current version of the DIRAC package and all the installed
    extension packages
    """
    for ext in extensionsByPriority():
        try:
            return S_OK(importlib.import_module(ext).version)
        except (ImportError, AttributeError):
            pass
Ejemplo n.º 7
0
def runConfigurationWizard(params):
    """Interactively configure DIRAC using metadata from installed extensions"""
    import subprocess
    from prompt_toolkit import prompt, print_formatted_text, HTML
    from DIRAC.Core.Utilities.Extensions import extensionsByPriority, getExtensionMetadata

    for extension in extensionsByPriority():
        extensionMetadata = getExtensionMetadata(extension)
        if extensionMetadata.get("primary_extension", False):
            break
    defaultSetup = extensionMetadata.get("default_setup", "")
    setups = extensionMetadata.get("setups", {})

    # Run the wizard
    try:
        # Get the user's password and create a proxy so we can download from the CS
        while True:
            userPasswd = prompt(u"Enter Certificate password: "******"dirac-proxy-init", "--nocs", "--no-upload", "--pwstdin"],
                input=userPasswd,
                encoding="utf-8",
                check=False,
            )
            if result.returncode == 0:
                break
            print_formatted_text(HTML("<red>Wizard failed, retrying...</red> (press Control + C to exit)\n"))

        print_formatted_text()

        # Ask the user for the appropriate configuration settings
        while True:
            result = _runConfigurationWizard(setups, defaultSetup)
            if result:
                break
            print_formatted_text(HTML("<red>Wizard failed, retrying...</red> (press Control + C to exit)\n"))
    except KeyboardInterrupt:
        print_formatted_text(HTML("<red>Cancelled</red>"))
        sys.exit(1)

    # Apply the arguments to the params object
    setup, csURL = result
    params.setSetup(setup)
    params.setServer(csURL)
    params.setSkipCAChecks(True)

    # Do the actual configuration
    runDiracConfigure(params)

    # Generate a new proxy without passing --nocs
    result = subprocess.run(  # pylint: disable=no-member
        ["dirac-proxy-init", "--pwstdin"],
        input=userPasswd,
        encoding="utf-8",
        check=False,
    )
    sys.exit(result.returncode)
Ejemplo n.º 8
0
def getVersion():
    """Get a dictionary corresponding to the current version of the DIRAC package and all the installed
    extension packages
    """
    vDict = {"Extensions": {}}
    for ext in extensionsByPriority():
        version = get_version(ext)

        vDict["Extensions"][ext] = version
    return S_OK(vDict)
Ejemplo n.º 9
0
    def __generateRootModules(self, baseModules):
        """Iterate over all the possible root modules"""
        self.__rootModules = baseModules
        for rootModule in reversed(extensionsByPriority()):
            if rootModule not in self.__rootModules:
                self.__rootModules.append(rootModule)
        self.__rootModules.append("")

        # Reversing the order because we want first to look in the extension(s)
        self.__rootModules.reverse()
Ejemplo n.º 10
0
 def export_installComponent(self,
                             componentType,
                             system,
                             component,
                             componentModule=""):
     """Install runit directory for the specified component"""
     return gComponentInstaller.installComponent(componentType, system,
                                                 component,
                                                 extensionsByPriority(),
                                                 componentModule)
Ejemplo n.º 11
0
 def __load(self):
     if self.__orderedExtNames:
         return
     for extName in extensionsByPriority():
         try:
             res = imp.find_module(extName)
             if res[0]:
                 res[0].close()
             self.__orderedExtNames.append(extName)
             self.__modules[extName] = res
         except ImportError:
             pass
Ejemplo n.º 12
0
    def __call__(self, func=None):
        """Set the wrapped function or call the script

        This function is either called with a decorator or directly to call the
        underlying function. When running with Python 2 the raw function will always
        be called however in Python 3 the priorities will be applied from the
        dirac.extension_metadata entry_point.
        """
        # If func is provided then the decorator is being applied to a function
        if func is not None:
            self._func = func
            # Find the name of the command and its documentation
            DIRACScript.localCfg.setUsageMessage(func.__globals__["__doc__"])
            DIRACScript.scriptName = os.path.basename(
                func.__globals__["__file__"])[:-3].replace("_", "-")
            return functools.wraps(func)(self)

        # Setuptools based installations aren't supported with Python 2
        if six.PY2:
            return self._func()  # pylint: disable=not-callable

        # This is only available in Python 3.8+ so it has to be here for now
        from importlib import metadata  # pylint: disable=no-name-in-module

        # Iterate through all known entry_points looking for self.scriptName
        matches = [
            ep for ep in metadata.entry_points()["console_scripts"]
            if ep.name == self.scriptName
        ]
        if not matches:
            # TODO: This should an error once the integration tests modified to use pip install
            return self._func()  # pylint: disable=not-callable
            # raise NotImplementedError("Something is very wrong")

        # Call the entry_point from the extension with the highest priority
        rankedExtensions = extensionsByPriority()
        entrypoint = min(
            matches,
            key=lambda e: rankedExtensions.index(entrypointToExtension(e)),
        )
        entrypointFunc = entrypoint.load()

        # Check if entrypoint is DIRACScript
        if not isinstance(entrypointFunc, DIRACScript):
            raise ImportError(
                "Invalid dirac- console_scripts entry_point: " +
                repr(entrypoint) + "\n" +
                "All dirac- console_scripts should be wrapped in the DiracScript "
                +
                "decorator to ensure extension overlays are applied correctly."
            )
        return entrypointFunc._func()
Ejemplo n.º 13
0
 def export_addDefaultOptionsToCS(self,
                                  componentType,
                                  system,
                                  component,
                                  overwrite=False):
     """Add default component options to the global CS or to the local options"""
     return gComponentInstaller.addDefaultOptionsToCS(
         gConfig,
         componentType,
         system,
         component,
         extensionsByPriority(),
         overwrite=overwrite)
Ejemplo n.º 14
0
 def export_setupComponent(self,
                           componentType,
                           system,
                           component,
                           componentModule=""):
     """Setup the specified component for running with the runsvdir daemon
     It implies installComponent
     """
     result = gComponentInstaller.setupComponent(componentType, system,
                                                 component,
                                                 extensionsByPriority(),
                                                 componentModule)
     gConfig.forceRefresh()
     return result
Ejemplo n.º 15
0
 def export_getComponentDocumentation(self, cType, system, module):
     if cType == "service":
         module = "%sHandler" % module
     # Look for the component in extensions
     for extension in extensionsByPriority():
         moduleName = [
             extension, system + "System",
             cType.capitalize(), module
         ]
         try:
             importedModule = importlib.import_module(moduleName)
             return S_OK(importedModule.__doc__)
         except Exception:
             pass
     return S_ERROR("No documentation was found")
Ejemplo n.º 16
0
    def getCSExtensions(self):
        if not self.__csExt:
            if six.PY3:
                exts = extensionsByPriority()
            else:
                from DIRAC.ConfigurationSystem.Client.Config import gConfig

                exts = gConfig.getValue("/DIRAC/Extensions", [])

            self.__csExt = []
            for ext in exts:
                if ext.endswith("DIRAC"):
                    ext = ext[:-5]
                # If the extension is now "" (i.e. vanilla DIRAC), don't include it
                if ext:
                    self.__csExt.append(ext)
        return self.__csExt
Ejemplo n.º 17
0
 def export_getOverallStatus(self):
     """Get the complete status information of all components."""
     result = gComponentInstaller.getOverallStatus(extensionsByPriority())
     if not result["OK"]:
         return result
     statusDict = result["Value"]
     for compType in statusDict:
         for system in statusDict[compType]:
             for component in statusDict[compType][system]:
                 result = gComponentInstaller.getComponentModule(
                     system, component, compType)
                 if not result["OK"]:
                     statusDict[compType][system][component][
                         "Module"] = "Unknown"
                 else:
                     statusDict[compType][system][component][
                         "Module"] = result["Value"]
     return S_OK(statusDict)
Ejemplo n.º 18
0
def getVersion():
    """Get a dictionary corresponding to the current version of the DIRAC package and all the installed
    extension packages
    """
    vDict = {"Extensions": {}}
    for ext in extensionsByPriority():
        if six.PY2:
            try:
                version = importlib.import_module(ext).version
            except (ImportError, AttributeError):
                continue
            if ext.endswith("DIRAC") and ext != "DIRAC":
                ext = ext[: -len("DIRAC")]
        else:
            from importlib.metadata import version as get_version  # pylint: disable=import-error,no-name-in-module

            version = get_version(ext)

        vDict["Extensions"][ext] = version
    return S_OK(vDict)
Ejemplo n.º 19
0
def main():
    global overwrite
    global specialOptions
    global module
    global specialOptions

    from DIRAC.FrameworkSystem.Client.ComponentInstaller import gComponentInstaller

    gComponentInstaller.exitOnError = True

    Script.registerSwitch("w", "overwrite",
                          "Overwrite the configuration in the global CS",
                          setOverwrite)
    Script.registerSwitch("m:", "module=",
                          "Python module name for the component code",
                          setModule)
    Script.registerSwitch("p:", "parameter=", "Special component option ",
                          setSpecialOption)
    # Registering arguments will automatically add their description to the help menu
    Script.registerArgument((
        "System/Component: Full component name (ie: WorkloadManagement/Matcher)",
        "System:           Name of the DIRAC system (ie: WorkloadManagement)",
    ))
    Script.registerArgument(
        " Component:        Name of the DIRAC service (ie: Matcher)",
        mandatory=False)

    Script.parseCommandLine()
    args = Script.getPositionalArgs()

    if len(args) == 1:
        args = args[0].split("/")

    if len(args) != 2:
        Script.showHelp(exitCode=1)

    system = args[0]
    component = args[1]
    compOrMod = module or component

    result = gComponentInstaller.getSoftwareComponents(extensionsByPriority())
    if not result["OK"]:
        gLogger.error(result["Message"])
        DIRACexit(1)
    availableComponents = result["Value"]

    for compType in availableComponents:
        if system in availableComponents[
                compType] and compOrMod in availableComponents[compType][
                    system]:
            cType = compType[:-1].lower()
            break
    else:
        gLogger.error("Component %s/%s is not available for installation" %
                      (system, component))
        DIRACexit(1)

    if module:
        result = gComponentInstaller.addDefaultOptionsToCS(
            gConfig,
            cType,
            system,
            module,
            extensionsByPriority(),
            overwrite=overwrite)
        result = gComponentInstaller.addDefaultOptionsToCS(
            gConfig,
            cType,
            system,
            component,
            extensionsByPriority(),
            specialOptions=specialOptions,
            overwrite=overwrite,
            addDefaultOptions=False,
        )
    else:
        result = gComponentInstaller.addDefaultOptionsToCS(
            gConfig,
            cType,
            system,
            component,
            extensionsByPriority(),
            specialOptions=specialOptions,
            overwrite=overwrite,
        )

    if not result["OK"]:
        gLogger.error(result["Message"])
        DIRACexit(1)
    result = gComponentInstaller.installComponent(cType, system, component,
                                                  extensionsByPriority(),
                                                  module)
    if not result["OK"]:
        gLogger.error(result["Message"])
        DIRACexit(1)
    gLogger.notice(
        "Successfully installed component %s in %s system, now setting it up" %
        (component, system))
    result = gComponentInstaller.setupComponent(cType, system, component,
                                                extensionsByPriority(), module)
    if not result["OK"]:
        gLogger.error(result["Message"])
        DIRACexit(1)
    if component == "ComponentMonitoring":
        result = MonitoringUtilities.monitorInstallation(
            "DB", system, "InstalledComponentsDB")
        if not result["OK"]:
            gLogger.error(result["Message"])
            DIRACexit(1)
    result = MonitoringUtilities.monitorInstallation(cType, system, component,
                                                     module)
    if not result["OK"]:
        gLogger.error(result["Message"])
        DIRACexit(1)
    gLogger.notice("Successfully completed the installation of %s/%s" %
                   (system, component))
    DIRACexit()
Ejemplo n.º 20
0
def getInstalledExtensions():
    """
    Return list of extensions registered in the CS and available in local installation
    """
    return extensionsByPriority()
Ejemplo n.º 21
0
componentType = args[0]

if len(args) == 2:
    system, component = args[1].split("/")
else:
    system = args[1]
    component = args[2]

# imports
from DIRAC import gConfig
from DIRAC import exit as DIRACexit

from DIRAC.Core.Utilities.Extensions import extensionsByPriority
from DIRAC.FrameworkSystem.Client.ComponentInstaller import gComponentInstaller

#

gComponentInstaller.exitOnError = True

result = gComponentInstaller.addDefaultOptionsToCS(gConfig,
                                                   componentType,
                                                   system,
                                                   component,
                                                   extensionsByPriority(),
                                                   specialOptions={},
                                                   overwrite=False)
if not result["OK"]:
    print("ERROR:", result["Message"])
else:
    DIRACexit()
Ejemplo n.º 22
0
    def loadModule(self, modName, hideExceptions=False, parentModule=False):
        """
        Load module name.
        name must take the form [DIRAC System Name]/[DIRAC module]
        """
        while modName and modName[0] == "/":
            modName = modName[1:]
        if modName in self.__modules:
            return S_OK()
        modList = modName.split("/")
        if len(modList) != 2:
            return S_ERROR("Can't load %s: Invalid module name" % (modName))
        csSection = self.__sectionFinder(modName)
        loadGroup = gConfig.getValue("%s/Load" % csSection, [])
        # Check if it's a load group
        if loadGroup:
            gLogger.info("Found load group %s. Will load %s" %
                         (modName, ", ".join(loadGroup)))
            for loadModName in loadGroup:
                if "/" not in loadModName:
                    loadModName = "%s/%s" % (modList[0], loadModName)
                result = self.loadModule(loadModName,
                                         hideExceptions=hideExceptions)
                if not result["OK"]:
                    return result
            return S_OK()
        # Normal load
        loadName = gConfig.getValue("%s/Module" % csSection, "")
        if not loadName:
            loadName = modName
            gLogger.info("Loading %s" % (modName))
        else:
            if "/" not in loadName:
                loadName = "%s/%s" % (modList[0], loadName)
            gLogger.info("Loading %s (%s)" % (modName, loadName))
        # If already loaded, skip
        loadList = loadName.split("/")
        if len(loadList) != 2:
            return S_ERROR("Can't load %s: Invalid module name" % (loadName))
        system, module = loadList
        # Load
        className = module
        if self.__modSuffix:
            className = "%s%s" % (className, self.__modSuffix)
        if loadName not in self.__loadedModules:
            # Check if handler is defined
            loadCSSection = self.__sectionFinder(loadName)
            handlerPath = gConfig.getValue("%s/HandlerPath" % loadCSSection,
                                           "")
            if handlerPath:
                gLogger.info("Trying to %s from CS defined path %s" %
                             (loadName, handlerPath))
                gLogger.verbose("Found handler for %s: %s" %
                                (loadName, handlerPath))
                handlerPath = handlerPath.replace("/", ".")
                if handlerPath.endswith(".py"):
                    handlerPath = handlerPath[:-3]
                className = List.fromChar(handlerPath, ".")[-1]
                result = recurseImport(handlerPath)
                if not result["OK"]:
                    return S_ERROR("Cannot load user defined handler %s: %s" %
                                   (handlerPath, result["Message"]))
                gLogger.verbose("Loading %s" % handlerPath)
            elif parentModule:
                gLogger.info("Trying to autodiscover %s from parent" %
                             loadName)
                # If we've got a parent module, load from there.
                modImport = module
                if self.__modSuffix:
                    modImport = "%s%s" % (modImport, self.__modSuffix)
                result = recurseImport(modImport,
                                       parentModule,
                                       hideExceptions=hideExceptions)
            else:
                # Check to see if the module exists in any of the root modules
                gLogger.info("Trying to autodiscover %s" % loadName)
                for rootModule in extensionsByPriority():
                    importString = "%s.%sSystem.%s.%s" % (
                        rootModule, system, self.__importLocation, module)
                    if self.__modSuffix:
                        importString = "%s%s" % (importString,
                                                 self.__modSuffix)
                    gLogger.verbose("Trying to load %s" % importString)
                    result = recurseImport(importString,
                                           hideExceptions=hideExceptions)
                    # Error while loading
                    if not result["OK"]:
                        return result
                    # Something has been found! break :)
                    if result["Value"]:
                        gLogger.verbose("Found %s" % importString)
                        break
            # Nothing found
            if not result["Value"]:
                return S_ERROR("Could not find %s" % loadName)
            modObj = result["Value"]
            try:
                # Try to get the class from the module
                modClass = getattr(modObj, className)
            except AttributeError:
                if "__file__" in dir(modObj):
                    location = modObj.__file__
                else:
                    location = modObj.__path__
                gLogger.exception("%s module does not have a %s class!" %
                                  (location, module))
                return S_ERROR("Cannot load %s" % module)
            # Check if it's subclass
            if not issubclass(modClass, self.__superClass):
                return S_ERROR("%s has to inherit from %s" %
                               (loadName, self.__superClass.__name__))
            self.__loadedModules[loadName] = {
                "classObj": modClass,
                "moduleObj": modObj
            }
            # End of loading of 'loadName' module

        # A-OK :)
        self.__modules[modName] = self.__loadedModules[loadName].copy()
        # keep the name of the real code module
        self.__modules[modName]["modName"] = modName
        self.__modules[modName]["loadName"] = loadName
        gLogger.notice("Loaded module %s" % modName)

        return S_OK()
Ejemplo n.º 23
0
def test_extensionsByPriority():
    assert "DIRAC" in extensionsByPriority()
Ejemplo n.º 24
0
    def _updateSoftwarePy3(self, version, rootPath_, diracOSVersion):
        if rootPath_:
            return S_ERROR(
                "rootPath argument is not supported for Python 3 installations"
            )
        # Validate and normalise the requested version
        primaryExtension = None
        if "==" in version:
            primaryExtension, version = version.split("==")
        elif six.PY2:
            return S_ERROR(
                "The extension must be specified like DIRAC==vX.Y.Z if installing "
                "a Python 3 version from an existing Python 2 installation.")
        try:
            version = Version(version)
        except InvalidVersion:
            self.log.exception("Invalid version passed", version)
            return S_ERROR("Invalid version passed %r" % version)
        isPrerelease = version.is_prerelease
        version = "v%s" % version

        # Find what to install
        otherExtensions = []
        for extension in extensionsByPriority():
            if primaryExtension is None and getExtensionMetadata(
                    extension).get("primary_extension", False):
                primaryExtension = extension
            else:
                otherExtensions.append(extension)
        self.log.info(
            "Installing Python 3 based", "%s %s with DIRACOS %s" %
            (primaryExtension, version, diracOSVersion or "2"))
        self.log.info("Will also install", repr(otherExtensions))

        # Install DIRACOS
        installer_url = "https://github.com/DIRACGrid/DIRACOS2/releases/"
        if diracOSVersion:
            installer_url += "download/%s/latest/download/DIRACOS-Linux-%s.sh" % (
                version, platform.machine())
        else:
            installer_url += "latest/download/DIRACOS-Linux-%s.sh" % platform.machine(
            )
        self.log.info("Downloading DIRACOS2 installer from", installer_url)
        with tempfile.NamedTemporaryFile(suffix=".sh", mode="wb") as installer:
            with requests.get(installer_url, stream=True) as r:
                if not r.ok:
                    return S_ERROR("Failed to download %s" % installer_url)
                for chunk in r.iter_content(chunk_size=1024**2):
                    installer.write(chunk)
            installer.flush()
            self.log.info("Downloaded DIRACOS installer to", installer.name)

            if six.PY2:
                newProPrefix = os.path.dirname(
                    os.path.realpath(os.path.join(rootPath, "bashrc")))
            else:
                newProPrefix = rootPath
            newProPrefix = os.path.join(
                newProPrefix,
                "versions",
                "%s-%s" % (version, datetime.utcnow().strftime("%s")),
            )
            installPrefix = os.path.join(
                newProPrefix,
                "%s-%s" % (platform.system(), platform.machine()))
            self.log.info("Running DIRACOS installer for prefix",
                          installPrefix)
            r = subprocess.run(  # pylint: disable=no-member
                ["bash", installer.name, "-p", installPrefix],
                stderr=subprocess.PIPE,
                universal_newlines=True,
                check=False,
                timeout=600,
            )
            if r.returncode != 0:
                stderr = [
                    x for x in r.stderr.split("\n")
                    if not x.startswith("Extracting : ")
                ]
                self.log.error("Installing DIRACOS2 failed with returncode",
                               "%s and stdout: %s" % (r.returncode, stderr))
                return S_ERROR("Failed to install DIRACOS2 %s" % stderr)

        # Install DIRAC
        cmd = ["%s/bin/pip" % installPrefix, "install", "--no-color", "-v"]
        if isPrerelease:
            cmd += ["--pre"]
        cmd += ["%s[server]==%s" % (primaryExtension, version)]
        cmd += ["%s[server]" % e for e in otherExtensions]
        r = subprocess.run(  # pylint: disable=no-member
            cmd,
            stderr=subprocess.PIPE,
            universal_newlines=True,
            check=False,
            timeout=600,
        )
        if r.returncode != 0:
            self.log.error("Installing DIRACOS2 failed with returncode",
                           "%s and stdout: %s" % (r.returncode, r.stderr))
            return S_ERROR("Failed to install DIRACOS2 with message %s" %
                           r.stderr)

        # Update the pro link
        oldLink = os.path.join(gComponentInstaller.instancePath, "old")
        proLink = os.path.join(gComponentInstaller.instancePath, "pro")
        if os.path.exists(oldLink):
            os.remove(oldLink)
        os.rename(proLink, oldLink)
        mkLink(newProPrefix, proLink)

        return S_OK()
def main():
    global overwrite
    global specialOptions
    global module
    global specialOptions

    from DIRAC.FrameworkSystem.Client.ComponentInstaller import gComponentInstaller

    gComponentInstaller.exitOnError = True

    Script.registerSwitch("w", "overwrite",
                          "Overwrite the configuration in the global CS",
                          setOverwrite)
    Script.registerSwitch("m:", "module=",
                          "Python module name for the component code",
                          setModule)
    Script.registerSwitch("p:", "parameter=", "Special component option ",
                          setSpecialOption)
    # Registering arguments will automatically add their description to the help menu
    Script.registerArgument((
        "System/Component: Full component name (ie: WorkloadManagement/Matcher)",
        "System:           Name of the DIRAC system (ie: WorkloadManagement)",
    ))
    Script.registerArgument(
        " Component:        Name of the DIRAC service (ie: Matcher)",
        mandatory=False)
    Script.parseCommandLine()
    args = Script.getPositionalArgs()

    if len(args) == 1:
        args = args[0].split("/")

    if len(args) != 2:
        Script.showHelp()
        DIRACexit(1)

    system = args[0]
    component = args[1]

    result = gComponentInstaller.addDefaultOptionsToCS(
        gConfig,
        "service",
        system,
        component,
        extensionsByPriority(),
        specialOptions=specialOptions,
        overwrite=overwrite,
    )

    if not result["OK"]:
        gLogger.error(result["Message"])
        DIRACexit(1)

    result = gComponentInstaller.addTornadoOptionsToCS(gConfig)
    if not result["OK"]:
        gLogger.error(result["Message"])
        DIRACexit(1)

    result = gComponentInstaller.installTornado()
    if not result["OK"]:
        gLogger.error(result["Message"])
        DIRACexit(1)

    gLogger.notice(
        "Successfully installed component %s in %s system, now setting it up" %
        (component, system))
    result = gComponentInstaller.setupTornadoService(system, component,
                                                     extensionsByPriority(),
                                                     module)
    if not result["OK"]:
        gLogger.error(result["Message"])
        DIRACexit(1)

    result = MonitoringUtilities.monitorInstallation("service", system,
                                                     component, module)
    if not result["OK"]:
        gLogger.error(result["Message"])
        DIRACexit(1)
    gLogger.notice("Successfully completed the installation of %s/%s" %
                   (system, component))
    DIRACexit()
Ejemplo n.º 26
0
 def export_addDefaultOptionsToComponentCfg(self, componentType, system,
                                            component):
     """Add default component options local component cfg"""
     return gComponentInstaller.addDefaultOptionsToComponentCfg(
         componentType, system, component, extensionsByPriority())
Ejemplo n.º 27
0
 def export_getSoftwareComponents(self):
     """Get the list of all the components ( services and agents ) for which the software
     is installed on the system
     """
     return gComponentInstaller.getSoftwareComponents(
         extensionsByPriority())
Ejemplo n.º 28
0
 def getInstalledExtensions(self):
     return extensionsByPriority()