def __init__( self, session, _id: int = None, name: str = None, nodedir: str = None, start: bool = True, server: DistributedServer = None, ) -> None: super().__init__(session, _id, name, start, server) if not self.server: raise CoreError("physical nodes must be assigned to a remote server") self.nodedir = nodedir self.up = start self.lock = threading.RLock() self._mounts = [] if start: self.startup()
def create_dir(self, dir_path: Path) -> None: """ Create a node private directory. :param dir_path: path to create :return: nothing """ if not dir_path.is_absolute(): raise CoreError( f"private directory path not fully qualified: {dir_path}") logger.debug("node(%s) creating private directory: %s", self.name, dir_path) parent_path = self._find_parent_path(dir_path) if parent_path: self.host_cmd(f"mkdir -p {parent_path}") else: host_path = self.host_path(dir_path, is_dir=True) self.host_cmd(f"mkdir -p {host_path}") self.mount(host_path, dir_path)
def create_mac_xml(emane_model: "EmaneModel", iface: CoreInterface, config: Dict[str, str]) -> None: """ Create the mac xml document. :param emane_model: emane model to create xml :param iface: interface to create xml for :param config: all current configuration values :return: nothing """ if not emane_model.mac_library: raise CoreError("must define emane model library") mac_element = etree.Element("mac", name=f"{emane_model.name} MAC", library=emane_model.mac_library) add_configurations(mac_element, emane_model.mac_config, config, emane_model.config_ignore) file_name = mac_file_name(iface) create_node_file(iface.node, mac_element, "mac", file_name)
def add_server(self, name: str, host: str) -> None: """ Add distributed server configuration. :param name: distributed server name :param host: distributed server host address :return: nothing :raises CoreError: when there is an error validating server """ server = DistributedServer(name, host) for requirement in get_requirements(self.session.use_ovs()): try: server.remote_cmd(f"which {requirement}") except CoreCommandError: raise CoreError(f"server({server.name}) failed validation for " f"command({requirement})") self.servers[name] = server cmd = f"mkdir -p {self.session.session_dir}" server.remote_cmd(cmd)
def setup(self) -> EmaneState: """ Setup duties for EMANE manager. :return: SUCCESS, NOT_NEEDED, NOT_READY in order to delay session instantiation """ logger.debug("emane setup") with self.session.nodes_lock: for node_id in self.session.nodes: node = self.session.nodes[node_id] if isinstance(node, EmaneNet): logger.debug("adding emane node: id(%s) name(%s)", node.id, node.name) self.add_node(node) if not self._emane_nets: logger.debug("no emane nodes in session") return EmaneState.NOT_NEEDED # check if bindings were installed if EventService is None: raise CoreError("EMANE python bindings are not installed") self.check_node_models() return EmaneState.SUCCESS
def addfile(self, srcname: str, filename: str) -> None: raise CoreError("rj45 does not support addfile")
def termcmdstring(self, sh: str) -> str: raise CoreError("rj45 does not support terminal commands")
def get_iface(self, iface_id: int) -> CoreInterface: if iface_id != self.iface_id or iface_id not in self.ifaces: raise CoreError( f"node({self.name}) interface({iface_id}) does not exist") return self.iface
def addfile(self, srcname: str, filename: str) -> None: raise CoreError("physical node does not support addfile")
def build_platform_xml( emane_manager: "EmaneManager", control_net: CtrlNet, data: "StartData" ) -> None: """ Create platform xml for a specific node. :param emane_manager: emane manager with emane configurations :param control_net: control net node for this emane network :param data: start data for a node connected to emane and associated interfaces :return: the next nem id that can be used for creating platform xml files """ # create top level platform element transport_configs = {"otamanagerdevice", "eventservicedevice"} platform_element = etree.Element("platform") for configuration in emane_manager.emane_config.emulator_config: name = configuration.id if not isinstance(data.node, CoreNode) and name in transport_configs: value = control_net.brname else: value = emane_manager.get_config(name) add_param(platform_element, name, value) # create nem xml entries for all interfaces for iface in data.ifaces: emane_net = iface.net if not isinstance(emane_net, EmaneNet): raise CoreError( f"emane interface not connected to emane net: {emane_net.name}" ) nem_id = emane_manager.next_nem_id() emane_manager.set_nem(nem_id, iface) emane_manager.write_nem(iface, nem_id) config = emane_manager.get_iface_config(emane_net, iface) emane_net.model.build_xml_files(config, iface) # build nem xml nem_definition = nem_file_name(iface) nem_element = etree.Element( "nem", id=str(nem_id), name=iface.localname, definition=nem_definition ) # check if this is an external transport if is_external(config): nem_element.set("transport", "external") platform_endpoint = "platformendpoint" add_param(nem_element, platform_endpoint, config[platform_endpoint]) transport_endpoint = "transportendpoint" add_param(nem_element, transport_endpoint, config[transport_endpoint]) # define transport element transport_name = transport_file_name(iface) transport_element = etree.SubElement( nem_element, "transport", definition=transport_name ) add_param(transport_element, "device", iface.name) # add nem element to platform element platform_element.append(nem_element) # generate and assign interface mac address based on nem id mac = _MAC_PREFIX + ":00:00:" mac += f"{(nem_id >> 8) & 0xFF:02X}:{nem_id & 0xFF:02X}" iface.set_mac(mac) doc_name = "platform" file_name = f"{data.node.name}-platform.xml" create_node_file(data.node, platform_element, doc_name, file_name)
def linknet(self, net: "CoreNetworkBase") -> CoreInterface: raise CoreError("emane networks cannot be linked to other networks")
def update_mobility(self, config: Dict[str, str]) -> None: if not self.mobility: raise CoreError(f"no mobility set to update for node({self.name})") self.mobility.update_config(config)
def set_nem(self, nem_id: int, iface: CoreInterface) -> None: if nem_id in self.nems_to_ifaces: raise CoreError(f"adding duplicate nem: {nem_id}") self.nems_to_ifaces[nem_id] = iface self.ifaces_to_nems[iface] = nem_id
def custom_iface(self, node: CoreNode, iface_data: InterfaceData) -> CoreInterface: raise CoreError(f"{type(self).__name__} does not support, custom interfaces")
def nodefile(self, filename: str, contents: str, mode: int = 0o644) -> None: raise CoreError("rj45 does not support nodefile")
def updatemodel(self, config: Dict[str, str]) -> None: if not self.model: raise CoreError(f"no model set to update for node({self.name})") logger.info("node(%s) updating model(%s): %s", self.id, self.model.name, config) self.model.update_config(config)
def cmd(self, args: str, wait: bool = True, shell: bool = False) -> str: raise CoreError("rj45 does not support cmds")
def get(cls, name: str) -> Type[EmaneModel]: model = cls.models.get(name) if model is None: raise CoreError(f"emame model does not exist {name}") return model