daemon: updated how local services are loaded to leverage full core path imports, avoiding name collisions with external modules
This commit is contained in:
parent
a42697ecce
commit
2eef7076f4
3 changed files with 23 additions and 27 deletions
|
@ -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)
|
||||
|
|
|
@ -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)
|
|
@ -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:
|
||||
"""
|
||||
|
|
Loading…
Reference in a new issue