changes to remove the need to pass services separately, when the node has access to them directly, also made a couple CoreServices methods more consistent to have the node as first param and service second

This commit is contained in:
Blake J. Harnden 2018-06-21 14:56:30 -07:00
parent b868454b5e
commit 0aca9d7809
11 changed files with 123 additions and 147 deletions

View file

@ -1151,7 +1151,7 @@ class CoreHandler(SocketServer.BaseRequestHandler):
# a file request: e.g. "service:zebra:quagga.conf" # a file request: e.g. "service:zebra:quagga.conf"
file_name = servicesstring[2] file_name = servicesstring[2]
service_name = services[0] service_name = services[0]
file_data = self.session.services.getservicefile(service_name, node, file_name, services) file_data = self.session.services.getservicefile(node, service_name, file_name)
self.session.broadcast_file(file_data) self.session.broadcast_file(file_data)
# short circuit this request early to avoid returning response below # short circuit this request early to avoid returning response below
return replies return replies
@ -1163,7 +1163,7 @@ class CoreHandler(SocketServer.BaseRequestHandler):
type_flag = ConfigFlags.UPDATE.value type_flag = ConfigFlags.UPDATE.value
data_types = tuple(repeat(ConfigDataTypes.STRING.value, len(ServiceShim.keys))) data_types = tuple(repeat(ConfigDataTypes.STRING.value, len(ServiceShim.keys)))
service = self.session.services.getcustomservice(node_id, service_name, default_service=True) service = self.session.services.getcustomservice(node_id, service_name, default_service=True)
values = ServiceShim.tovaluelist(service, node, services) values = ServiceShim.tovaluelist(node, service)
captions = None captions = None
possible_values = None possible_values = None
groups = None groups = None
@ -1530,15 +1530,15 @@ class CoreHandler(SocketServer.BaseRequestHandler):
if status: if status:
fail += "Stop %s," % service.name fail += "Stop %s," % service.name
if event_type == EventTypes.START.value or event_type == EventTypes.RESTART.value: if event_type == EventTypes.START.value or event_type == EventTypes.RESTART.value:
status = self.session.services.node_service_startup(node, service, services) status = self.session.services.node_service_startup(node, service)
if status: if status:
fail += "Start %s(%s)," % service.name fail += "Start %s(%s)," % service.name
if event_type == EventTypes.PAUSE.value: if event_type == EventTypes.PAUSE.value:
status = self.session.services.validatenodeservice(node, service, services) status = self.session.services.validatenodeservice(node, service)
if status: if status:
fail += "%s," % service.name fail += "%s," % service.name
if event_type == EventTypes.RECONFIGURE.value: if event_type == EventTypes.RECONFIGURE.value:
self.session.services.node_service_reconfigure(node, service, services) self.session.services.node_service_reconfigure(node, service)
fail_data = "" fail_data = ""
if len(fail) > 0: if len(fail) > 0:
@ -1724,7 +1724,7 @@ class CoreHandler(SocketServer.BaseRequestHandler):
opaque = "service:%s" % service.name opaque = "service:%s" % service.name
data_types = tuple(repeat(ConfigDataTypes.STRING.value, len(ServiceShim.keys))) data_types = tuple(repeat(ConfigDataTypes.STRING.value, len(ServiceShim.keys)))
node = self.session.get_object(node_id) node = self.session.get_object(node_id)
values = ServiceShim.tovaluelist(service, node, node.services) values = ServiceShim.tovaluelist(node, service)
config_data = ConfigData( config_data = ConfigData(
message_type=0, message_type=0,
node=node_id, node=node_id,

View file

@ -35,14 +35,13 @@ class ServiceShim(object):
keys = ["dirs", "files", "startidx", "cmdup", "cmddown", "cmdval", "meta", "starttime"] keys = ["dirs", "files", "startidx", "cmdup", "cmddown", "cmdval", "meta", "starttime"]
@classmethod @classmethod
def tovaluelist(cls, service, node, services): def tovaluelist(cls, node, service):
""" """
Convert service properties into a string list of key=value pairs, Convert service properties into a string list of key=value pairs,
separated by "|". separated by "|".
:param CoreService service: service to get value list for
:param core.netns.nodes.CoreNode node: node to get value list for :param core.netns.nodes.CoreNode node: node to get value list for
:param list[CoreService] services: services for node :param CoreService service: service to get value list for
:return: value list string :return: value list string
:rtype: str :rtype: str
""" """
@ -50,8 +49,8 @@ class ServiceShim(object):
service.shutdown, service.validate, service.meta, service.starttime] service.shutdown, service.validate, service.meta, service.starttime]
if not service.custom: if not service.custom:
# this is always reached due to classmethod # this is always reached due to classmethod
valmap[valmap.index(service.configs)] = service.getconfigfilenames(node.objid, services) valmap[valmap.index(service.configs)] = service.getconfigfilenames(node)
valmap[valmap.index(service.startup)] = service.getstartup(node, services) valmap[valmap.index(service.startup)] = service.getstartup(node)
vals = map(lambda a, b: "%s=%s" % (a, str(b)), cls.keys, valmap) vals = map(lambda a, b: "%s=%s" % (a, str(b)), cls.keys, valmap)
return "|".join(vals) return "|".join(vals)
@ -112,7 +111,7 @@ class ServiceShim(object):
service.starttime = value service.starttime = value
@classmethod @classmethod
def servicesfromopaque(self, opaque): def servicesfromopaque(cls, opaque):
""" """
Build a list of services from an opaque data string. Build a list of services from an opaque data string.
@ -288,18 +287,18 @@ class CoreServices(object):
return startups return startups
def getdefaultservices(self, service_type): def getdefaultservices(self, node_type):
""" """
Get the list of default services that should be enabled for a Get the list of default services that should be enabled for a
node for the given node type. node for the given node type.
:param service_type: service type to get default services for :param node_type: node type to get default services for
:return: default services :return: default services
:rtype: list[CoreService] :rtype: list[CoreService]
""" """
logger.debug("getting default services for type: %s", service_type) logger.debug("getting default services for type: %s", node_type)
results = [] results = []
defaults = self.defaultservices.get(service_type, []) defaults = self.defaultservices.get(node_type, [])
for name in defaults: for name in defaults:
logger.debug("checking for service with service manager: %s", name) logger.debug("checking for service with service manager: %s", name)
service = ServiceManager.get(name) service = ServiceManager.get(name)
@ -351,7 +350,7 @@ class CoreServices(object):
:param core.coreobj.PyCoreNode node: node to add services to :param core.coreobj.PyCoreNode node: node to add services to
:param str node_type: node type to add services to :param str node_type: node type to add services to
:param list[str] services: services to add to node :param list[str] services: names of services to add to node
:return: nothing :return: nothing
""" """
if not services: if not services:
@ -372,7 +371,6 @@ class CoreServices(object):
Return (nodenum, service) tuples for all stored configs. Used when reconnecting to a Return (nodenum, service) tuples for all stored configs. Used when reconnecting to a
session or opening XML. session or opening XML.
:param bool use_clsmap: should a class map be used, default to True
:return: list of tuples of node ids and services :return: list of tuples of node ids and services
:rtype: list :rtype: list
""" """
@ -413,10 +411,9 @@ class CoreServices(object):
pool = ThreadPool() pool = ThreadPool()
results = [] results = []
services = sorted(node.services, key=lambda x: x.startindex) boot_paths = self.node_service_dependencies(node.services)
boot_paths = self.node_service_dependencies(services)
for boot_path in boot_paths: for boot_path in boot_paths:
result = pool.apply_async(self.boot_node_dependencies, (node, boot_path, services)) result = pool.apply_async(self.boot_node_dependencies, (node, boot_path))
results.append(result) results.append(result)
pool.close() pool.close()
@ -424,19 +421,18 @@ class CoreServices(object):
for result in results: for result in results:
result.get() result.get()
def boot_node_dependencies(self, node, boot_path, all_services): def boot_node_dependencies(self, node, boot_path):
logger.info("booting node service dependencies: %s", boot_path) logger.info("booting node service dependencies: %s", boot_path)
for service in boot_path: for service in boot_path:
self.bootnodeservice(node, service, all_services) self.bootnodeservice(node, service)
def bootnodeservice(self, node, service, services): def bootnodeservice(self, node, service):
""" """
Start a service on a node. Create private dirs, generate config Start a service on a node. Create private dirs, generate config
files, and execute startup commands. files, and execute startup commands.
:param core.netns.vnode.LxcNode node: node to boot services on :param core.netns.vnode.LxcNode node: node to boot services on
:param CoreService service: service to start :param CoreService service: service to start
:param list services: service list
:return: nothing :return: nothing
""" """
logger.info("starting node(%s) service: %s (%s)", node.name, service.name, service.startindex) logger.info("starting node(%s) service: %s (%s)", node.name, service.name, service.startindex)
@ -446,11 +442,11 @@ class CoreServices(object):
node.privatedir(directory) node.privatedir(directory)
# create service files # create service files
self.node_service_files(node, service, services) self.node_service_files(node, service)
# run startup # run startup
wait = service.validation_mode == ServiceMode.BLOCKING wait = service.validation_mode == ServiceMode.BLOCKING
status = self.node_service_startup(node, service, services, wait) status = self.node_service_startup(node, service, wait)
if status: if status:
raise ServiceBootError("node(%s) service(%s) error during startup" % (node.name, service.name)) raise ServiceBootError("node(%s) service(%s) error during startup" % (node.name, service.name))
@ -461,7 +457,7 @@ class CoreServices(object):
# run validation commands, if present and not timer mode # run validation commands, if present and not timer mode
if service.validation_mode != ServiceMode.TIMER: if service.validation_mode != ServiceMode.TIMER:
status = self.validatenodeservice(node, service, services) status = self.validatenodeservice(node, service)
if status: if status:
raise ServiceBootError("node(%s) service(%s) failed validation" % (node.name, service.name)) raise ServiceBootError("node(%s) service(%s) failed validation" % (node.name, service.name))
@ -493,31 +489,29 @@ class CoreServices(object):
:param core.netns.vnode.LxcNode node: node to validate services for :param core.netns.vnode.LxcNode node: node to validate services for
:return: nothing :return: nothing
""" """
services = sorted(node.services, key=lambda x: x.startindex) for service in node.services:
for service in services: self.validatenodeservice(node, service)
self.validatenodeservice(node, service, services)
def validatenodeservice(self, node, service, services): def validatenodeservice(self, node, service):
""" """
Run the validation command(s) for a service. Run the validation command(s) for a service.
:param core.netns.vnode.LxcNode node: node to validate service for :param core.netns.vnode.LxcNode node: node to validate service for
:param CoreService service: service to validate :param CoreService service: service to validate
:param list services: services for node
:return: service validation status :return: service validation status
:rtype: int :rtype: int
""" """
logger.info("validating node(%s) service(%s): %s", node.name, service.name, service.startindex) logger.info("validating node(%s) service(%s): %s", node.name, service.name, service.startindex)
cmds = service.validate cmds = service.validate
if not service.custom: if not service.custom:
cmds = service.getvalidate(node, services) cmds = service.getvalidate(node)
status = 0 status = 0
for cmd in cmds: for cmd in cmds:
logger.info("validating service(%s) using: %s", service.name, cmd) logger.info("validating service(%s) using: %s", service.name, cmd)
try: try:
node.check_cmd(cmd) node.check_cmd(cmd)
except CoreCommandError as e: except CoreCommandError:
logger.exception("node(%s) service(%s) validate command failed", node.name, service.name) logger.exception("node(%s) service(%s) validate command failed", node.name, service.name)
status = -1 status = -1
@ -552,15 +546,14 @@ class CoreServices(object):
status = -1 status = -1
return status return status
def getservicefile(self, service_name, node, filename, services): def getservicefile(self, node, service_name, filename):
""" """
Send a File Message when the GUI has requested a service file. Send a File Message when the GUI has requested a service file.
The file data is either auto-generated or comes from an existing config. The file data is either auto-generated or comes from an existing config.
:param str service_name: service to get file from
:param core.netns.vnode.LxcNode node: node to get service file from :param core.netns.vnode.LxcNode node: node to get service file from
:param str service_name: service to get file from
:param str filename: file name to retrieve :param str filename: file name to retrieve
:param list[str] services: list of services associated with node
:return: file message for node :return: file message for node
""" """
# get service to get file from # get service to get file from
@ -568,20 +561,11 @@ class CoreServices(object):
if not service: if not service:
raise ValueError("invalid service: %s", service_name) raise ValueError("invalid service: %s", service_name)
# get service for node
node_services = []
for service_name in services:
node_service = self.getcustomservice(node.objid, service_name, default_service=True)
if not node_service:
logger.warn("unknown service: %s", service)
continue
node_services.append(node_service)
# retrieve config files for default/custom service # retrieve config files for default/custom service
if service.custom: if service.custom:
config_files = service.configs config_files = service.configs
else: else:
config_files = service.getconfigfilenames(node.objid, node_services) config_files = service.getconfigfilenames(node)
if filename not in config_files: if filename not in config_files:
raise ValueError("unknown service(%s) config file: %s", service_name, filename) raise ValueError("unknown service(%s) config file: %s", service_name, filename)
@ -589,7 +573,7 @@ class CoreServices(object):
# get the file data # get the file data
data = service.configtxt.get(filename) data = service.configtxt.get(filename)
if data is None: if data is None:
data = "%s" % service.generateconfig(node, filename, node_services) data = "%s" % service.generateconfig(node, filename)
else: else:
data = "%s" % data data = "%s" % data
@ -632,13 +616,12 @@ class CoreServices(object):
# set custom service file data # set custom service file data
service.configtxt[filename] = data service.configtxt[filename] = data
def node_service_startup(self, node, service, services, wait=False): def node_service_startup(self, node, service, wait=False):
""" """
Startup a node service. Startup a node service.
:param PyCoreNode node: node to reconfigure service for :param PyCoreNode node: node to reconfigure service for
:param CoreService service: service to reconfigure :param CoreService service: service to reconfigure
:param list[CoreService] services: node services
:param bool wait: determines if we should wait to validate startup :param bool wait: determines if we should wait to validate startup
:return: status of startup :return: status of startup
:rtype: int :rtype: int
@ -646,7 +629,7 @@ class CoreServices(object):
cmds = service.startup cmds = service.startup
if not service.custom: if not service.custom:
cmds = service.getstartup(node, services) cmds = service.getstartup(node)
status = 0 status = 0
for cmd in cmds: for cmd in cmds:
@ -660,26 +643,25 @@ class CoreServices(object):
status = -1 status = -1
return status return status
def node_service_files(self, node, service, services): def node_service_files(self, node, service):
""" """
Creates node service files. Creates node service files.
:param PyCoreNode node: node to reconfigure service for :param PyCoreNode node: node to reconfigure service for
:param CoreService service: service to reconfigure :param CoreService service: service to reconfigure
:param list[CoreService] services: node services
:return: nothing :return: nothing
""" """
# get values depending on if custom or not # get values depending on if custom or not
file_names = service.configs file_names = service.configs
if not service.custom: if not service.custom:
file_names = service.getconfigfilenames(node.objid, services) file_names = service.getconfigfilenames(node)
for file_name in file_names: for file_name in file_names:
logger.info("generating service config: %s", file_name) logger.info("generating service config: %s", file_name)
if service.custom: if service.custom:
cfg = service.configtxt.get(file_name) cfg = service.configtxt.get(file_name)
if cfg is None: if cfg is None:
cfg = service.generateconfig(node, file_name, services) cfg = service.generateconfig(node, file_name)
# cfg may have a file:/// url for copying from a file # cfg may have a file:/// url for copying from a file
try: try:
@ -689,22 +671,21 @@ class CoreServices(object):
logger.exception("error copying service file: %s", file_name) logger.exception("error copying service file: %s", file_name)
continue continue
else: else:
cfg = service.generateconfig(node, file_name, services) cfg = service.generateconfig(node, file_name)
node.nodefile(file_name, cfg) node.nodefile(file_name, cfg)
def node_service_reconfigure(self, node, service, services): def node_service_reconfigure(self, node, service):
""" """
Reconfigure a node service. Reconfigure a node service.
:param PyCoreNode node: node to reconfigure service for :param PyCoreNode node: node to reconfigure service for
:param CoreService service: service to reconfigure :param CoreService service: service to reconfigure
:param list[CoreService] services: node services
:return: nothing :return: nothing
""" """
file_names = service.configs file_names = service.configs
if not service.custom: if not service.custom:
file_names = service.getconfigfilenames(node.objid, services) file_names = service.getconfigfilenames(node)
for file_name in file_names: for file_name in file_names:
if file_name[:7] == "file:///": if file_name[:7] == "file:///":
@ -713,7 +694,7 @@ class CoreServices(object):
cfg = service.configtxt.get(file_name) cfg = service.configtxt.get(file_name)
if cfg is None: if cfg is None:
cfg = service.generateconfig(node, file_name, services) cfg = service.generateconfig(node, file_name)
node.nodefile(file_name, cfg) node.nodefile(file_name, cfg)
@ -794,21 +775,20 @@ class CoreService(object):
pass pass
@classmethod @classmethod
def getconfigfilenames(cls, node_id, services): def getconfigfilenames(cls, node):
""" """
Return the tuple of configuration file filenames. This default method Return the tuple of configuration file filenames. This default method
returns the cls._configs tuple, but this method may be overriden to returns the cls._configs tuple, but this method may be overriden to
provide node-specific filenames that may be based on other services. provide node-specific filenames that may be based on other services.
:param int node_id: node id to get config file names for :param core.netns.vnode.LxcNode node: node to generate config for
:param list services: node services :return: configuration files
:return: class configuration files
:rtype: tuple :rtype: tuple
""" """
return cls.configs return cls.configs
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
""" """
Generate configuration file given a node object. The filename is Generate configuration file given a node object. The filename is
provided to allow for multiple config files. The other services are provided to allow for multiple config files. The other services are
@ -818,13 +798,12 @@ class CoreService(object):
:param core.netns.vnode.LxcNode node: node to generate config for :param core.netns.vnode.LxcNode node: node to generate config for
:param str filename: file name to generate config for :param str filename: file name to generate config for
:param list services: services for node
:return: nothing :return: nothing
""" """
raise NotImplementedError raise NotImplementedError
@classmethod @classmethod
def getstartup(cls, node, services): def getstartup(cls, node):
""" """
Return the tuple of startup commands. This default method Return the tuple of startup commands. This default method
returns the cls._startup tuple, but this method may be returns the cls._startup tuple, but this method may be
@ -832,14 +811,13 @@ class CoreService(object):
based on other services. based on other services.
:param core.netns.vnode.LxcNode node: node to get startup for :param core.netns.vnode.LxcNode node: node to get startup for
:param list services: services for node
:return: startup commands :return: startup commands
:rtype: tuple :rtype: tuple
""" """
return cls.startup return cls.startup
@classmethod @classmethod
def getvalidate(cls, node, services): def getvalidate(cls, node):
""" """
Return the tuple of validate commands. This default method Return the tuple of validate commands. This default method
returns the cls._validate tuple, but this method may be returns the cls._validate tuple, but this method may be
@ -847,7 +825,6 @@ class CoreService(object):
based on other services. based on other services.
:param core.netns.vnode.LxcNode node: node to validate :param core.netns.vnode.LxcNode node: node to validate
:param list services: services for node
:return: validation commands :return: validation commands
:rtype: tuple :rtype: tuple
""" """

