refactored configs back to be able to provide instance conifgurations for sessions
This commit is contained in:
parent
eb415aa4d4
commit
3a39432fc7
22 changed files with 560 additions and 319 deletions
|
@ -8,7 +8,6 @@ from core.enumerations import ConfigDataTypes
|
|||
|
||||
class EmaneBypassModel(emanemodel.EmaneModel):
|
||||
name = "emane_bypass"
|
||||
configuration_maps = {}
|
||||
|
||||
# values to ignore, when writing xml files
|
||||
config_ignore = {"none"}
|
||||
|
|
|
@ -29,7 +29,6 @@ def convert_none(x):
|
|||
|
||||
class EmaneCommEffectModel(emanemodel.EmaneModel):
|
||||
name = "emane_commeffect"
|
||||
configuration_maps = {}
|
||||
|
||||
shim_library = "commeffectshim"
|
||||
shim_xml = "/usr/share/emane/manifest/commeffectshim.xml"
|
||||
|
@ -55,7 +54,7 @@ class EmaneCommEffectModel(emanemodel.EmaneModel):
|
|||
:param interface: interface for the emane node
|
||||
:return: nothing
|
||||
"""
|
||||
config = self.getifcconfig(self.object_id, interface)
|
||||
config = emane_manager.getifcconfig(self.object_id, interface, self.name)
|
||||
if not config:
|
||||
return
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ from core import constants
|
|||
from core import logger
|
||||
from core.api import coreapi
|
||||
from core.api import dataconversion
|
||||
from core.conf import ConfigShim
|
||||
from core.conf import ConfigShim, ConfigurableManager
|
||||
from core.conf import Configuration
|
||||
from core.emane import emanemanifest
|
||||
from core.emane.bypass import EmaneBypassModel
|
||||
|
@ -53,7 +53,7 @@ EMANE_MODELS = [
|
|||
]
|
||||
|
||||
|
||||
class EmaneManager(object):
|
||||
class EmaneManager(ConfigurableManager):
|
||||
"""
|
||||
EMANE controller object. Lives in a Session instance and is used for
|
||||
building EMANE config files from all of the EmaneNode objects in this
|
||||
|
@ -73,6 +73,7 @@ class EmaneManager(object):
|
|||
:param core.session.Session session: session this manager is tied to
|
||||
:return: nothing
|
||||
"""
|
||||
super(EmaneManager, self).__init__()
|
||||
self.session = session
|
||||
self._emane_nodes = {}
|
||||
self._emane_node_lock = threading.Lock()
|
||||
|
@ -86,6 +87,7 @@ class EmaneManager(object):
|
|||
|
||||
# model for global EMANE configuration options
|
||||
self.emane_config = EmaneGlobalModel(session)
|
||||
self.set_configs(self.emane_config.default_values())
|
||||
|
||||
# store the last configured model for a node, used during startup
|
||||
self.node_models = {}
|
||||
|
@ -98,19 +100,106 @@ class EmaneManager(object):
|
|||
self.service = None
|
||||
self.emane_check()
|
||||
|
||||
def set_node_model(self, node_id, model_name):
|
||||
if model_name not in self._modelclsmap:
|
||||
raise ValueError("unknown emane model: %s", model_name)
|
||||
def set_model_config(self, node_id, model_name, config):
|
||||
"""
|
||||
Set configuration data for a model.
|
||||
|
||||
:param int node_id: node id to set model configuration for
|
||||
:param str model_name: model to set configuration for
|
||||
:param dict config: configuration data to set for model
|
||||
:return: nothing
|
||||
"""
|
||||
# get model class to configure
|
||||
model_class = self._modelclsmap.get(model_name)
|
||||
if not model_class:
|
||||
raise ValueError("%s is an invalid model" % model_name)
|
||||
|
||||
# retrieve default values
|
||||
node_config = self.get_model_config(node_id, model_name)
|
||||
for key, value in config.iteritems():
|
||||
node_config[key] = value
|
||||
|
||||
# set as node model for startup
|
||||
self.node_models[node_id] = model_name
|
||||
|
||||
def config_reset(self, node_id=None):
|
||||
# clear and reset current emane configuration
|
||||
self.emane_config.config_reset()
|
||||
self.emane_config.set_configs()
|
||||
# set configuration
|
||||
self.set_configs(node_config, node_id=node_id, config_type=model_name)
|
||||
|
||||
# reset model configurations
|
||||
for model_class in self._modelclsmap.itervalues():
|
||||
model_class.config_reset(node_id=node_id)
|
||||
def get_model_config(self, node_id, model_name):
|
||||
"""
|
||||
Set configuration data for a model.
|
||||
|
||||
:param int node_id: node id to set model configuration for
|
||||
:param str model_name: model to set configuration for
|
||||
:return: current model configuration for node
|
||||
:rtype: dict
|
||||
"""
|
||||
# get model class to configure
|
||||
model_class = self._modelclsmap.get(model_name)
|
||||
if not model_class:
|
||||
raise ValueError("%s is an invalid model" % model_name)
|
||||
|
||||
config = self.get_configs(node_id=node_id, config_type=model_name)
|
||||
if not config:
|
||||
# set default values, when not already set
|
||||
config = model_class.default_values()
|
||||
self.set_configs(config, node_id=node_id, config_type=model_name)
|
||||
|
||||
return config
|
||||
|
||||
def getifcconfig(self, node_id, interface, model_name):
|
||||
"""
|
||||
Retrieve interface configuration or node configuration if not provided.
|
||||
|
||||
:param int node_id: node id
|
||||
:param interface: node interface
|
||||
:param str model_name: model to get configuration for
|
||||
:return: node/interface model configuration
|
||||
:rtype: dict
|
||||
"""
|
||||
# use the network-wide config values or interface(NEM)-specific values?
|
||||
if interface is None:
|
||||
return self.get_configs(node_id=node_id, config_type=model_name)
|
||||
else:
|
||||
# don"t use default values when interface config is the same as net
|
||||
# note here that using ifc.node.objid as key allows for only one type
|
||||
# of each model per node;
|
||||
# TODO: use both node and interface as key
|
||||
|
||||
# Adamson change: first check for iface config keyed by "node:ifc.name"
|
||||
# (so that nodes w/ multiple interfaces of same conftype can have
|
||||
# different configs for each separate interface)
|
||||
key = 1000 * interface.node.objid
|
||||
if interface.netindex is not None:
|
||||
key += interface.netindex
|
||||
|
||||
# try retrieve interface specific configuration, avoid getting defaults
|
||||
config = {}
|
||||
if self.has_configs(key):
|
||||
config = self.get_configs(key)
|
||||
|
||||
# otherwise retrieve the interfaces node configuration, avoid using defaults
|
||||
if not config and self.has_configs(interface.node.objid):
|
||||
config = self.get_configs(node_id=interface.node.objid, config_type=model_name)
|
||||
|
||||
if not config and interface.transport_type == "raw":
|
||||
# with EMANE 0.9.2+, we need an extra NEM XML from
|
||||
# model.buildnemxmlfiles(), so defaults are returned here
|
||||
config = self.get_configs(node_id=node_id, config_type=model_name)
|
||||
|
||||
return config
|
||||
|
||||
def set_model(self, node, model_class, config=None):
|
||||
logger.info("setting emane model(%s) for node(%s): %s", model_class.name, node.objid, config)
|
||||
if not config:
|
||||
config = {}
|
||||
self.set_model_config(node.objid, model_class.name, config)
|
||||
config = self.get_model_config(node.objid, model_class.name)
|
||||
node.setmodel(model_class, config)
|
||||
|
||||
def config_reset(self, node_id=None):
|
||||
super(EmaneManager, self).config_reset(node_id)
|
||||
self.set_configs(self.emane_config.default_values())
|
||||
|
||||
def emane_models(self):
|
||||
return self._modelclsmap.keys()
|
||||
|
@ -162,8 +251,8 @@ class EmaneManager(object):
|
|||
return
|
||||
|
||||
# Get the control network to be used for events
|
||||
group, port = self.emane_config.get_config("eventservicegroup").split(":")
|
||||
self.event_device = self.emane_config.get_config("eventservicedevice")
|
||||
group, port = self.get_config("eventservicegroup").split(":")
|
||||
self.event_device = self.get_config("eventservicedevice")
|
||||
eventnetidx = self.session.get_control_net_index(self.event_device)
|
||||
if eventnetidx < 0:
|
||||
logger.error("invalid emane event service device provided: %s", self.event_device)
|
||||
|
@ -223,11 +312,15 @@ class EmaneManager(object):
|
|||
Used with XML export.
|
||||
"""
|
||||
models = []
|
||||
for model_class in self._modelclsmap.itervalues():
|
||||
if node.objid in model_class.configuration_maps:
|
||||
config = model_class.get_configs(node_id=node.objid)
|
||||
models.append((model_class, config))
|
||||
logger.debug("emane models: %s", models)
|
||||
all_configs = {}
|
||||
if self.has_configs(node_id=node.objid):
|
||||
all_configs = self.get_all_configs(node_id=node.objid)
|
||||
|
||||
for model_name in all_configs.iterkeys():
|
||||
model_class = self._modelclsmap[model_name]
|
||||
config = self.get_configs(node_id=node.objid, config_type=model_name)
|
||||
models.append((model_class, config))
|
||||
logger.debug("emane models for node(%s): %s", node.objid, models)
|
||||
return models
|
||||
|
||||
def setup(self):
|
||||
|
@ -254,7 +347,7 @@ class EmaneManager(object):
|
|||
# - needs to be configured before checkdistributed() for distributed
|
||||
# - needs to exist when eventservice binds to it (initeventservice)
|
||||
if self.session.master:
|
||||
otadev = self.emane_config.get_config("otamanagerdevice")
|
||||
otadev = self.get_config("otamanagerdevice")
|
||||
netidx = self.session.get_control_net_index(otadev)
|
||||
logger.debug("emane ota manager device: index(%s) otadev(%s)", netidx, otadev)
|
||||
if netidx < 0:
|
||||
|
@ -263,7 +356,7 @@ class EmaneManager(object):
|
|||
|
||||
ctrlnet = self.session.add_remove_control_net(net_index=netidx, remove=False, conf_required=False)
|
||||
self.distributedctrlnet(ctrlnet)
|
||||
eventdev = self.emane_config.get_config("eventservicedevice")
|
||||
eventdev = self.get_config("eventservicedevice")
|
||||
logger.debug("emane event service device: eventdev(%s)", eventdev)
|
||||
if eventdev != otadev:
|
||||
netidx = self.session.get_control_net_index(eventdev)
|
||||
|
@ -279,7 +372,7 @@ class EmaneManager(object):
|
|||
# we are slave, but haven't received a platformid yet
|
||||
platform_id_start = "platform_id_start"
|
||||
default_values = self.emane_config.default_values()
|
||||
value = self.emane_config.get_config(platform_id_start)
|
||||
value = self.get_config(platform_id_start)
|
||||
if value == default_values[platform_id_start]:
|
||||
return EmaneManager.NOT_READY
|
||||
|
||||
|
@ -411,10 +504,10 @@ class EmaneManager(object):
|
|||
emane_node = self._emane_nodes[key]
|
||||
nemcount += emane_node.numnetif()
|
||||
|
||||
nemid = int(self.emane_config.get_config("nem_id_start"))
|
||||
nemid = int(self.get_config("nem_id_start"))
|
||||
nemid += nemcount
|
||||
|
||||
platformid = int(self.emane_config.get_config("platform_id_start"))
|
||||
platformid = int(self.get_config("platform_id_start"))
|
||||
|
||||
# build an ordered list of servers so platform ID is deterministic
|
||||
servers = []
|
||||
|
@ -433,8 +526,8 @@ class EmaneManager(object):
|
|||
|
||||
platformid += 1
|
||||
typeflags = ConfigFlags.UPDATE.value
|
||||
self.emane_config.set_config("platform_id_start", str(platformid))
|
||||
self.emane_config.set_config("nem_id_start", str(nemid))
|
||||
self.set_config("platform_id_start", str(platformid))
|
||||
self.set_config("nem_id_start", str(nemid))
|
||||
config_data = ConfigShim.config_data(0, None, typeflags, self.emane_config, self.get_configs())
|
||||
message = dataconversion.convert_config(config_data)
|
||||
server.sock.send(message)
|
||||
|
@ -555,9 +648,9 @@ class EmaneManager(object):
|
|||
logger.error("emane node(%s) has no node model", node_id)
|
||||
raise ValueError("emane node has no model set")
|
||||
|
||||
config = self.get_model_config(node_id=node_id, model_name=model_name)
|
||||
logger.debug("setting emane model(%s) config(%s)", model_name, config)
|
||||
model_class = self._modelclsmap[model_name]
|
||||
config = model_class.get_configs(node_id=node_id)
|
||||
logger.debug("setting emane model(%s) config(%s)", model_class, config)
|
||||
emane_node.setmodel(model_class, config)
|
||||
|
||||
def nemlookup(self, nemid):
|
||||
|
@ -597,10 +690,10 @@ class EmaneManager(object):
|
|||
plat = doc.getElementsByTagName("platform").pop()
|
||||
|
||||
if otadev:
|
||||
self.emane_config.set_config("otamanagerdevice", otadev)
|
||||
self.set_config("otamanagerdevice", otadev)
|
||||
|
||||
if eventdev:
|
||||
self.emane_config.set_config("eventservicedevice", eventdev)
|
||||
self.set_config("eventservicedevice", eventdev)
|
||||
|
||||
# append all platform options (except starting id) to doc
|
||||
for configuration in self.emane_config.emulator_config:
|
||||
|
@ -608,7 +701,7 @@ class EmaneManager(object):
|
|||
if name == "platform_id_start":
|
||||
continue
|
||||
|
||||
value = self.emane_config.get_config(name)
|
||||
value = self.get_config(name)
|
||||
param = self.xmlparam(doc, name, value)
|
||||
plat.appendChild(param)
|
||||
|
||||
|
@ -618,7 +711,7 @@ class EmaneManager(object):
|
|||
"""
|
||||
Build a platform.xml file now that all nodes are configured.
|
||||
"""
|
||||
nemid = int(self.emane_config.get_config("nem_id_start"))
|
||||
nemid = int(self.get_config("nem_id_start"))
|
||||
platformxmls = {}
|
||||
|
||||
# assume self._objslock is already held here
|
||||
|
@ -695,7 +788,7 @@ class EmaneManager(object):
|
|||
default_values = self.emane_config.default_values()
|
||||
for name in ["eventservicegroup", "eventservicedevice"]:
|
||||
a = default_values[name]
|
||||
b = self.emane_config.get_config(name)
|
||||
b = self.get_config(name)
|
||||
if a != b:
|
||||
need_xml = True
|
||||
|
||||
|
@ -705,12 +798,12 @@ class EmaneManager(object):
|
|||
return
|
||||
|
||||
try:
|
||||
group, port = self.emane_config.get_config("eventservicegroup").split(":")
|
||||
group, port = self.get_config("eventservicegroup").split(":")
|
||||
except ValueError:
|
||||
logger.exception("invalid eventservicegroup in EMANE config")
|
||||
return
|
||||
|
||||
dev = self.emane_config.get_config("eventservicedevice")
|
||||
dev = self.get_config("eventservicedevice")
|
||||
doc = self.xmldoc("emaneeventmsgsvc")
|
||||
es = doc.getElementsByTagName("emaneeventmsgsvc").pop()
|
||||
kvs = (("group", group), ("port", port), ("device", dev), ("mcloop", "1"), ("ttl", "32"))
|
||||
|
@ -737,12 +830,12 @@ class EmaneManager(object):
|
|||
if realtime:
|
||||
emanecmd += "-r",
|
||||
|
||||
otagroup, otaport = self.emane_config.get_config("otamanagergroup").split(":")
|
||||
otadev = self.emane_config.get_config("otamanagerdevice")
|
||||
otagroup, otaport = self.get_config("otamanagergroup").split(":")
|
||||
otadev = self.get_config("otamanagerdevice")
|
||||
otanetidx = self.session.get_control_net_index(otadev)
|
||||
|
||||
eventgroup, eventport = self.emane_config.get_config("eventservicegroup").split(":")
|
||||
eventdev = self.emane_config.get_config("eventservicedevice")
|
||||
eventgroup, eventport = self.get_config("eventservicegroup").split(":")
|
||||
eventdev = self.get_config("eventservicedevice")
|
||||
eventservicenetidx = self.session.get_control_net_index(eventdev)
|
||||
|
||||
run_emane_on_host = False
|
||||
|
|
|
@ -79,7 +79,7 @@ class EmaneModel(WirelessModel):
|
|||
:return: nothing
|
||||
"""
|
||||
# retrieve configuration values
|
||||
config = self.getifcconfig(self.object_id, interface)
|
||||
config = emane_manager.getifcconfig(self.object_id, interface, self.name)
|
||||
if not config:
|
||||
return
|
||||
|
||||
|
@ -149,7 +149,7 @@ class EmaneModel(WirelessModel):
|
|||
continue
|
||||
|
||||
# check if value is a multi param
|
||||
value = config[name]
|
||||
value = str(config[name])
|
||||
param = value_to_params(mac_document, name, value)
|
||||
if not param:
|
||||
param = emane_manager.xmlparam(mac_document, name, value)
|
||||
|
@ -182,7 +182,7 @@ class EmaneModel(WirelessModel):
|
|||
continue
|
||||
|
||||
# check if value is a multi param
|
||||
value = config[name]
|
||||
value = str(config[name])
|
||||
param = value_to_params(phy_document, name, value)
|
||||
if not param:
|
||||
param = emane_manager.xmlparam(phy_document, name, value)
|
||||
|
@ -269,7 +269,7 @@ class EmaneModel(WirelessModel):
|
|||
|
||||
if interface:
|
||||
node_id = interface.node.objid
|
||||
if self.getifcconfig(node_id, interface):
|
||||
if self.session.emane.getifcconfig(node_id, interface, self.name):
|
||||
name = interface.localname.replace(".", "_")
|
||||
|
||||
return "%s%s" % (name, self.name)
|
||||
|
@ -348,43 +348,3 @@ class EmaneModel(WirelessModel):
|
|||
:return: nothing
|
||||
"""
|
||||
logger.warn("emane model(%s) does not support link configuration", self.name)
|
||||
|
||||
def getifcconfig(self, node_id, ifc):
|
||||
"""
|
||||
Retrieve interface configuration or node configuration if not provided.
|
||||
|
||||
:param int node_id: node id
|
||||
:param ifc: node interface
|
||||
:return:
|
||||
"""
|
||||
# use the network-wide config values or interface(NEM)-specific values?
|
||||
if ifc is None:
|
||||
return self.get_configs(node_id)
|
||||
else:
|
||||
# don"t use default values when interface config is the same as net
|
||||
# note here that using ifc.node.objid as key allows for only one type
|
||||
# of each model per node;
|
||||
# TODO: use both node and interface as key
|
||||
|
||||
# Adamson change: first check for iface config keyed by "node:ifc.name"
|
||||
# (so that nodes w/ multiple interfaces of same conftype can have
|
||||
# different configs for each separate interface)
|
||||
key = 1000 * ifc.node.objid
|
||||
if ifc.netindex is not None:
|
||||
key += ifc.netindex
|
||||
|
||||
# try retrieve interface specific configuration, avoid getting defaults
|
||||
config = {}
|
||||
if key in self.configuration_maps:
|
||||
config = self.get_configs(key)
|
||||
|
||||
# otherwise retrieve the interfaces node configuration, avoid using defaults
|
||||
if not config and ifc.node.objid in self.configuration_maps:
|
||||
config = self.get_configs(ifc.node.objid)
|
||||
|
||||
if not config and ifc.transport_type == "raw":
|
||||
# with EMANE 0.9.2+, we need an extra NEM XML from
|
||||
# model.buildnemxmlfiles(), so defaults are returned here
|
||||
config = self.get_configs(node_id)
|
||||
|
||||
return config
|
||||
|
|
|
@ -9,7 +9,6 @@ from core.emane import emanemodel
|
|||
class EmaneIeee80211abgModel(emanemodel.EmaneModel):
|
||||
# model name
|
||||
name = "emane_ieee80211abg"
|
||||
configuration_maps = {}
|
||||
|
||||
# mac configuration
|
||||
mac_library = "ieee80211abgmaclayer"
|
||||
|
|
|
@ -73,7 +73,7 @@ class EmaneNode(EmaneNet):
|
|||
logger.info("node(%s) updating model(%s): %s", self.objid, self.model.name, config)
|
||||
self.model.set_configs(config, node_id=self.objid)
|
||||
|
||||
def setmodel(self, model, config=None):
|
||||
def setmodel(self, model, config):
|
||||
"""
|
||||
set the EmaneModel associated with this node
|
||||
"""
|
||||
|
@ -81,9 +81,11 @@ class EmaneNode(EmaneNet):
|
|||
if model.config_type == RegisterTlvs.WIRELESS.value:
|
||||
# EmaneModel really uses values from ConfigurableManager
|
||||
# when buildnemxml() is called, not during init()
|
||||
self.model = model(session=self.session, object_id=self.objid, config=config)
|
||||
self.model = model(session=self.session, object_id=self.objid)
|
||||
self.model.update_config(config)
|
||||
elif model.config_type == RegisterTlvs.MOBILITY.value:
|
||||
self.mobility = model(session=self.session, object_id=self.objid, config=config)
|
||||
self.mobility = model(session=self.session, object_id=self.objid)
|
||||
self.mobility.update_config(config)
|
||||
|
||||
def setnemid(self, netif, nemid):
|
||||
"""
|
||||
|
@ -180,8 +182,7 @@ class EmaneNode(EmaneNet):
|
|||
trans.setAttribute("library", "trans%s" % transport_type.lower())
|
||||
trans.appendChild(emane.xmlparam(transdoc, "bitrate", "0"))
|
||||
|
||||
model_class = emane.get_model_class(self.model.name)
|
||||
config = model_class.get_configs(self.objid)
|
||||
config = emane.get_configs(node_id=self.objid, config_type=self.model.name)
|
||||
logger.debug("transport xml config: %s", config)
|
||||
flowcontrol = config.get("flowcontrolenable", "0") == "1"
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ from core.emane import emanemodel
|
|||
class EmaneRfPipeModel(emanemodel.EmaneModel):
|
||||
# model name
|
||||
name = "emane_rfpipe"
|
||||
configuration_maps = {}
|
||||
|
||||
# mac configuration
|
||||
mac_library = "rfpipemaclayer"
|
||||
|
|
|
@ -16,7 +16,6 @@ from core.misc import utils
|
|||
class EmaneTdmaModel(emanemodel.EmaneModel):
|
||||
# model name
|
||||
name = "emane_tdma"
|
||||
configuration_maps = {}
|
||||
|
||||
# mac configuration
|
||||
mac_library = "tdmaeventschedulerradiomodel"
|
||||
|
@ -47,7 +46,7 @@ class EmaneTdmaModel(emanemodel.EmaneModel):
|
|||
:return: nothing
|
||||
"""
|
||||
# get configured schedule
|
||||
config = self.get_configs(self.object_id)
|
||||
config = self.session.emane.get_configs(node_id=self.object_id, config_type=self.name)
|
||||
if not config:
|
||||
return
|
||||
schedule = config[self.schedule_name]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue