refactored how services are loaded to be more dynamic

This commit is contained in:
Blake J. Harnden 2017-08-03 16:33:54 -07:00
parent 35c48e67a3
commit 850cc599c8
4 changed files with 53 additions and 68 deletions

View file

@ -2,7 +2,6 @@
Miscellaneous utility functions, wrappers around some subprocess procedures. Miscellaneous utility functions, wrappers around some subprocess procedures.
""" """
import ast
import os import os
import subprocess import subprocess

View file

@ -6,6 +6,7 @@ The CoreServices class handles configuration messages for sending
a list of available services to the GUI and for configuring individual a list of available services to the GUI and for configuring individual
services. services.
""" """
import importlib import importlib
import inspect import inspect
import os import os
@ -30,7 +31,7 @@ from core.misc import utils
logger = log.get_logger(__name__) 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. Check if file is a valid python module.
@ -52,7 +53,7 @@ def valid_module(path, file_name):
return True 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. 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 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): class ServiceManager(object):
""" """
Manages services available for CORE nodes to use. Manages services available for CORE nodes to use.
@ -139,6 +111,37 @@ class ServiceManager(object):
return service return service
return None 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): class CoreServices(ConfigurableManager):
""" """
@ -194,9 +197,7 @@ class CoreServices(ConfigurableManager):
logger.warn("invalid custom service directory specified" ": %s" % path) logger.warn("invalid custom service directory specified" ": %s" % path)
return return
for service in get_services(path): ServiceManager.add_services(path)
logger.info("adding new service to manager: %s", service)
ServiceManager.add(service)
def reset(self): def reset(self):
""" """

View file

@ -4,17 +4,20 @@ Services
Services available to nodes can be put in this directory. Everything listed in Services available to nodes can be put in this directory. Everything listed in
__all__ is automatically loaded by the main core module. __all__ is automatically loaded by the main core module.
""" """
import os
__all__ = [ from core.misc import log
"quagga", from core.service import ServiceManager
"nrl",
"xorp", logger = log.get_logger(__name__)
"bird",
"utility", _PATH = os.path.abspath(os.path.dirname(__file__))
"security",
"ucarp",
"dockersvc", def load():
"OvsService", """
"RyuService", Loads all services from the modules that reside under core.services.
"startup"
] :return: nothing
"""
ServiceManager.add_services(_PATH)

View file

@ -30,6 +30,7 @@ from core import constants
from core import corehandlers from core import corehandlers
from core import coreserver from core import coreserver
from core import enumerations from core import enumerations
from core import services
from core.api import coreapi from core.api import coreapi
from core.corehandlers import CoreDatagramRequestHandler from core.corehandlers import CoreDatagramRequestHandler
from core.enumerations import MessageFlags from core.enumerations import MessageFlags
@ -39,16 +40,6 @@ from core.misc import nodemaps
from core.misc import nodeutils from core.misc import nodeutils
from core.misc.utils import closeonexec from core.misc.utils import closeonexec
from core.misc.utils import daemonize 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__) logger = log.get_logger(__name__)
@ -355,15 +346,6 @@ if __name__ == "__main__":
nodeutils.set_node_map(node_map) nodeutils.set_node_map(node_map)
# load default services # load default services
quagga.load_services() services.load()
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()
main() main()