View file

@ -21,12 +21,12 @@ class Bird(CoreService):
validate = ("pidof bird",) validate = ("pidof bird",)
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
""" """
Return the bird.conf file contents. Return the bird.conf file contents.
""" """
if filename == cls.configs[0]: if filename == cls.configs[0]:
return cls.generateBirdConf(node, services) return cls.generateBirdConf(node)
else: else:
raise ValueError raise ValueError
@ -45,7 +45,7 @@ class Bird(CoreService):
return "0.0.0.0" return "0.0.0.0"
@classmethod @classmethod
def generateBirdConf(cls, node, services): def generateBirdConf(cls, node):
""" """
Returns configuration file text. Other services that depend on bird Returns configuration file text. Other services that depend on bird
will have generatebirdifcconfig() and generatebirdconfig() will have generatebirdifcconfig() and generatebirdconfig()
@ -77,7 +77,7 @@ protocol device {
""" % (cls.name, cls.routerid(node)) """ % (cls.name, cls.routerid(node))
# Generate protocol specific configurations # Generate protocol specific configurations
for s in services: for s in node.services:
if cls.name not in s.depends: if cls.name not in s.depends:
continue continue
cfg += s.generatebirdconfig(node) cfg += s.generatebirdconfig(node)

View file

@ -125,7 +125,7 @@ class DockerService(CoreService):
image = "" image = ""
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
""" """
Returns a string having contents of a docker.sh script that Returns a string having contents of a docker.sh script that
can be modified to start a specific docker image. can be modified to start a specific docker image.

View file

@ -23,7 +23,7 @@ class NrlService(CoreService):
shutdown = () shutdown = ()
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
return "" return ""
@staticmethod @staticmethod
@ -55,7 +55,7 @@ class MgenSinkService(NrlService):
shutdown = ("killall mgen",) shutdown = ("killall mgen",)
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
cfg = "0.0 LISTEN UDP 5000\n" cfg = "0.0 LISTEN UDP 5000\n"
for ifc in node.netifs(): for ifc in node.netifs():
name = utils.sysctl_devname(ifc.name) name = utils.sysctl_devname(ifc.name)
@ -63,7 +63,7 @@ class MgenSinkService(NrlService):
return cfg return cfg
@classmethod @classmethod
def getstartup(cls, node, services): def getstartup(cls, node):
cmd = cls.startup[0] cmd = cls.startup[0]
cmd += " output /tmp/mgen_%s.log" % node.name cmd += " output /tmp/mgen_%s.log" % node.name
return cmd, return cmd,
@ -80,7 +80,7 @@ class NrlNhdp(NrlService):
validate = ("pidof nrlnhdp",) validate = ("pidof nrlnhdp",)
@classmethod @classmethod
def getstartup(cls, node, services): def getstartup(cls, node):
""" """
Generate the appropriate command-line based on node interfaces. Generate the appropriate command-line based on node interfaces.
""" """
@ -88,7 +88,7 @@ class NrlNhdp(NrlService):
cmd += " -l /var/log/nrlnhdp.log" cmd += " -l /var/log/nrlnhdp.log"
cmd += " -rpipe %s_nhdp" % node.name cmd += " -rpipe %s_nhdp" % node.name
servicenames = map(lambda x: x.name, services) servicenames = map(lambda x: x.name, node.services)
if "SMF" in servicenames: if "SMF" in servicenames:
cmd += " -flooding ecds" cmd += " -flooding ecds"
cmd += " -smfClient %s_smf" % node.name cmd += " -smfClient %s_smf" % node.name
@ -114,7 +114,7 @@ class NrlSmf(NrlService):
configs = ("startsmf.sh",) configs = ("startsmf.sh",)
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename, ):
""" """
Generate a startup script for SMF. Because nrlsmf does not Generate a startup script for SMF. Because nrlsmf does not
daemonize, it can cause problems in some situations when launched daemonize, it can cause problems in some situations when launched
@ -125,7 +125,7 @@ class NrlSmf(NrlService):
comments = "" comments = ""
cmd = "nrlsmf instance %s_smf" % node.name cmd = "nrlsmf instance %s_smf" % node.name
servicenames = map(lambda x: x.name, services) servicenames = map(lambda x: x.name, node.services)
netifs = filter(lambda x: not getattr(x, 'control', False), node.netifs()) netifs = filter(lambda x: not getattr(x, 'control', False), node.netifs())
if len(netifs) == 0: if len(netifs) == 0:
return "" return ""
@ -165,7 +165,7 @@ class NrlOlsr(NrlService):
validate = ("pidof nrlolsrd",) validate = ("pidof nrlolsrd",)
@classmethod @classmethod
def getstartup(cls, node, services): def getstartup(cls, node):
""" """
Generate the appropriate command-line based on node interfaces. Generate the appropriate command-line based on node interfaces.
""" """
@ -178,7 +178,7 @@ class NrlOlsr(NrlService):
cmd += " -l /var/log/nrlolsrd.log" cmd += " -l /var/log/nrlolsrd.log"
cmd += " -rpipe %s_olsr" % node.name cmd += " -rpipe %s_olsr" % node.name
servicenames = map(lambda x: x.name, services) servicenames = map(lambda x: x.name, node.services)
if "SMF" in servicenames and not "NHDP" in servicenames: if "SMF" in servicenames and not "NHDP" in servicenames:
cmd += " -flooding s-mpr" cmd += " -flooding s-mpr"
cmd += " -smfClient %s_smf" % node.name cmd += " -smfClient %s_smf" % node.name
@ -199,7 +199,7 @@ class NrlOlsrv2(NrlService):
validate = ("pidof nrlolsrv2",) validate = ("pidof nrlolsrv2",)
@classmethod @classmethod
def getstartup(cls, node, services): def getstartup(cls, node):
""" """
Generate the appropriate command-line based on node interfaces. Generate the appropriate command-line based on node interfaces.
""" """
@ -207,7 +207,7 @@ class NrlOlsrv2(NrlService):
cmd += " -l /var/log/nrlolsrv2.log" cmd += " -l /var/log/nrlolsrv2.log"
cmd += " -rpipe %s_olsrv2" % node.name cmd += " -rpipe %s_olsrv2" % node.name
servicenames = map(lambda x: x.name, services) servicenames = map(lambda x: x.name, node.services)
if "SMF" in servicenames: if "SMF" in servicenames:
cmd += " -flooding ecds" cmd += " -flooding ecds"
cmd += " -smfClient %s_smf" % node.name cmd += " -smfClient %s_smf" % node.name
@ -236,7 +236,7 @@ class OlsrOrg(NrlService):
validate = ("pidof olsrd",) validate = ("pidof olsrd",)
@classmethod @classmethod
def getstartup(cls, node, services): def getstartup(cls, node):
""" """
Generate the appropriate command-line based on node interfaces. Generate the appropriate command-line based on node interfaces.
""" """
@ -250,7 +250,7 @@ class OlsrOrg(NrlService):
return cmd, return cmd,
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
""" """
Generate a default olsrd config file to use the broadcast address of 255.255.255.255. Generate a default olsrd config file to use the broadcast address of 255.255.255.255.
""" """
@ -598,7 +598,7 @@ class MgenActor(NrlService):
shutdown = ("killall mgen",) shutdown = ("killall mgen",)
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
""" """
Generate a startup script for MgenActor. Because mgenActor does not Generate a startup script for MgenActor. Because mgenActor does not
daemonize, it can cause problems in some situations when launched daemonize, it can cause problems in some situations when launched
@ -609,7 +609,7 @@ class MgenActor(NrlService):
comments = "" comments = ""
cmd = "mgenBasicActor.py -n %s -a 0.0.0.0" % node.name cmd = "mgenBasicActor.py -n %s -a 0.0.0.0" % node.name
servicenames = map(lambda x: x.name, services) servicenames = map(lambda x: x.name, node.services)
netifs = filter(lambda x: not getattr(x, 'control', False), node.netifs()) netifs = filter(lambda x: not getattr(x, 'control', False), node.netifs())
if len(netifs) == 0: if len(netifs) == 0:
return "" return ""
@ -631,7 +631,7 @@ class Arouted(NrlService):
validate = ("pidof arouted",) validate = ("pidof arouted",)
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
""" """
Return the Quagga.conf or quaggaboot.sh file contents. Return the Quagga.conf or quaggaboot.sh file contents.
""" """

View file

@ -24,29 +24,28 @@ class Zebra(CoreService):
validate = ("pidof zebra",) validate = ("pidof zebra",)
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
""" """
Return the Quagga.conf or quaggaboot.sh file contents. Return the Quagga.conf or quaggaboot.sh file contents.
""" """
if filename == cls.configs[0]: if filename == cls.configs[0]:
return cls.generateQuaggaConf(node, services) return cls.generateQuaggaConf(node)
elif filename == cls.configs[1]: elif filename == cls.configs[1]:
return cls.generateQuaggaBoot(node, services) return cls.generateQuaggaBoot(node)
elif filename == cls.configs[2]: elif filename == cls.configs[2]:
return cls.generateVtyshConf(node, services) return cls.generateVtyshConf(node)
else: else:
raise ValueError("file name (%s) is not a known configuration: %s", raise ValueError("file name (%s) is not a known configuration: %s", filename, cls.configs)
filename, cls.configs)
@classmethod @classmethod
def generateVtyshConf(cls, node, services): def generateVtyshConf(cls, node):
""" """
Returns configuration file text. Returns configuration file text.
""" """
return "service integrated-vtysh-config\n" return "service integrated-vtysh-config\n"
@classmethod @classmethod
def generateQuaggaConf(cls, node, services): def generateQuaggaConf(cls, node):
""" """
Returns configuration file text. Other services that depend on zebra Returns configuration file text. Other services that depend on zebra
will have generatequaggaifcconfig() and generatequaggaconfig() will have generatequaggaifcconfig() and generatequaggaconfig()
@ -66,7 +65,7 @@ class Zebra(CoreService):
cfgv6 = "" cfgv6 = ""
want_ipv4 = False want_ipv4 = False
want_ipv6 = False want_ipv6 = False
for s in services: for s in node.services:
if cls.name not in s.depends: if cls.name not in s.depends:
continue continue
ifccfg = s.generatequaggaifcconfig(node, ifc) ifccfg = s.generatequaggaifcconfig(node, ifc)
@ -92,7 +91,7 @@ class Zebra(CoreService):
cfg += cfgv6 cfg += cfgv6
cfg += "!\n" cfg += "!\n"
for s in services: for s in node.services:
if cls.name not in s.depends: if cls.name not in s.depends:
continue continue
cfg += s.generatequaggaconfig(node) cfg += s.generatequaggaconfig(node)
@ -111,7 +110,7 @@ class Zebra(CoreService):
raise ValueError("invalid address: %s", x) raise ValueError("invalid address: %s", x)
@classmethod @classmethod
def generateQuaggaBoot(cls, node, services): def generateQuaggaBoot(cls, node):
""" """
Generate a shell script used to boot the Quagga daemons. Generate a shell script used to boot the Quagga daemons.
""" """
@ -263,7 +262,7 @@ class QuaggaService(CoreService):
return False return False
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
return "" return ""
@classmethod @classmethod

