daemon: updates to emane manager to setup ota/event control networks on nodes and host based on individual nem configurations

This commit is contained in:
Blake Harnden 2021-05-21 22:57:27 -07:00
parent aea727ba42
commit ef0fa8c1a7
2 changed files with 37 additions and 70 deletions

View file

@ -274,6 +274,9 @@ class EmaneManager:
:return: SUCCESS, NOT_NEEDED, NOT_READY in order to delay session :return: SUCCESS, NOT_NEEDED, NOT_READY in order to delay session
instantiation instantiation
""" """
# check if bindings were installed
if EventService is None:
raise CoreError("EMANE python bindings are not installed")
logger.debug("emane setup") logger.debug("emane setup")
with self.session.nodes_lock: with self.session.nodes_lock:
for node_id in self.session.nodes: for node_id in self.session.nodes:
@ -286,24 +289,6 @@ class EmaneManager:
if not self._emane_nets: if not self._emane_nets:
logger.debug("no emane nodes in session") logger.debug("no emane nodes in session")
return EmaneState.NOT_NEEDED return EmaneState.NOT_NEEDED
# check if bindings were installed
if EventService is None:
raise CoreError("EMANE python bindings are not installed")
# control network bridge required for emane
otadev = DEFAULT_DEV
netidx = self.session.get_control_net_index(otadev)
logger.debug("emane ota manager device: index(%s) otadev(%s)", netidx, otadev)
if netidx < 0:
logger.error(
"EMANE cannot start, check core config. invalid OTA device provided: %s",
otadev,
)
return EmaneState.NOT_READY
self.session.add_remove_control_net(
net_index=netidx, remove=False, conf_required=False
)
self.check_node_models() self.check_node_models()
return EmaneState.SUCCESS return EmaneState.SUCCESS
@ -322,14 +307,23 @@ class EmaneManager:
self.initeventservice() self.initeventservice()
if self.service and self.doeventmonitor(): if self.service and self.doeventmonitor():
self.starteventmonitor() self.starteventmonitor()
self.startup_nodes()
if self.links_enabled():
self.link_monitor.start()
return EmaneState.SUCCESS
def startup_nodes(self) -> None:
with self._emane_node_lock: with self._emane_node_lock:
logger.info("emane building xmls...") logger.info("emane building xmls...")
start_data = self.get_start_data() start_data = self.get_start_data()
for data in start_data: for data in start_data:
self.start_node(data) node = data.node
if self.links_enabled(): for iface in data.ifaces:
self.link_monitor.start() if isinstance(node, CoreNode):
return EmaneState.SUCCESS self.setup_ota(node, iface)
emanexml.build_platform_xml(self, node, iface)
self.start_daemon(node, iface)
self.install_iface(iface)
def get_start_data(self) -> List[StartData]: def get_start_data(self) -> List[StartData]:
node_map = {} node_map = {}
@ -353,19 +347,6 @@ class EmaneManager:
start_node.ifaces = sorted(start_node.ifaces, key=lambda x: x.node_id) start_node.ifaces = sorted(start_node.ifaces, key=lambda x: x.node_id)
return start_nodes return start_nodes
def start_node(self, data: StartData) -> None:
node = data.node
control_net = self.session.add_remove_control_net(
0, remove=False, conf_required=False
)
# builds xmls and start emane daemons
for iface in data.ifaces:
if isinstance(node, CoreNode):
self.setup_ota(node, iface)
emanexml.build_platform_xml(self, control_net, node, iface)
self.start_daemon(node, iface)
self.install_iface(iface)
def setup_ota(self, node: CoreNode, iface: CoreInterface) -> None: def setup_ota(self, node: CoreNode, iface: CoreInterface) -> None:
if not isinstance(iface.net, EmaneNet): if not isinstance(iface.net, EmaneNet):
raise CoreError( raise CoreError(
@ -375,35 +356,27 @@ class EmaneManager:
# setup ota device # setup ota device
otagroup, _otaport = config["otamanagergroup"].split(":") otagroup, _otaport = config["otamanagergroup"].split(":")
otadev = config["otamanagerdevice"] otadev = config["otamanagerdevice"]
otanetidx = self.session.get_control_net_index(otadev) ota_index = self.session.get_control_net_index(otadev)
self.session.add_remove_control_net(ota_index, conf_required=False)
self.session.add_remove_control_iface(node, ota_index, conf_required=False)
# setup event device
eventgroup, _eventport = config["eventservicegroup"].split(":") eventgroup, _eventport = config["eventservicegroup"].split(":")
eventdev = config["eventservicedevice"] eventdev = config["eventservicedevice"]
eventservicenetidx = self.session.get_control_net_index(eventdev) event_index = self.session.get_control_net_index(eventdev)
# control network not yet started here self.session.add_remove_control_net(event_index, conf_required=False)
self.session.add_remove_control_iface( self.session.add_remove_control_iface(node, event_index, conf_required=False)
node, 0, remove=False, conf_required=False # setup multicast routes as needed
)
if otanetidx > 0:
logger.info("adding ota device ctrl%d", otanetidx)
self.session.add_remove_control_iface(
node, otanetidx, remove=False, conf_required=False
)
if eventservicenetidx >= 0:
logger.info("adding event service device ctrl%d", eventservicenetidx)
self.session.add_remove_control_iface(
node, eventservicenetidx, remove=False, conf_required=False
)
# multicast route is needed for OTA data
logger.info( logger.info(
"node(%s) interface(%s) ota group(%s) dev(%s)", "node(%s) interface(%s) ota(%s:%s) event(%s:%s)",
node.name, node.name,
iface.name, iface.name,
otagroup, otagroup,
otadev, otadev,
eventgroup,
eventdev,
) )
node.node_net_client.create_route(otagroup, otadev) node.node_net_client.create_route(otagroup, otadev)
# multicast route is also needed for event data if on control network if eventgroup != otagroup:
if eventservicenetidx >= 0 and eventgroup != otagroup:
node.node_net_client.create_route(eventgroup, eventdev) node.node_net_client.create_route(eventgroup, eventdev)
def get_iface(self, nem_id: int) -> Optional[CoreInterface]: def get_iface(self, nem_id: int) -> Optional[CoreInterface]:
@ -536,7 +509,13 @@ class EmaneManager:
Start one EMANE daemon per node having a radio. Start one EMANE daemon per node having a radio.
Add a control network even if the user has not configured one. Add a control network even if the user has not configured one.
""" """
logger.info("starting emane daemons...") nem = self.get_nem_id(iface)
logger.info(
"starting emane daemon node(%s) iface(%s) nem(%s)",
node.name,
iface.name,
nem,
)
loglevel = str(DEFAULT_LOG_LEVEL) loglevel = str(DEFAULT_LOG_LEVEL)
cfgloglevel = self.session.options.get_config_int("emane_log_level") cfgloglevel = self.session.options.get_config_int("emane_log_level")
realtime = self.session.options.get_config_bool("emane_realtime", default=True) realtime = self.session.options.get_config_bool("emane_realtime", default=True)
@ -552,13 +531,11 @@ class EmaneManager:
platform_xml = node.directory / emanexml.platform_file_name(iface) platform_xml = node.directory / emanexml.platform_file_name(iface)
args = f"{emanecmd} -f {log_file} {platform_xml}" args = f"{emanecmd} -f {log_file} {platform_xml}"
node.cmd(args) node.cmd(args)
logger.info("node(%s) emane daemon running: %s", node.name, args)
else: else:
log_file = self.session.directory / f"{iface.name}-emane.log" log_file = self.session.directory / f"{iface.name}-emane.log"
platform_xml = self.session.directory / emanexml.platform_file_name(iface) platform_xml = self.session.directory / emanexml.platform_file_name(iface)
args = f"{emanecmd} -f {log_file} {platform_xml}" args = f"{emanecmd} -f {log_file} {platform_xml}"
node.host_cmd(args, cwd=self.session.directory) node.host_cmd(args, cwd=self.session.directory)
logger.info("node(%s) host emane daemon running: %s", node.name, args)
def install_iface(self, iface: CoreInterface) -> None: def install_iface(self, iface: CoreInterface) -> None:
emane_net = iface.net emane_net = iface.net

View file

@ -12,7 +12,6 @@ from core.emulator.distributed import DistributedServer
from core.errors import CoreError from core.errors import CoreError
from core.nodes.base import CoreNode, CoreNodeBase from core.nodes.base import CoreNode, CoreNodeBase
from core.nodes.interface import CoreInterface from core.nodes.interface import CoreInterface
from core.nodes.network import CtrlNet
from core.xml import corexml from core.xml import corexml
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -146,18 +145,13 @@ def add_configurations(
def build_platform_xml( def build_platform_xml(
emane_manager: "EmaneManager", emane_manager: "EmaneManager", node: CoreNodeBase, iface: CoreInterface
control_net: CtrlNet,
node: CoreNodeBase,
iface: CoreInterface,
) -> None: ) -> None:
""" """
Create platform xml for a specific node. Create platform xml for a specific node.
:param emane_manager: emane manager with emane :param emane_manager: emane manager with emane
configurations configurations
:param control_net: control net node for this emane
network
:param node: node to create a platform xml for :param node: node to create a platform xml for
:param iface: node interface to create platform xml for :param iface: node interface to create platform xml for
:return: the next nem id that can be used for creating platform xml files :return: the next nem id that can be used for creating platform xml files
@ -171,14 +165,10 @@ def build_platform_xml(
emane_net.model.build_xml_files(config, iface) emane_net.model.build_xml_files(config, iface)
# create top level platform element # create top level platform element
transport_configs = {"otamanagerdevice", "eventservicedevice"}
platform_element = etree.Element("platform") platform_element = etree.Element("platform")
for configuration in emane_net.model.platform_config: for configuration in emane_net.model.platform_config:
name = configuration.id name = configuration.id
if not isinstance(node, CoreNode) and name in transport_configs: value = config[configuration.id]
value = control_net.brname
else:
value = config[configuration.id]
if name == "controlportendpoint": if name == "controlportendpoint":
port = emane_manager.get_nem_port(iface) port = emane_manager.get_nem_port(iface)
value = f"0.0.0.0:{port}" value = f"0.0.0.0:{port}"