refactored service function names
This commit is contained in:
parent
0efcd910db
commit
8186f3716c
14 changed files with 127 additions and 115 deletions
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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 """\
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue