예제 #1
0
    def discoverHandlers(self):
        """
        Force the discovery of URL, automatic call when we try to get handlers for the first time.
        You can disable the automatic call with autoDiscovery=False at initialization
        """
        gLogger.debug("Trying to auto-discover the handlers for Tornado")

        # Look in config
        diracSystems = gConfig.getSections("/Systems")
        serviceList = []
        if diracSystems["OK"]:
            for system in diracSystems["Value"]:
                try:
                    instance = PathFinder.getSystemInstance(system)
                    services = gConfig.getSections("/Systems/%s/%s/Services" % (system, instance))
                    if services["OK"]:
                        for service in services["Value"]:
                            newservice = "%s/%s" % (system, service)

                            # We search in the CS all handlers which used HTTPS as protocol
                            isHTTPS = gConfig.getValue(
                                "/Systems/%s/%s/Services/%s/Protocol" % (system, instance, service)
                            )
                            if isHTTPS and isHTTPS.lower() == "https":
                                serviceList.append(newservice)
                # On systems sometime you have things not related to services...
                except RuntimeError:
                    pass
        return self.loadHandlersByServiceName(serviceList)
예제 #2
0
    def __init__(self, services=True, endpoints=False, port=None):
        """C'r

        :param list services: (default True) List of service handlers to load.
            If ``True``, loads all described in the CS
            If ``False``, do not load services
        :param list endpoints: (default False) List of endpoint handlers to load.
            If ``True``, loads all described in the CS
            If ``False``, do not load endpoints
        :param int port: Port to listen to.
            If ``None``, the port is resolved following the logic described in the class documentation
        """
        self.__startTime = time.time()
        # Application metadata, routes and settings mapping on the ports
        self.__appsSettings = {}
        # Default port, if enother is not discover
        if port is None:
            port = gConfig.getValue(
                "/Systems/Tornado/%s/Port" %
                PathFinder.getSystemInstance("Tornado"), 8443)
        self.port = port

        # Handler manager initialization with default settings
        self.handlerManager = HandlerManager(services, endpoints)

        # temp value for computation, used by the monitoring
        self.__report = None
        # Last update time stamp
        self.__monitorLastStatsUpdate = None
        self.__monitoringLoopDelay = 60  # In secs

        self.activityMonitoring = False
        if "Monitoring" in Operations().getMonitoringBackends(
                monitoringType="ServiceMonitoring"):
            self.activityMonitoring = True
        # If services are defined, load only these ones (useful for debug purpose or specific services)
        retVal = self.handlerManager.loadServicesHandlers()
        if not retVal["OK"]:
            sLog.error(retVal["Message"])
            raise ImportError(
                "Some services can't be loaded, check the service names and configuration."
            )
        # Response time to load services
        self.__elapsedTime = time.time() - self.__startTime
        retVal = self.handlerManager.loadEndpointsHandlers()
        if not retVal["OK"]:
            sLog.error(retVal["Message"])
            raise ImportError(
                "Some endpoints can't be loaded, check the endpoint names and configuration."
            )
예제 #3
0
    def __init__(self, services=None, port=None):
        """

    :param list services: (default None) List of service handlers to load. If ``None``, loads all
    :param int port: Port to listen to. If None, the port is resolved following the logic
       described in the class documentation
    """

        if port is None:
            port = gConfig.getValue(
                "/Systems/Tornado/%s/Port" %
                PathFinder.getSystemInstance('Tornado'), 8443)

        if services and not isinstance(services, list):
            services = [services]

        # URLs for services.
        # Contains Tornado :py:class:`tornado.web.url` object
        self.urls = []
        # Other infos
        self.port = port
        self.handlerManager = HandlerManager()

        # Monitoring attributes

        self._monitor = MonitoringClient()
        # temp value for computation, used by the monitoring
        self.__report = None
        # Last update time stamp
        self.__monitorLastStatsUpdate = None
        self.__monitoringLoopDelay = 60  # In secs

        # If services are defined, load only these ones (useful for debug purpose or specific services)
        if services:
            retVal = self.handlerManager.loadHandlersByServiceName(services)
            if not retVal['OK']:
                sLog.error(retVal['Message'])
                raise ImportError(
                    "Some services can't be loaded, check the service names and configuration."
                )

        # if no service list is given, load services from configuration
        handlerDict = self.handlerManager.getHandlersDict()
        for item in handlerDict.items():
            # handlerDict[key].initializeService(key)
            self.urls.append(url(item[0], item[1]))
        # If there is no services loaded:
        if not self.urls:
            raise ImportError(
                "There is no services loaded, please check your configuration")
