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.
"""
import ast
import os
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
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):
"""

View file

@ -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)

View file

@ -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()