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

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 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:
"""