From 850cc599c85144b8e1c320ed24ded834fca2cb6a Mon Sep 17 00:00:00 2001 From: "Blake J. Harnden" Date: Thu, 3 Aug 2017 16:33:54 -0700 Subject: [PATCH] refactored how services are loaded to be more dynamic --- daemon/core/misc/utils.py | 1 - daemon/core/service.py | 69 ++++++++++++++++---------------- daemon/core/services/__init__.py | 29 ++++++++------ daemon/sbin/core-daemon | 22 +--------- 4 files changed, 53 insertions(+), 68 deletions(-) diff --git a/daemon/core/misc/utils.py b/daemon/core/misc/utils.py index 2efaa23b..9f5d76e3 100644 --- a/daemon/core/misc/utils.py +++ b/daemon/core/misc/utils.py @@ -2,7 +2,6 @@ Miscellaneous utility functions, wrappers around some subprocess procedures. """ -import ast import os import subprocess diff --git a/daemon/core/service.py b/daemon/core/service.py index 5593df8d..77ed89e1 100644 --- a/daemon/core/service.py +++ b/daemon/core/service.py @@ -6,6 +6,7 @@ The CoreServices class handles configuration messages for sending a list of available services to the GUI and for configuring individual services. """ + import importlib import inspect import os @@ -30,7 +31,7 @@ from core.misc import utils logger = log.get_logger(__name__) -def valid_module(path, file_name): +def _valid_module(path, file_name): """ Check if file is a valid python module. @@ -52,7 +53,7 @@ def valid_module(path, file_name): return True -def is_service(module, member): +def _is_service(module, member): """ Validates if a module member is a class and an instance of a CoreService. @@ -73,35 +74,6 @@ def is_service(module, member): return True -def get_services(path): - """ - Method for retrieving all CoreServices from a given path. - - :param str path: path to retrieve services from - :return: list of core services - :rtype: list - """ - logger.info("getting custom services from: %s", path) - parent_path = os.path.dirname(path) - logger.info("adding parent path to allow imports: %s", parent_path) - sys.path.append(parent_path) - 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) - - custom_services = [] - for module_name in module_names: - import_statement = "%s.%s" % (base_module, module_name) - logger.info("importing custom service: %s", import_statement) - module = importlib.import_module(import_statement) - members = inspect.getmembers(module, lambda x: is_service(module, x)) - for member in members: - custom_services.append(member[1]) - - return custom_services - - class ServiceManager(object): """ Manages services available for CORE nodes to use. @@ -139,6 +111,37 @@ class ServiceManager(object): return service return None + @classmethod + def add_services(cls, path): + """ + Method for retrieving all CoreServices from a given path. + + :param str path: path to retrieve services from + :return: list of core services + :rtype: list + """ + 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) + 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) + + # custom_services = [] + for module_name in module_names: + import_statement = "%s.%s" % (base_module, module_name) + logger.info("importing custom service module: %s", import_statement) + module = importlib.import_module(import_statement) + members = inspect.getmembers(module, lambda x: _is_service(module, x)) + for member in members: + # custom_services.append(member[1]) + cls.add(member[1]) + + # return custom_services + class CoreServices(ConfigurableManager): """ @@ -194,9 +197,7 @@ class CoreServices(ConfigurableManager): logger.warn("invalid custom service directory specified" ": %s" % path) return - for service in get_services(path): - logger.info("adding new service to manager: %s", service) - ServiceManager.add(service) + ServiceManager.add_services(path) def reset(self): """ diff --git a/daemon/core/services/__init__.py b/daemon/core/services/__init__.py index ddd5485d..391fc9a1 100644 --- a/daemon/core/services/__init__.py +++ b/daemon/core/services/__init__.py @@ -4,17 +4,20 @@ Services Services available to nodes can be put in this directory. Everything listed in __all__ is automatically loaded by the main core module. """ +import os -__all__ = [ - "quagga", - "nrl", - "xorp", - "bird", - "utility", - "security", - "ucarp", - "dockersvc", - "OvsService", - "RyuService", - "startup" -] +from core.misc import log +from core.service import ServiceManager + +logger = log.get_logger(__name__) + +_PATH = os.path.abspath(os.path.dirname(__file__)) + + +def load(): + """ + Loads all services from the modules that reside under core.services. + + :return: nothing + """ + ServiceManager.add_services(_PATH) diff --git a/daemon/sbin/core-daemon b/daemon/sbin/core-daemon index 2b54dfd0..6f78afb2 100755 --- a/daemon/sbin/core-daemon +++ b/daemon/sbin/core-daemon @@ -30,6 +30,7 @@ from core import constants from core import corehandlers from core import coreserver from core import enumerations +from core import services from core.api import coreapi from core.corehandlers import CoreDatagramRequestHandler from core.enumerations import MessageFlags @@ -39,16 +40,6 @@ from core.misc import nodemaps from core.misc import nodeutils from core.misc.utils import closeonexec from core.misc.utils import daemonize -from core.services import bird -from core.services import dockersvc -from core.services import nrl -from core.services import quagga -from core.services import sdn -from core.services import security -from core.services import startup -from core.services import ucarp -from core.services import utility -from core.services import xorp logger = log.get_logger(__name__) @@ -355,15 +346,6 @@ if __name__ == "__main__": nodeutils.set_node_map(node_map) # load default services - quagga.load_services() - nrl.load_services() - xorp.load_services() - bird.load_services() - utility.load_services() - security.load_services() - ucarp.load_services() - dockersvc.load_services() - startup.load_services() - sdn.load_services() + services.load() main()