daemon: updated how local services are loaded to leverage full core path imports, avoiding name collisions with external modules

This commit is contained in:
Blake Harnden 2022-03-02 12:42:53 -08:00
parent a42697ecce
commit 2eef7076f4
3 changed files with 23 additions and 27 deletions

View file

@ -6,7 +6,6 @@ import sys
from pathlib import Path from pathlib import Path
from typing import Dict, List, Type from typing import Dict, List, Type
import core.services
from core import utils from core import utils
from core.configservice.manager import ConfigServiceManager from core.configservice.manager import ConfigServiceManager
from core.emane.modelmanager import EmaneModelManager from core.emane.modelmanager import EmaneModelManager
@ -92,7 +91,7 @@ class CoreEmu:
:return: nothing :return: nothing
""" """
# load default services # load default services
self.service_errors = core.services.load() self.service_errors = ServiceManager.load_locals()
# load custom services # load custom services
service_paths = self.config.get("custom_services_dir") service_paths = self.config.get("custom_services_dir")
logger.debug("custom service paths: %s", service_paths) logger.debug("custom service paths: %s", service_paths)

View file

@ -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)

View file

@ -9,6 +9,7 @@ services.
import enum import enum
import logging import logging
import pkgutil
import time import time
from pathlib import Path from pathlib import Path
from typing import ( from typing import (
@ -23,6 +24,7 @@ from typing import (
Union, Union,
) )
from core import services as core_services
from core import utils from core import utils
from core.emulator.data import FileData from core.emulator.data import FileData
from core.emulator.enumerations import ExceptionLevels, MessageFlags, RegisterTlvs from core.emulator.enumerations import ExceptionLevels, MessageFlags, RegisterTlvs
@ -233,25 +235,25 @@ class ServiceManager:
""" """
name = service.name name = service.name
logger.debug("loading service: class(%s) name(%s)", service.__name__, 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 # avoid duplicate services
if name in cls.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 # validate dependent executables are present
for executable in service.executables: for executable in service.executables:
try: try:
utils.which(executable, required=True) utils.which(executable, required=True)
except CoreError as e: except CoreError as e:
raise CoreError(f"service({name}): {e}") raise CoreError(f"service({name}): {e}")
# validate service on load succeeds # validate service on load succeeds
try: try:
service.on_load() service.on_load()
except Exception as e: except Exception as e:
logger.exception("error during service(%s) on load", service.name) logger.exception("error during service(%s) on load", service.name)
raise ValueError(e) raise ValueError(e)
# make service available # make service available
cls.services[name] = service cls.services[name] = service
@ -288,6 +290,21 @@ class ServiceManager:
logger.debug("not loading service(%s): %s", service.name, e) logger.debug("not loading service(%s): %s", service.name, e)
return service_errors 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: class CoreServices:
""" """