diff --git a/daemon/core/emulator/coreemu.py b/daemon/core/emulator/coreemu.py index 179faf9c..9baadb54 100644 --- a/daemon/core/emulator/coreemu.py +++ b/daemon/core/emulator/coreemu.py @@ -6,7 +6,6 @@ import sys from pathlib import Path from typing import Dict, List, Type -import core.services from core import utils from core.configservice.manager import ConfigServiceManager from core.emane.modelmanager import EmaneModelManager @@ -92,7 +91,7 @@ class CoreEmu: :return: nothing """ # load default services - self.service_errors = core.services.load() + self.service_errors = ServiceManager.load_locals() # load custom services service_paths = self.config.get("custom_services_dir") logger.debug("custom service paths: %s", service_paths) diff --git a/daemon/core/services/__init__.py b/daemon/core/services/__init__.py index 4d9b90a2..e69de29b 100644 --- a/daemon/core/services/__init__.py +++ b/daemon/core/services/__init__.py @@ -1,20 +0,0 @@ -""" -Services - -Services available to nodes can be put in this directory. Everything listed in -__all__ is automatically loaded by the main core module. -""" -from pathlib import Path - -from core.services.coreservices import ServiceManager - -_PATH: Path = Path(__file__).resolve().parent - - -def load(): - """ - Loads all services from the modules that reside under core.services. - - :return: list of services that failed to load - """ - return ServiceManager.add_services(_PATH) diff --git a/daemon/core/services/coreservices.py b/daemon/core/services/coreservices.py index cabc93c0..8d611d4b 100644 --- a/daemon/core/services/coreservices.py +++ b/daemon/core/services/coreservices.py @@ -9,6 +9,7 @@ services. import enum import logging +import pkgutil import time from pathlib import Path from typing import ( @@ -23,6 +24,7 @@ from typing import ( Union, ) +from core import services as core_services from core import utils from core.emulator.data import FileData from core.emulator.enumerations import ExceptionLevels, MessageFlags, RegisterTlvs @@ -233,25 +235,25 @@ class ServiceManager: """ name = service.name logger.debug("loading service: class(%s) name(%s)", service.__name__, name) - + # avoid services with no name + if name is None: + logger.debug("not loading class(%s) with no name", service.__name__) + return # avoid duplicate services if name in cls.services: - raise ValueError("duplicate service being added: %s" % name) - + raise ValueError(f"duplicate service being added: {name}") # validate dependent executables are present for executable in service.executables: try: utils.which(executable, required=True) except CoreError as e: raise CoreError(f"service({name}): {e}") - # validate service on load succeeds try: service.on_load() except Exception as e: logger.exception("error during service(%s) on load", service.name) raise ValueError(e) - # make service available cls.services[name] = service @@ -288,6 +290,21 @@ class ServiceManager: logger.debug("not loading service(%s): %s", service.name, e) return service_errors + @classmethod + def load_locals(cls) -> List[str]: + errors = [] + for module_info in pkgutil.walk_packages( + core_services.__path__, f"{core_services.__name__}." + ): + services = utils.load_module(module_info.name, CoreService) + for service in services: + try: + cls.add(service) + except CoreError as e: + errors.append(service.name) + logger.debug("not loading service(%s): %s", service.name, e) + return errors + class CoreServices: """