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 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)
|
||||||
|
|
|
@ -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 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:
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in a new issue