View file

@ -15,7 +15,7 @@ class SdnService(CoreService):
startindex = 50 startindex = 50
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
return "" return ""
@ -31,16 +31,16 @@ class OvsService(SdnService):
shutdown = ('killall ovs-vswitchd', 'killall ovsdb-server') shutdown = ('killall ovs-vswitchd', 'killall ovsdb-server')
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
# Check whether the node is running zebra # Check whether the node is running zebra
has_zebra = 0 has_zebra = 0
for s in services: for s in node.services:
if s.name == "zebra": if s.name == "zebra":
has_zebra = 1 has_zebra = 1
# Check whether the node is running an SDN controller # Check whether the node is running an SDN controller
has_sdn_ctrlr = 0 has_sdn_ctrlr = 0
for s in services: for s in node.services:
if s.name == "ryuService": if s.name == "ryuService":
has_sdn_ctrlr = 1 has_sdn_ctrlr = 1
@ -106,7 +106,7 @@ class RyuService(SdnService):
shutdown = ('killall ryu-manager',) shutdown = ('killall ryu-manager',)
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
""" """
Return a string that will be written to filename, or sent to the Return a string that will be written to filename, or sent to the
GUI for user customization. GUI for user customization.

View file

@ -19,7 +19,7 @@ class VPNClient(CoreService):
custom_needed = True custom_needed = True
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
""" """
Return the client.conf and vpnclient.sh file contents to Return the client.conf and vpnclient.sh file contents to
""" """
@ -46,7 +46,7 @@ class VPNServer(CoreService):
custom_needed = True custom_needed = True
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
""" """
Return the sample server.conf and vpnserver.sh file contents to Return the sample server.conf and vpnserver.sh file contents to
GUI for user customization. GUI for user customization.
@ -73,7 +73,7 @@ class IPsec(CoreService):
custom_needed = True custom_needed = True
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
""" """
Return the ipsec.conf and racoon.conf file contents to Return the ipsec.conf and racoon.conf file contents to
GUI for user customization. GUI for user customization.
@ -100,7 +100,7 @@ class Firewall(CoreService):
custom_needed = True custom_needed = True
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
""" """
Return the firewall rule examples to GUI for user customization. Return the firewall rule examples to GUI for user customization.
""" """

