refactored service function names

This commit is contained in:
Blake J. Harnden 2018-06-22 14:41:06 -07:00
parent 0efcd910db
commit 8186f3716c
14 changed files with 127 additions and 115 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(node, service_name, file_name) file_data = self.session.services.get_service_file(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
@ -1162,7 +1162,7 @@ class CoreHandler(SocketServer.BaseRequestHandler):
# dirs, configs, startindex, startup, shutdown, metadata, config # dirs, configs, startindex, startup, shutdown, metadata, config
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.get_service(node_id, service_name, default_service=True)
values = ServiceShim.tovaluelist(node, service) values = ServiceShim.tovaluelist(node, service)
captions = None captions = None
possible_values = None possible_values = None
@ -1199,7 +1199,7 @@ class CoreHandler(SocketServer.BaseRequestHandler):
logger.info(error_message) logger.info(error_message)
return None return None
key = values.pop(0) key = values.pop(0)
self.session.services.defaultservices[key] = values self.session.services.default_services[key] = values
logger.debug("default services for type %s set to %s", key, values) logger.debug("default services for type %s set to %s", key, values)
elif node_id: elif node_id:
services = ServiceShim.servicesfromopaque(opaque) services = ServiceShim.servicesfromopaque(opaque)
@ -1207,10 +1207,10 @@ class CoreHandler(SocketServer.BaseRequestHandler):
service_name = services[0] service_name = services[0]
# set custom service for node # set custom service for node
self.session.services.setcustomservice(node_id, service_name) self.session.services.set_service(node_id, service_name)
# set custom values for custom service # set custom values for custom service
service = self.session.services.getcustomservice(node_id, service_name) service = self.session.services.get_service(node_id, service_name)
if not service: if not service:
raise ValueError("custom service(%s) for node(%s) does not exist", service_name, node_id) raise ValueError("custom service(%s) for node(%s) does not exist", service_name, node_id)
@ -1359,7 +1359,7 @@ class CoreHandler(SocketServer.BaseRequestHandler):
if file_type is not None: if file_type is not None:
if file_type.startswith("service:"): if file_type.startswith("service:"):
_, service_name = file_type.split(':')[:2] _, service_name = file_type.split(':')[:2]
self.session.services.setservicefile(node_num, service_name, file_name, data) self.session.services.set_service_file(node_num, service_name, file_name, data)
return () return ()
elif file_type.startswith("hook:"): elif file_type.startswith("hook:"):
_, state = file_type.split(':')[:2] _, state = file_type.split(':')[:2]
@ -1520,13 +1520,13 @@ class CoreHandler(SocketServer.BaseRequestHandler):
unknown = [] unknown = []
services = ServiceShim.servicesfromopaque(name) services = ServiceShim.servicesfromopaque(name)
for service_name in services: for service_name in services:
service = self.session.services.getcustomservice(node_id, service_name, default_service=True) service = self.session.services.get_service(node_id, service_name, default_service=True)
if not service: if not service:
unknown.append(service_name) unknown.append(service_name)
continue continue
if event_type == EventTypes.STOP.value or event_type == EventTypes.RESTART.value: if event_type == EventTypes.STOP.value or event_type == EventTypes.RESTART.value:
status = self.session.services.stopnodeservice(node, service) status = self.session.services.stop_node_service(node, service)
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:
@ -1534,7 +1534,7 @@ class CoreHandler(SocketServer.BaseRequestHandler):
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) status = self.session.services.validate_node_service(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:
@ -1719,7 +1719,7 @@ class CoreHandler(SocketServer.BaseRequestHandler):
self.session.broadcast_config(config_data) self.session.broadcast_config(config_data)
# service customizations # service customizations
service_configs = self.session.services.getallconfigs() service_configs = self.session.services.all_configs()
for node_id, service in service_configs: for node_id, service in service_configs:
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)))
@ -1737,7 +1737,7 @@ class CoreHandler(SocketServer.BaseRequestHandler):
) )
self.session.broadcast_config(config_data) self.session.broadcast_config(config_data)
for file_name, config_data in self.session.services.getallfiles(service): for file_name, config_data in self.session.services.all_files(service):
file_data = FileData( file_data = FileData(
message_type=MessageFlags.ADD.value, message_type=MessageFlags.ADD.value,
node=node_id, node=node_id,

View file

@ -126,7 +126,7 @@ class EmuSession(Session):
self.node_id_gen = IdGen() self.node_id_gen = IdGen()
# set default services # set default services
self.services.defaultservices = { self.services.default_services = {
"mdr": ("zebra", "OSPFv3MDR", "IPForward"), "mdr": ("zebra", "OSPFv3MDR", "IPForward"),
"PC": ("DefaultRoute",), "PC": ("DefaultRoute",),
"prouter": ("zebra", "OSPFv2", "OSPFv3", "IPForward"), "prouter": ("zebra", "OSPFv2", "OSPFv3", "IPForward"),
@ -508,14 +508,14 @@ class EmuSession(Session):
if _type in [NodeTypes.DEFAULT, NodeTypes.PHYSICAL]: if _type in [NodeTypes.DEFAULT, NodeTypes.PHYSICAL]:
node.type = node_options.model node.type = node_options.model
logger.debug("set node type: %s", node.type) logger.debug("set node type: %s", node.type)
self.services.addservicestonode(node, node.type, node_options.services) self.services.add_services(node, node.type, node_options.services)
# boot nodes if created after runtime, LcxNodes, Physical, and RJ45 are all PyCoreNodes # boot nodes if created after runtime, LcxNodes, Physical, and RJ45 are all PyCoreNodes
is_boot_node = isinstance(node, PyCoreNode) and not nodeutils.is_node(node, NodeTypes.RJ45) is_boot_node = isinstance(node, PyCoreNode) and not nodeutils.is_node(node, NodeTypes.RJ45)
if self.state == EventTypes.RUNTIME_STATE.value and is_boot_node: if self.state == EventTypes.RUNTIME_STATE.value and is_boot_node:
self.write_objects() self.write_objects()
self.add_remove_control_interface(node=node, remove=False) self.add_remove_control_interface(node=node, remove=False)
self.services.bootnodeservices(node) self.services.boot_node_services(node)
return node return node

View file

@ -206,18 +206,18 @@ class CoreServices(object):
""" """
self.session = session self.session = session
# dict of default services tuples, key is node type # dict of default services tuples, key is node type
self.defaultservices = {} self.default_services = {}
# dict of tuple of service objects, key is node number # dict of node ids to dict of custom services by name
self.customservices = {} self.custom_services = {}
def reset(self): def reset(self):
""" """
Called when config message with reset flag is received Called when config message with reset flag is received
""" """
self.defaultservices.clear() self.default_services.clear()
self.customservices.clear() self.custom_services.clear()
def node_service_dependencies(self, services): def node_boot_paths(self, services):
# generate service map and find starting points # generate service map and find starting points
node_services = {service.name: service for service in services} node_services = {service.name: service for service in services}
is_dependency = set() is_dependency = set()
@ -280,11 +280,11 @@ class CoreServices(object):
stack.pop() stack.pop()
if visited != all_services: if visited != all_services:
raise ValueError("cycle encountered, services are being skipped") raise ValueError("failure to visit all services for boot path")
return startups return startups
def getdefaultservices(self, node_type): def get_default_services(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.
@ -295,7 +295,7 @@ class CoreServices(object):
""" """
logger.debug("getting default services for type: %s", node_type) logger.debug("getting default services for type: %s", node_type)
results = [] results = []
defaults = self.defaultservices.get(node_type, []) defaults = self.default_services.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)
@ -305,7 +305,7 @@ class CoreServices(object):
results.append(service) results.append(service)
return results return results
def getcustomservice(self, node_id, service_name, default_service=False): def get_service(self, node_id, service_name, default_service=False):
""" """
Get any custom service configured for the given node that matches the specified service name. Get any custom service configured for the given node that matches the specified service name.
If no custom service is found, return the specified service. If no custom service is found, return the specified service.
@ -316,13 +316,13 @@ class CoreServices(object):
:return: custom service from the node :return: custom service from the node
:rtype: CoreService :rtype: CoreService
""" """
node_services = self.customservices.setdefault(node_id, {}) node_services = self.custom_services.setdefault(node_id, {})
default = None default = None
if default_service: if default_service:
default = ServiceManager.get(service_name) default = ServiceManager.get(service_name)
return node_services.get(service_name, default) return node_services.get(service_name, default)
def setcustomservice(self, node_id, service_name): def set_service(self, node_id, service_name):
""" """
Store service customizations in an instantiated service object Store service customizations in an instantiated service object
using a list of values that came from a config message. using a list of values that came from a config message.
@ -332,16 +332,16 @@ class CoreServices(object):
:return: nothing :return: nothing
""" """
logger.debug("setting custom service(%s) for node: %s", node_id, service_name) logger.debug("setting custom service(%s) for node: %s", node_id, service_name)
service = self.getcustomservice(node_id, service_name) service = self.get_service(node_id, service_name)
if not service: if not service:
service_class = ServiceManager.get(service_name) service_class = ServiceManager.get(service_name)
service = service_class() service = service_class()
# add the custom service to dict # add the custom service to dict
node_services = self.customservices.setdefault(node_id, {}) node_services = self.custom_services.setdefault(node_id, {})
node_services[service.name] = service node_services[service.name] = service
def addservicestonode(self, node, node_type, services=None): def add_services(self, node, node_type, services=None):
""" """
Add services to a node. Add services to a node.
@ -352,52 +352,53 @@ class CoreServices(object):
""" """
if not services: if not services:
logger.info("using default services for node(%s) type(%s)", node.name, node_type) logger.info("using default services for node(%s) type(%s)", node.name, node_type)
services = self.defaultservices.get(node_type, []) services = self.default_services.get(node_type, [])
logger.info("setting services for node(%s): %s", node.name, services) logger.info("setting services for node(%s): %s", node.name, services)
for service_name in services: for service_name in services:
service = self.getcustomservice(node.objid, service_name, default_service=True) service = self.get_service(node.objid, service_name, default_service=True)
if not service: if not service:
logger.warn("unknown service(%s) for node(%s)", service_name, node.name) logger.warn("unknown service(%s) for node(%s)", service_name, node.name)
continue continue
logger.info("adding service to node(%s): %s", node.name, service_name) logger.info("adding service to node(%s): %s", node.name, service_name)
node.addservice(service) node.addservice(service)
def getallconfigs(self): def all_configs(self):
""" """
Return (nodenum, service) tuples for all stored configs. Used when reconnecting to a Return (node_id, service) tuples for all stored configs. Used when reconnecting to a
session or opening XML. session or opening XML.
:return: list of tuples of node ids and services :return: list of tuples of node ids and services
:rtype: list :rtype: list[tuple]
""" """
configs = [] configs = []
for node_id in self.customservices.iterkeys(): for node_id in self.custom_services.iterkeys():
for service in self.customservices[node_id].itervalues(): for service in self.custom_services[node_id].itervalues():
configs.append((node_id, service)) configs.append((node_id, service))
return configs return configs
def getallfiles(self, service): def all_files(self, service):
""" """
Return all customized files stored with a service. Return all customized files stored with a service.
Used when reconnecting to a session or opening XML. Used when reconnecting to a session or opening XML.
:param CoreService service: service to get files for :param CoreService service: service to get files for
:return: :return: list of all custom service files
:rtype: list[tuple]
""" """
files = [] files = []
if not service.custom: if not service.custom:
return files return files
for filename in service.configs: for filename in service.configs:
data = service.configtxt.get(filename) data = service.config_data.get(filename)
if data is None: if data is None:
continue continue
files.append((filename, data)) files.append((filename, data))
return files return files
def bootnodeservices(self, node): def boot_node_services(self, node):
""" """
Start all services on a node. Start all services on a node.
@ -407,9 +408,9 @@ class CoreServices(object):
pool = ThreadPool() pool = ThreadPool()
results = [] results = []
boot_paths = self.node_service_dependencies(node.services) boot_paths = self.node_boot_paths(node.services)
for boot_path in boot_paths: for boot_path in boot_paths:
result = pool.apply_async(self.boot_node_dependencies, (node, boot_path)) result = pool.apply_async(self._boot_node_paths, (node, boot_path))
results.append(result) results.append(result)
pool.close() pool.close()
@ -417,12 +418,19 @@ class CoreServices(object):
for result in results: for result in results:
result.get() result.get()
def boot_node_dependencies(self, node, boot_path): def _boot_node_paths(self, node, boot_path):
"""
Start all service boot paths found, based on dependencies.
:param core.netns.vnode.LxcNode node: node to start services on
:param list[CoreService] boot_path: service to start in dependent order
:return: nothing
"""
logger.debug("booting node service dependencies: %s", boot_path) logger.debug("booting node service dependencies: %s", boot_path)
for service in boot_path: for service in boot_path:
self.bootnodeservice(node, service) self.boot_node_service(node, service)
def bootnodeservice(self, node, service): def boot_node_service(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.
@ -453,11 +461,11 @@ 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) status = self.validate_node_service(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))
def copyservicefile(self, node, filename, cfg): def copy_service_file(self, node, filename, cfg):
""" """
Given a configured service filename and config, determine if the Given a configured service filename and config, determine if the
config references an existing file that should be copied. config references an existing file that should be copied.
@ -478,7 +486,7 @@ class CoreServices(object):
return True return True
return False return False
def validatenodeservice(self, node, service): def validate_node_service(self, node, service):
""" """
Run the validation command(s) for a service. Run the validation command(s) for a service.
@ -503,7 +511,7 @@ class CoreServices(object):
return status return status
def stopnodeservices(self, node): def stop_node_services(self, node):
""" """
Stop all services on a node. Stop all services on a node.
@ -511,9 +519,9 @@ class CoreServices(object):
:return: nothing :return: nothing
""" """
for service in node.services: for service in node.services:
self.stopnodeservice(node, service) self.stop_node_service(node, service)
def stopnodeservice(self, node, service): def stop_node_service(self, node, service):
""" """
Stop a service on a node. Stop a service on a node.
@ -531,7 +539,7 @@ class CoreServices(object):
status = -1 status = -1
return status return status
def getservicefile(self, node, service_name, filename): def get_service_file(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.
@ -542,7 +550,7 @@ class CoreServices(object):
:return: file message for node :return: file message for node
""" """
# get service to get file from # get service to get file from
service = self.getcustomservice(node.objid, service_name, default_service=True) service = self.get_service(node.objid, service_name, default_service=True)
if not service: if not service:
raise ValueError("invalid service: %s", service_name) raise ValueError("invalid service: %s", service_name)
@ -556,7 +564,7 @@ class CoreServices(object):
raise ValueError("unknown service(%s) config file: %s", service_name, filename) raise ValueError("unknown service(%s) config file: %s", service_name, filename)
# get the file data # get the file data
data = service.configtxt.get(filename) data = service.config_data.get(filename)
if data is None: if data is None:
data = "%s" % service.generateconfig(node, filename) data = "%s" % service.generateconfig(node, filename)
else: else:
@ -571,7 +579,7 @@ class CoreServices(object):
data=data data=data
) )
def setservicefile(self, node_id, service_name, filename, data): def set_service_file(self, node_id, service_name, filename, data):
""" """
Receive a File Message from the GUI and store the customized file Receive a File Message from the GUI and store the customized file
in the service config. The filename must match one from the list of in the service config. The filename must match one from the list of
@ -584,10 +592,10 @@ class CoreServices(object):
:return: nothing :return: nothing
""" """
# attempt to set custom service, if needed # attempt to set custom service, if needed
self.setcustomservice(node_id, service_name) self.set_service(node_id, service_name)
# retrieve custom service # retrieve custom service
service = self.getcustomservice(node_id, service_name) service = self.get_service(node_id, service_name)
if service is None: if service is None:
logger.warn("received filename for unknown service: %s", service_name) logger.warn("received filename for unknown service: %s", service_name)
return return
@ -599,7 +607,7 @@ class CoreServices(object):
return return
# set custom service file data # set custom service file data
service.configtxt[filename] = data service.config_data[filename] = data
def node_service_startup(self, node, service, wait=False): def node_service_startup(self, node, service, wait=False):
""" """
@ -645,13 +653,13 @@ class CoreServices(object):
for file_name in file_names: for file_name in file_names:
logger.debug("generating service config: %s", file_name) logger.debug("generating service config: %s", file_name)
if service.custom: if service.custom:
cfg = service.configtxt.get(file_name) cfg = service.config_data.get(file_name)
if cfg is None: if cfg is None:
cfg = service.generateconfig(node, file_name) 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:
if self.copyservicefile(node, file_name, cfg): if self.copy_service_file(node, file_name, cfg):
continue continue
except IOError: except IOError:
logger.exception("error copying service file: %s", file_name) logger.exception("error copying service file: %s", file_name)
@ -678,7 +686,7 @@ class CoreServices(object):
# TODO: implement this # TODO: implement this
raise NotImplementedError raise NotImplementedError
cfg = service.configtxt.get(file_name) cfg = service.config_data.get(file_name)
if cfg is None: if cfg is None:
cfg = service.generateconfig(node, file_name) cfg = service.generateconfig(node, file_name)
@ -707,6 +715,9 @@ class CoreService(object):
# config files written by this service # config files written by this service
configs = () configs = ()
# config file data
config_data = {}
# list of startup commands # list of startup commands
startup = () startup = ()
@ -726,7 +737,6 @@ class CoreService(object):
meta = None meta = None
# custom configuration text # custom configuration text
configtxt = {}
custom = False custom = False
custom_needed = False custom_needed = False
@ -743,7 +753,7 @@ class CoreService(object):
self.shutdown = self.__class__.shutdown self.shutdown = self.__class__.shutdown
self.validate = self.__class__.validate self.validate = self.__class__.validate
self.meta = self.__class__.meta self.meta = self.__class__.meta
self.configtxt = self.__class__.configtxt self.config_data = self.__class__.config_data
@classmethod @classmethod
def on_load(cls): def on_load(cls):
@ -766,8 +776,7 @@ class CoreService(object):
def generateconfig(cls, node, filename): 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.
provided to allow interdependencies (e.g. zebra and OSPF).
Return the configuration string to be written to a file or sent Return the configuration string to be written to a file or sent
to the GUI for customization. to the GUI for customization.
@ -781,7 +790,7 @@ class CoreService(object):
def getstartup(cls, node): 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
overridden to provide node-specific commands that may be overridden to provide node-specific commands that may be
based on other services. based on other services.
@ -795,8 +804,8 @@ class CoreService(object):
def getvalidate(cls, node): 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
overriden to provide node-specific commands that may be overridden to provide node-specific commands that may be
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

View file

@ -673,7 +673,7 @@ class Session(object):
for obj in self.objects.itervalues(): for obj in self.objects.itervalues():
# TODO: determine if checking for CoreNode alone is ok # TODO: determine if checking for CoreNode alone is ok
if isinstance(obj, nodes.PyCoreNode): if isinstance(obj, nodes.PyCoreNode):
self.services.stopnodeservices(obj) self.services.stop_node_services(obj)
# shutdown emane # shutdown emane
self.emane.shutdown() self.emane.shutdown()
@ -727,7 +727,7 @@ class Session(object):
# add a control interface if configured # add a control interface if configured
logger.info("booting node: %s", obj.name) logger.info("booting node: %s", obj.name)
self.add_remove_control_interface(node=obj, remove=False) self.add_remove_control_interface(node=obj, remove=False)
result = pool.apply_async(self.services.bootnodeservices, (obj,)) result = pool.apply_async(self.services.boot_node_services, (obj,))
results.append(result) results.append(result)
pool.close() pool.close()

View file

@ -279,7 +279,7 @@ class CoreDocumentParser0(object):
services = [] services = []
for service in node.getElementsByTagName("Service"): for service in node.getElementsByTagName("Service"):
services.append(str(service.getAttribute("name"))) services.append(str(service.getAttribute("name")))
self.session.services.defaultservices[type] = services self.session.services.default_services[type] = services
logger.info("default services for type %s set to %s" % (type, services)) logger.info("default services for type %s set to %s" % (type, services))
def parseservices(self): def parseservices(self):
@ -319,7 +319,7 @@ class CoreDocumentParser0(object):
services = svclists[objid] services = svclists[objid]
if services: if services:
services = services.split("|") services = services.split("|")
self.session.services.addservicestonode(node=n, node_type=n.type, services=services) self.session.services.add_services(node=n, node_type=n.type, services=services)
def parseservice(self, service, n): def parseservice(self, service, n):
""" """
@ -370,15 +370,15 @@ class CoreDocumentParser0(object):
filename = file.getAttribute("name") filename = file.getAttribute("name")
files.append(filename) files.append(filename)
data = xmlutils.get_text_child(file) data = xmlutils.get_text_child(file)
self.session.services.setservicefile(node_id=n.objid, service_name=name, filename=filename, data=data) self.session.services.set_service_file(node_id=n.objid, service_name=name, filename=filename, data=data)
if len(files): if len(files):
values.append("files=%s" % files) values.append("files=%s" % files)
if not bool(service.getAttribute("custom")): if not bool(service.getAttribute("custom")):
return True return True
self.session.services.setcustomservice(n.objid, svc) self.session.services.set_service(n.objid, svc)
# set custom values for custom service # set custom values for custom service
svc = self.session.services.getcustomservice(n.objid, None) svc = self.session.services.get_service(n.objid, None)
if not svc: if not svc:
raise ValueError("custom service(%s) for node(%s) does not exist", svc.name, n.objid) raise ValueError("custom service(%s) for node(%s) does not exist", svc.name, n.objid)
values = ConfigShim.str_to_dict("|".join(values)) values = ConfigShim.str_to_dict("|".join(values))

View file

@ -639,7 +639,7 @@ class CoreDocumentParser1(object):
custom = service.getAttribute('custom') custom = service.getAttribute('custom')
if custom and custom.lower() == 'true': if custom and custom.lower() == 'true':
self.session.services.setcustomservice(node.objid, session_service.name) self.session.services.set_service(node.objid, session_service.name)
values = ConfigShim.str_to_dict("|".join(values)) values = ConfigShim.str_to_dict("|".join(values))
for key, value in values.iteritems(): for key, value in values.iteritems():
ServiceShim.setvalue(session_service, key, value) ServiceShim.setvalue(session_service, key, value)
@ -648,7 +648,7 @@ class CoreDocumentParser1(object):
# called after the custom service exists # called after the custom service exists
for typestr, filename, data in files: for typestr, filename, data in files:
svcname = typestr.split(":")[1] svcname = typestr.split(":")[1]
self.session.services.setservicefile( self.session.services.set_service_file(
node_id=node.objid, node_id=node.objid,
service_name=svcname, service_name=svcname,
filename=filename, filename=filename,
@ -683,7 +683,7 @@ class CoreDocumentParser1(object):
if services_str: if services_str:
services_str = services_str.split("|") services_str = services_str.split("|")
self.session.services.addservicestonode( self.session.services.add_services(
node=node, node=node,
node_type=node_type, node_type=node_type,
services=services_str services=services_str
@ -885,5 +885,5 @@ class CoreDocumentParser1(object):
self.default_services[device_type] = services self.default_services[device_type] = services
# store default services for the session # store default services for the session
for t, s in self.default_services.iteritems(): for t, s in self.default_services.iteritems():
self.session.services.defaultservices[t] = s self.session.services.default_services[t] = s
logger.info('default services for node type \'%s\' set to: %s' % (t, s)) logger.info('default services for node type \'%s\' set to: %s' % (t, s))

View file

@ -276,8 +276,8 @@ class CoreDocumentWriter0(Document):
""" """
Add default services and node types to the ServicePlan. Add default services and node types to the ServicePlan.
""" """
for type in self.session.services.defaultservices: for type in self.session.services.default_services:
defaults = self.session.services.getdefaultservices(type) defaults = self.session.services.get_default_services(type)
spn = self.createElement("Node") spn = self.createElement("Node")
spn.setAttribute("type", type) spn.setAttribute("type", type)
self.sp.appendChild(spn) self.sp.appendChild(spn)
@ -292,7 +292,7 @@ class CoreDocumentWriter0(Document):
""" """
if len(node.services) == 0: if len(node.services) == 0:
return return
defaults = self.session.services.getdefaultservices(node.type) defaults = self.session.services.get_default_services(node.type)
if node.services == defaults: if node.services == defaults:
return return
spn = self.createElement("Node") spn = self.createElement("Node")
@ -316,7 +316,7 @@ class CoreDocumentWriter0(Document):
f.setAttribute("name", fn) f.setAttribute("name", fn)
# all file names are added to determine when a file has been deleted # all file names are added to determine when a file has been deleted
s.appendChild(f) s.appendChild(f)
data = self.session.services.getservicefiledata(svc, fn) data = svc.config_data.get(fn)
if data is None: if data is None:
# this includes only customized file contents and skips # this includes only customized file contents and skips
# the auto-generated files # the auto-generated files

View file

@ -269,8 +269,8 @@ class ScenarioPlan(XmlElement):
Add default services and node types to the ServicePlan. Add default services and node types to the ServicePlan.
""" """
defaultservices = self.createElement("CORE:defaultservices") defaultservices = self.createElement("CORE:defaultservices")
for type in self.coreSession.services.defaultservices: for type in self.coreSession.services.default_services:
defaults = self.coreSession.services.getdefaultservices(type) defaults = self.coreSession.services.get_default_services(type)
spn = self.createElement("device") spn = self.createElement("device")
spn.setAttribute("type", type) spn.setAttribute("type", type)
defaultservices.appendChild(spn) defaultservices.appendChild(spn)
@ -670,7 +670,7 @@ class DeviceElement(NamedXmlElement):
if len(device_object.services) == 0: if len(device_object.services) == 0:
return return
defaults = self.coreSession.services.getdefaultservices(device_object.type) defaults = self.coreSession.services.get_default_services(device_object.type)
if device_object.services == defaults: if device_object.services == defaults:
return return
spn = self.createElement("CORE:services") spn = self.createElement("CORE:services")

View file

@ -159,8 +159,8 @@ def main():
n.newnetif(switch, ["%s/%s" % (prefix.addr(i), prefix.prefixlen)]) n.newnetif(switch, ["%s/%s" % (prefix.addr(i), prefix.prefixlen)])
n.cmd([constants.SYSCTL_BIN, "net.ipv4.icmp_echo_ignore_broadcasts=0"]) n.cmd([constants.SYSCTL_BIN, "net.ipv4.icmp_echo_ignore_broadcasts=0"])
if options.services is not None: if options.services is not None:
session.services.addservicestonode(n, "", options.services.split("|")) session.services.add_services(n, "", options.services.split("|"))
session.services.bootnodeservices(n) session.services.boot_node_services(n)
nodelist.append(n) nodelist.append(n)
if i % 25 == 0: if i % 25 == 0:
print "\n%s nodes created " % i, print "\n%s nodes created " % i,

View file

@ -88,7 +88,7 @@ ip forwarding
def boot(self): def boot(self):
self.config() self.config()
self.session.services.bootnodeservices(self) self.session.services.boot_node_services(self)
def bootscript(self): def bootscript(self):
return """\ return """\

View file

@ -420,8 +420,8 @@ class Experiment(object):
tmp = self.session.add_object(cls=nodes.CoreNode, objid=i, name="n%d" % i) tmp = self.session.add_object(cls=nodes.CoreNode, objid=i, name="n%d" % i)
tmp.newnetif(self.net, [addr]) tmp.newnetif(self.net, [addr])
self.nodes.append(tmp) self.nodes.append(tmp)
self.session.services.addservicestonode(tmp, "router", "IPForward") self.session.services.add_services(tmp, "router", "IPForward")
self.session.services.bootnodeservices(tmp) self.session.services.boot_node_services(tmp)
self.staticroutes(i, prefix, numnodes) self.staticroutes(i, prefix, numnodes)
# link each node in a chain, with the previous node # link each node in a chain, with the previous node
@ -451,7 +451,7 @@ class Experiment(object):
tmp.setposition(50, 50, None) tmp.setposition(50, 50, None)
tmp.newnetif(self.net, [addr]) tmp.newnetif(self.net, [addr])
self.nodes.append(tmp) self.nodes.append(tmp)
self.session.services.addservicestonode(tmp, "router", "IPForward") self.session.services.add_services(tmp, "router", "IPForward")
if values is None: if values is None:
values = cls.getdefaultvalues() values = cls.getdefaultvalues()
@ -463,7 +463,7 @@ class Experiment(object):
for i in xrange(1, numnodes + 1): for i in xrange(1, numnodes + 1):
tmp = self.nodes[i - 1] tmp = self.nodes[i - 1]
self.session.services.bootnodeservices(tmp) self.session.services.boot_node_services(tmp)
self.staticroutes(i, prefix, numnodes) self.staticroutes(i, prefix, numnodes)
def setnodes(self): def setnodes(self):

View file

@ -48,18 +48,21 @@ class TestServices:
assert ServiceManager.get("MyService") assert ServiceManager.get("MyService")
assert ServiceManager.get("MyService2") assert ServiceManager.get("MyService2")
def test_service_defaults(self):
pass
def test_services_dependencies(self, session): def test_services_dependencies(self, session):
# given # given
services = [ services = [
ServiceA(), ServiceA,
ServiceB(), ServiceB,
ServiceC(), ServiceC,
ServiceD(), ServiceD,
ServiceF(), ServiceF,
] ]
# when # when
startups = session.services.node_service_dependencies(services) startups = session.services.node_boot_paths(services)
# then # then
assert len(startups) == 2 assert len(startups) == 2
@ -67,28 +70,28 @@ class TestServices:
def test_services_dependencies_not_present(self, session): def test_services_dependencies_not_present(self, session):
# given # given
services = [ services = [
ServiceA(), ServiceA,
ServiceB(), ServiceB,
ServiceC(), ServiceC,
ServiceE() ServiceE
] ]
# when # when
with pytest.raises(ValueError): with pytest.raises(ValueError):
session.services.node_service_dependencies(services) session.services.node_boot_paths(services)
def test_services_dependencies_cycle(self, session): def test_services_dependencies_cycle(self, session):
# given # given
service_c = ServiceC() service_c = ServiceC()
service_c.dependencies = ("D",) service_c.dependencies = ("D",)
services = [ services = [
ServiceA(), ServiceA,
ServiceB(), ServiceB,
service_c, service_c,
ServiceD(), ServiceD,
ServiceF() ServiceF
] ]
# when # when
with pytest.raises(ValueError): with pytest.raises(ValueError):
session.services.node_service_dependencies(services) session.services.node_boot_paths(services)

View file

@ -93,10 +93,10 @@ class TestXml:
session.add_link(node.objid, ptp_node.objid, interface_one=interface) session.add_link(node.objid, ptp_node.objid, interface_one=interface)
# set custom values for node service # set custom values for node service
session.services.setcustomservice(node_one.objid, SshService.name) session.services.set_service(node_one.objid, SshService.name)
service_file = SshService.configs[0] service_file = SshService.configs[0]
file_data = "# test" file_data = "# test"
session.services.setservicefile(node_one.objid, SshService.name, service_file, file_data) session.services.set_service_file(node_one.objid, SshService.name, service_file, file_data)
# instantiate session # instantiate session
session.instantiate() session.instantiate()
@ -127,12 +127,12 @@ class TestXml:
session.open_xml(file_path, start=True) session.open_xml(file_path, start=True)
# retrieve custom service # retrieve custom service
service = session.services.getcustomservice(node_one.objid, SshService.name) service = session.services.get_service(node_one.objid, SshService.name)
# verify nodes have been recreated # verify nodes have been recreated
assert session.get_object(n1_id) assert session.get_object(n1_id)
assert session.get_object(n2_id) assert session.get_object(n2_id)
assert service.configtxt.get(service_file) == file_data assert service.config_data.get(service_file) == file_data
@pytest.mark.parametrize("version", _XML_VERSIONS) @pytest.mark.parametrize("version", _XML_VERSIONS)
def test_xml_mobility(self, session, tmpdir, version, ip_prefixes): def test_xml_mobility(self, session, tmpdir, version, ip_prefixes):

View file

@ -60,8 +60,8 @@ def wifisession(opt):
node = session.addnode(name="n%d" % i) node = session.addnode(name="n%d" % i)
node.newnetif(wifi, ["%s/%s" % (prefix.addr(i), prefix.prefixlen)]) node.newnetif(wifi, ["%s/%s" % (prefix.addr(i), prefix.prefixlen)])
nodes.append(node) nodes.append(node)
session.services.addservicestonode(node, "router", services_str.split("|")) session.services.add_services(node, "router", services_str.split("|"))
session.services.bootnodeservices(node) session.services.boot_node_services(node)
session.setuprandomwalkmobility(bounds=(1000.0, 750.0, 0)) session.setuprandomwalkmobility(bounds=(1000.0, 750.0, 0))
# PHY tracing # PHY tracing