From c4a61b269b9453c1a2157802d79af3fb06615b42 Mon Sep 17 00:00:00 2001 From: "Blake J. Harnden" Date: Mon, 5 Feb 2018 11:22:01 -0800 Subject: [PATCH] updates to support dynamic loading of emane models from a custom emane directory --- configure.ac | 4 +- daemon/core/emane/emanemanager.py | 28 +++++------ daemon/core/misc/utils.py | 4 +- daemon/core/service.py | 77 ++--------------------------- daemon/data/core.conf | 2 +- daemon/examples/myemane/__init__.py | 0 gui/core-gui.in | 6 +++ 7 files changed, 26 insertions(+), 95 deletions(-) create mode 100644 daemon/examples/myemane/__init__.py diff --git a/configure.ac b/configure.ac index 351e7223..b309eb30 100644 --- a/configure.ac +++ b/configure.ac @@ -12,10 +12,10 @@ # # this defines the CORE version number, must be static for AC_INIT # -AC_INIT(core, m4_esyscmd_s([./revision.sh 5.1]), core-dev@nrl.navy.mil) +AC_INIT(core, 5.1, core-dev@nrl.navy.mil) VERSION=$PACKAGE_VERSION CORE_VERSION=$PACKAGE_VERSION -CORE_VERSION_DATE=m4_esyscmd_s([./revision.sh -d]) +CORE_VERSION_DATE=m4_esyscmd_s([date +%Y%m%d]) COREDPY_VERSION=$PACKAGE_VERSION CORE_MAINTAINERS="CORE Developers " CORE_VENDOR="CORE Developers" diff --git a/daemon/core/emane/emanemanager.py b/daemon/core/emane/emanemanager.py index f60b1084..918f2c56 100644 --- a/daemon/core/emane/emanemanager.py +++ b/daemon/core/emane/emanemanager.py @@ -93,7 +93,16 @@ class EmaneManager(ConfigurableManager): self._modelclsmap = { self.emane_config.name: self.emane_config } - self.load_models(_PATH) + + # load provided models + self.load_models(EMANE_MODELS) + + # load custom models + custom_models_path = session.config.get("emane_models_dir") + if custom_models_path: + emane_models = utils.load_classes(custom_models_path, EmaneModel) + self.load_models(emane_models) + def logversion(self): """ @@ -183,25 +192,10 @@ class EmaneManager(ConfigurableManager): return rc - def loadmodels(self): + def load_models(self, emane_models): """ load EMANE models and make them available. """ - for emane_model in EMANE_MODELS: - logger.info("loading emane model: (%s) %s - %s", - emane_model, emane_model.name, RegisterTlvs(emane_model.config_type)) - self._modelclsmap[emane_model.name] = emane_model - self.session.add_config_object(emane_model.name, emane_model.config_type, - emane_model.configure_emane) - - def load_models(self, path): - """ - Loads EMANE models into the manager for usage within CORE. - - :param str path: path to retrieve model from - :return: nothing - """ - emane_models = utils.load_classes(path, EmaneModel) for emane_model in emane_models: logger.info("loading emane model: (%s) %s - %s", emane_model, emane_model.name, RegisterTlvs(emane_model.config_type)) diff --git a/daemon/core/misc/utils.py b/daemon/core/misc/utils.py index 7eb9281c..f99847c7 100644 --- a/daemon/core/misc/utils.py +++ b/daemon/core/misc/utils.py @@ -527,8 +527,8 @@ def load_classes(path, clazz): module = importlib.import_module(import_statement) members = inspect.getmembers(module, lambda x: _is_class(module, x, clazz)) for member in members: - clazz = member[1] - classes.append(clazz) + valid_class = member[1] + classes.append(valid_class) except: logger.exception("unexpected error during import, skipping: %s", import_statement) diff --git a/daemon/core/service.py b/daemon/core/service.py index 3b76eb0a..16b7834d 100644 --- a/daemon/core/service.py +++ b/daemon/core/service.py @@ -29,49 +29,6 @@ from core.enumerations import RegisterTlvs from core.misc import utils -def _valid_module(path, file_name): - """ - Check if file is a valid python module. - - :param str path: path to file - :param str file_name: file name to check - :return: True if a valid python module file, False otherwise - :rtype: bool - """ - file_path = os.path.join(path, file_name) - if not os.path.isfile(file_path): - return False - - if file_name.startswith("_"): - return False - - if not file_name.endswith(".py"): - return False - - return True - - -def _is_service(module, member): - """ - Validates if a module member is a class and an instance of a CoreService. - - :param module: module to validate for service - :param member: member to validate for service - :return: True if a valid service, False otherwise - :rtype: bool - """ - if not inspect.isclass(member): - return False - - if not issubclass(member, CoreService): - return False - - if member.__module__ != module.__name__: - return False - - return True - - class ServiceManager(object): """ Manages services available for CORE nodes to use. @@ -118,36 +75,10 @@ class ServiceManager(object): :return: list of core services :rtype: list """ - # validate path exists - logger.info("attempting to add services from path: %s", path) - if not os.path.isdir(path): - logger.warn("invalid custom service directory specified" ": %s" % path) - # check if path is in sys.path - logger.info("getting custom services from: %s", path) - parent_path = os.path.dirname(path) - if parent_path not in sys.path: - logger.info("adding parent path to allow imports: %s", parent_path) - sys.path.append(parent_path) - - # retrieve potential service modules, and filter out invalid modules - base_module = os.path.basename(path) - module_names = os.listdir(path) - module_names = filter(lambda x: _valid_module(path, x), module_names) - module_names = map(lambda x: x[:-3], module_names) - - # import and add all service modules in the path - for module_name in module_names: - import_statement = "%s.%s" % (base_module, module_name) - logger.info("importing custom service module: %s", import_statement) - try: - module = importlib.import_module(import_statement) - members = inspect.getmembers(module, lambda x: _is_service(module, x)) - for member in members: - clazz = member[1] - clazz.on_load() - cls.add(clazz) - except: - logger.exception("unexpected error during import, skipping: %s", import_statement) + services = utils.load_classes(path, CoreService) + for service in services: + service.on_load() + cls.add(service) class CoreServices(ConfigurableManager): diff --git a/daemon/data/core.conf b/daemon/data/core.conf index 032d4390..97bb96bb 100644 --- a/daemon/data/core.conf +++ b/daemon/data/core.conf @@ -57,7 +57,7 @@ emane_platform_port = 8101 emane_transform_port = 8201 emane_event_generate = True emane_event_monitor = False -emane_models = RfPipe, Ieee80211abg, CommEffect, Bypass, Tdma +#emane_models_dir = /home/username/.core/emane # EMANE log level range [0,4] default: 2 #emane_log_level = 2 emane_realtime = True diff --git a/daemon/examples/myemane/__init__.py b/daemon/examples/myemane/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/gui/core-gui.in b/gui/core-gui.in index 2c42c186..a66d7f77 100755 --- a/gui/core-gui.in +++ b/gui/core-gui.in @@ -88,6 +88,12 @@ init_conf_dir() { else cp -a $CORE_DATA_DIR/examples/myservices/* $CONFDIR/myservices/ fi + mkdir -p $CONFDIR/myemane + if [ $? != 0 ]; then + echo "error making directory $CONFDIR/myemane!"; + else + cp -a $CORE_DATA_DIR/examples/myemane/* $CONFDIR/myemane/ + fi } cd $LIBDIR