View file

@ -20,23 +20,23 @@ class Ucarp(CoreService):
validate = ("pidof ucarp",) validate = ("pidof ucarp",)
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
""" """
Return the default file contents Return the default file contents
""" """
if filename == cls.configs[0]: if filename == cls.configs[0]:
return cls.generateUcarpConf(node, services) return cls.generateUcarpConf(node)
elif filename == cls.configs[1]: elif filename == cls.configs[1]:
return cls.generateVipUp(node, services) return cls.generateVipUp(node)
elif filename == cls.configs[2]: elif filename == cls.configs[2]:
return cls.generateVipDown(node, services) return cls.generateVipDown(node)
elif filename == cls.configs[3]: elif filename == cls.configs[3]:
return cls.generateUcarpBoot(node, services) return cls.generateUcarpBoot(node)
else: else:
raise ValueError raise ValueError
@classmethod @classmethod
def generateUcarpConf(cls, node, services): def generateUcarpConf(cls, node):
""" """
Returns configuration file text. Returns configuration file text.
""" """
@ -105,7 +105,7 @@ ${UCARP_EXEC} -B ${UCARP_OPTS}
""" % (ucarp_bin, UCARP_ETC) """ % (ucarp_bin, UCARP_ETC)
@classmethod @classmethod
def generateUcarpBoot(cls, node, services): def generateUcarpBoot(cls, node):
""" """
Generate a shell script used to boot the Ucarp daemons. Generate a shell script used to boot the Ucarp daemons.
""" """
@ -127,7 +127,7 @@ ${UCARP_CFGDIR}/default.sh
""" % UCARP_ETC """ % UCARP_ETC
@classmethod @classmethod
def generateVipUp(cls, node, services): def generateVipUp(cls, node):
""" """
Generate a shell script used to start the virtual ip Generate a shell script used to start the virtual ip
""" """
@ -154,7 +154,7 @@ fi
""" """
@classmethod @classmethod
def generateVipDown(cls, node, services): def generateVipDown(cls, node):
""" """
Generate a shell script used to stop the virtual ip Generate a shell script used to stop the virtual ip
""" """