예제 #4
0
def main():

    if os.environ.get("DIRAC_USE_TORNADO_IOLOOP",
                      "false").lower() not in ("yes", "true"):
        raise RuntimeError(
            "DIRAC_USE_TORNADO_IOLOOP is not defined in the environment." +
            "\n" + "It is necessary to run with Tornado." + "\n" +
            "https://dirac.readthedocs.io/en/latest/DeveloperGuide/TornadoServices/index.html"
        )

    from DIRAC import gConfig
    from DIRAC.ConfigurationSystem.Client import PathFinder
    from DIRAC.ConfigurationSystem.Client.ConfigurationData import gConfigurationData
    from DIRAC.Core.Tornado.Server.TornadoServer import TornadoServer
    from DIRAC.Core.Utilities.DErrno import includeExtensionErrors
    from DIRAC.FrameworkSystem.Client.Logger import gLogger

    localCfg = Script.localCfg
    localCfg.setConfigurationForServer("Tornado/Tornado")
    localCfg.addMandatoryEntry("/DIRAC/Setup")
    localCfg.addDefaultEntry("/DIRAC/Security/UseServerCertificate", "yes")
    localCfg.addDefaultEntry("LogLevel", "INFO")
    localCfg.addDefaultEntry("LogColor", True)
    resultDict = localCfg.loadUserData()
    if not resultDict["OK"]:
        gLogger.initialize("Tornado", "/")
        gLogger.error("There were errors when loading configuration",
                      resultDict["Message"])
        sys.exit(1)

    includeExtensionErrors()

    gLogger.initialize("Tornado", "/")

    # We check if there is no configuration server started as master
    # If you want to start a master CS you should use Configuration_Server.cfg and
    # use tornado-start-CS.py
    key = "/Systems/Configuration/%s/Services/Server/Protocol" % PathFinder.getSystemInstance(
        "Configuration")
    if gConfigurationData.isMaster() and gConfig.getValue(
            key, "dips").lower() == "https":
        gLogger.fatal("You can't run the CS and services in the same server!")
        sys.exit(0)

    serverToLaunch = TornadoServer(endpoints=True)
    serverToLaunch.startTornado()
예제 #5
0
    def checkURLs(self):
        """Ensure that the running services have their URL in the Config."""
        self.log.info("Checking URLs")
        # get services again, in case they were started/stop in controlComponents
        gConfig.forceRefresh(fromMaster=True)

        # get port used for https based services
        try:
            tornadoSystemInstance = PathFinder.getSystemInstance(
                system="Tornado",
                setup=self.setup,
            )
            self._tornadoPort = gConfig.getValue(
                Path.cfgPath("/System/Tornado/", tornadoSystemInstance,
                             "Port"),
                self._tornadoPort,
            )
        except RuntimeError:
            pass

        self.log.debug("Using Tornado Port:", self._tornadoPort)

        res = self.getRunningInstances(instanceType="Services",
                                       runitStatus="All")
        if not res["OK"]:
            return S_ERROR("Failure to get running services")
        self.services = res["Value"]
        for service, options in sorted(self.services.items()):
            self.log.debug("Checking URL for %s with options %s" %
                           (service, options))
            # ignore SystemAdministrator, does not have URLs
            if "SystemAdministrator" in service:
                continue
            self._checkServiceURL(service, options)

        if self.csAPI.csModified and self.commitURLs:
            self.log.info("Commiting changes to the CS")
            result = self.csAPI.commit()
            if not result["OK"]:
                self.logError("Commit to CS failed", result["Message"])
                return S_ERROR("Failed to commit to CS")
        return S_OK()
예제 #6
0
def main():
  # Must be defined BEFORE any dirac import
  os.environ['DIRAC_USE_TORNADO_IOLOOP'] = "True"

  from DIRAC import gConfig
  from DIRAC.ConfigurationSystem.Client import PathFinder
  from DIRAC.ConfigurationSystem.Client.ConfigurationData import gConfigurationData
  from DIRAC.ConfigurationSystem.Client.LocalConfiguration import LocalConfiguration
  from DIRAC.Core.Tornado.Server.TornadoServer import TornadoServer
  from DIRAC.Core.Utilities.DErrno import includeExtensionErrors
  from DIRAC.FrameworkSystem.Client.Logger import gLogger

  # We check if there is no configuration server started as master
  # If you want to start a master CS you should use Configuration_Server.cfg and
  # use tornado-start-CS.py
  key = '/Systems/Configuration/%s/Services/Server/Protocol' % PathFinder.getSystemInstance('Configuration')
  if gConfigurationData.isMaster() and gConfig.getValue(key, 'dips').lower() == 'https':
    gLogger.fatal("You can't run the CS and services in the same server!")
    sys.exit(0)

  localCfg = LocalConfiguration()
  localCfg.setConfigurationForServer('Tornado/Tornado')
  localCfg.addMandatoryEntry("/DIRAC/Setup")
  localCfg.addDefaultEntry("/DIRAC/Security/UseServerCertificate", "yes")
  localCfg.addDefaultEntry("LogLevel", "INFO")
  localCfg.addDefaultEntry("LogColor", True)
  resultDict = localCfg.loadUserData()
  if not resultDict['OK']:
    gLogger.initialize("Tornado", "/")
    gLogger.error("There were errors when loading configuration", resultDict['Message'])
    sys.exit(1)

  includeExtensionErrors()

  gLogger.initialize('Tornado', "/")

  serverToLaunch = TornadoServer()
  serverToLaunch.startTornado()