View file

@ -26,7 +26,7 @@ class UtilService(CoreService):
shutdown = () shutdown = ()
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
return "" return ""
@ -37,14 +37,14 @@ class IPForwardService(UtilService):
startup = ("sh ipforward.sh",) startup = ("sh ipforward.sh",)
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
if os.uname()[0] == "Linux": if os.uname()[0] == "Linux":
return cls.generateconfiglinux(node, filename, services) return cls.generateconfiglinux(node, filename)
else: else:
raise Exception("unknown platform") raise Exception("unknown platform")
@classmethod @classmethod
def generateconfiglinux(cls, node, filename, services): def generateconfiglinux(cls, node, filename):
cfg = """\ cfg = """\
#!/bin/sh #!/bin/sh
# auto-generated by IPForward service (utility.py) # auto-generated by IPForward service (utility.py)
@ -72,7 +72,7 @@ class DefaultRouteService(UtilService):
startup = ("sh defaultroute.sh",) startup = ("sh defaultroute.sh",)
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
cfg = "#!/bin/sh\n" cfg = "#!/bin/sh\n"
cfg += "# auto-generated by DefaultRoute service (utility.py)\n" cfg += "# auto-generated by DefaultRoute service (utility.py)\n"
for ifc in node.netifs(): for ifc in node.netifs():
@ -106,7 +106,7 @@ class DefaultMulticastRouteService(UtilService):
startup = ("sh defaultmroute.sh",) startup = ("sh defaultmroute.sh",)
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
cfg = "#!/bin/sh\n" cfg = "#!/bin/sh\n"
cfg += "# auto-generated by DefaultMulticastRoute service (utility.py)\n" cfg += "# auto-generated by DefaultMulticastRoute service (utility.py)\n"
cfg += "# the first interface is chosen below; please change it " cfg += "# the first interface is chosen below; please change it "
@ -132,7 +132,7 @@ class StaticRouteService(UtilService):
custom_needed = True custom_needed = True
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
cfg = "#!/bin/sh\n" cfg = "#!/bin/sh\n"
cfg += "# auto-generated by StaticRoute service (utility.py)\n#\n" cfg += "# auto-generated by StaticRoute service (utility.py)\n#\n"
cfg += "# NOTE: this service must be customized to be of any use\n" cfg += "# NOTE: this service must be customized to be of any use\n"
@ -173,7 +173,7 @@ class SshService(UtilService):
validate = () validate = ()
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
""" """
Use a startup script for launching sshd in order to wait for host Use a startup script for launching sshd in order to wait for host
key generation. key generation.
@ -241,7 +241,7 @@ class DhcpService(UtilService):
validate = ("pidof dhcpd",) validate = ("pidof dhcpd",)
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
""" """
Generate a dhcpd config file using the network address of Generate a dhcpd config file using the network address of
each interface. each interface.
@ -303,7 +303,7 @@ class DhcpClientService(UtilService):
validate = ("pidof dhclient",) validate = ("pidof dhclient",)
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
""" """
Generate a script to invoke dhclient on all interfaces. Generate a script to invoke dhclient on all interfaces.
""" """
@ -314,7 +314,7 @@ class DhcpClientService(UtilService):
cfg += "#mkdir -p /var/run/resolvconf/interface\n" cfg += "#mkdir -p /var/run/resolvconf/interface\n"
for ifc in node.netifs(): for ifc in node.netifs():
if hasattr(ifc, 'control') and ifc.control == True: if hasattr(ifc, 'control') and ifc.control is True:
continue continue
cfg += "#ln -s /var/run/resolvconf/interface/%s.dhclient" % ifc.name cfg += "#ln -s /var/run/resolvconf/interface/%s.dhclient" % ifc.name
cfg += " /var/run/resolvconf/resolv.conf\n" cfg += " /var/run/resolvconf/resolv.conf\n"
@ -335,7 +335,7 @@ class FtpService(UtilService):
validate = ("pidof vsftpd",) validate = ("pidof vsftpd",)
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
""" """
Generate a vsftpd.conf configuration file. Generate a vsftpd.conf configuration file.
""" """
@ -371,16 +371,16 @@ class HttpService(UtilService):
APACHEVER22, APACHEVER24 = (22, 24) APACHEVER22, APACHEVER24 = (22, 24)
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
""" """
Generate an apache2.conf configuration file. Generate an apache2.conf configuration file.
""" """
if filename == cls.configs[0]: if filename == cls.configs[0]:
return cls.generateapache2conf(node, filename, services) return cls.generateapache2conf(node, filename)
elif filename == cls.configs[1]: elif filename == cls.configs[1]:
return cls.generateenvvars(node, filename, services) return cls.generateenvvars(node, filename)
elif filename == cls.configs[2]: elif filename == cls.configs[2]:
return cls.generatehtml(node, filename, services) return cls.generatehtml(node, filename)
else: else:
return "" return ""
@ -400,7 +400,7 @@ class HttpService(UtilService):
return cls.APACHEVER22 return cls.APACHEVER22
@classmethod @classmethod
def generateapache2conf(cls, node, filename, services): def generateapache2conf(cls, node, filename):
lockstr = {cls.APACHEVER22: lockstr = {cls.APACHEVER22:
'LockFile ${APACHE_LOCK_DIR}/accept.lock\n', 'LockFile ${APACHE_LOCK_DIR}/accept.lock\n',
cls.APACHEVER24: cls.APACHEVER24:
@ -538,7 +538,7 @@ TraceEnable Off
return cfg return cfg
@classmethod @classmethod
def generateenvvars(cls, node, filename, services): def generateenvvars(cls, node, filename):
return """\ return """\
# this file is used by apache2ctl - generated by utility.py:HttpService # this file is used by apache2ctl - generated by utility.py:HttpService
# these settings come from a default Ubuntu apache2 installation # these settings come from a default Ubuntu apache2 installation
@ -553,7 +553,7 @@ export LANG
""" """
@classmethod @classmethod
def generatehtml(cls, node, filename, services): def generatehtml(cls, node, filename):
body = """\ body = """\
<!-- generated by utility.py:HttpService --> <!-- generated by utility.py:HttpService -->
<h1>%s web server</h1> <h1>%s web server</h1>
@ -581,7 +581,7 @@ class PcapService(UtilService):
meta = "logs network traffic to pcap packet capture files" meta = "logs network traffic to pcap packet capture files"
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
""" """
Generate a startpcap.sh traffic logging script. Generate a startpcap.sh traffic logging script.
""" """
@ -619,7 +619,7 @@ class RadvdService(UtilService):
validate = ("pidof radvd",) validate = ("pidof radvd",)
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
""" """
Generate a RADVD router advertisement daemon config file Generate a RADVD router advertisement daemon config file
using the network address of each interface. using the network address of each interface.
@ -678,7 +678,7 @@ class AtdService(UtilService):
shutdown = ("pkill atd",) shutdown = ("pkill atd",)
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
return """ return """
#!/bin/sh #!/bin/sh
echo 00001 > /var/spool/cron/atjobs/.SEQ echo 00001 > /var/spool/cron/atjobs/.SEQ

View file

@ -23,7 +23,7 @@ class XorpRtrmgr(CoreService):
validate = ("pidof xorp_rtrmgr",) validate = ("pidof xorp_rtrmgr",)
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
""" """
Returns config.boot configuration file text. Other services that Returns config.boot configuration file text. Other services that
depend on this will have generatexorpconfig() hooks that are depend on this will have generatexorpconfig() hooks that are
@ -39,7 +39,7 @@ class XorpRtrmgr(CoreService):
cfg += " }\n" cfg += " }\n"
cfg += "}\n\n" cfg += "}\n\n"
for s in services: for s in node.services:
try: try:
s.depends.index(cls.name) s.depends.index(cls.name)
cfg += s.generatexorpconfig(node) cfg += s.generatexorpconfig(node)
@ -154,7 +154,7 @@ class XorpService(CoreService):
return "0.0.0.0" return "0.0.0.0"
@classmethod @classmethod
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename):
return "" return ""
@classmethod @classmethod