updated session.add_node to use better type hinting and force usage of classes directly, instead of indirectly through NodeTypes
This commit is contained in:
parent
d5254e6a91
commit
c07766e1eb
31 changed files with 315 additions and 276 deletions
|
@ -123,7 +123,8 @@ def create_nodes(
|
|||
funcs = []
|
||||
for node_proto in node_protos:
|
||||
_type, _id, options = add_node_data(node_proto)
|
||||
args = (_type, _id, options)
|
||||
_class = session.get_node_class(_type)
|
||||
args = (_class, _id, options)
|
||||
funcs.append((session.add_node, args, {}))
|
||||
start = time.monotonic()
|
||||
results, exceptions = utils.threadpool(funcs)
|
||||
|
|
|
@ -667,7 +667,8 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
|||
logging.debug("add node: %s", request)
|
||||
session = self.get_session(request.session_id, context)
|
||||
_type, _id, options = grpcutils.add_node_data(request.node)
|
||||
node = session.add_node(_type=_type, _id=_id, options=options)
|
||||
_class = session.get_node_class(_type)
|
||||
node = session.add_node(_class, _id, options)
|
||||
return core_pb2.AddNodeResponse(node_id=node.id)
|
||||
|
||||
def GetNode(
|
||||
|
|
|
@ -41,7 +41,7 @@ from core.emulator.enumerations import (
|
|||
)
|
||||
from core.errors import CoreCommandError, CoreError
|
||||
from core.location.mobility import BasicRangeModel
|
||||
from core.nodes.base import CoreNodeBase, NodeBase
|
||||
from core.nodes.base import CoreNode, CoreNodeBase, NodeBase
|
||||
from core.nodes.network import WlanNode
|
||||
from core.services.coreservices import ServiceManager, ServiceShim
|
||||
|
||||
|
@ -682,10 +682,11 @@ class CoreHandler(socketserver.BaseRequestHandler):
|
|||
logging.warning("ignoring invalid message: add and delete flag both set")
|
||||
return ()
|
||||
|
||||
node_type = None
|
||||
_class = CoreNode
|
||||
node_type_value = message.get_tlv(NodeTlvs.TYPE.value)
|
||||
if node_type_value is not None:
|
||||
node_type = NodeTypes(node_type_value)
|
||||
_class = self.session.get_node_class(node_type)
|
||||
|
||||
node_id = message.get_tlv(NodeTlvs.NUMBER.value)
|
||||
|
||||
|
@ -720,7 +721,7 @@ class CoreHandler(socketserver.BaseRequestHandler):
|
|||
options.services = services.split("|")
|
||||
|
||||
if message.flags & MessageFlags.ADD.value:
|
||||
node = self.session.add_node(node_type, node_id, options)
|
||||
node = self.session.add_node(_class, node_id, options)
|
||||
if node:
|
||||
if message.flags & MessageFlags.STRING.value:
|
||||
self.node_status_request[node.id] = True
|
||||
|
|
|
@ -75,6 +75,7 @@ NODES = {
|
|||
NodeTypes.LXC: LxcNode,
|
||||
}
|
||||
NODES_TYPE = {NODES[x]: x for x in NODES}
|
||||
CONTAINER_NODES = {DockerNode, LxcNode}
|
||||
CTRL_NET_ID = 9001
|
||||
LINK_COLORS = ["green", "blue", "orange", "purple", "turquoise"]
|
||||
NT = TypeVar("NT", bound=NodeBase)
|
||||
|
@ -348,7 +349,7 @@ class Session:
|
|||
node_two.name,
|
||||
)
|
||||
start = self.state.should_start()
|
||||
net_one = self.create_node(cls=PtpNet, start=start)
|
||||
net_one = self.create_node(_class=PtpNet, start=start)
|
||||
|
||||
# node to network
|
||||
if node_one and net_one:
|
||||
|
@ -662,32 +663,21 @@ class Session:
|
|||
node_two.lock.release()
|
||||
|
||||
def add_node(
|
||||
self,
|
||||
_type: NodeTypes = NodeTypes.DEFAULT,
|
||||
_id: int = None,
|
||||
options: NodeOptions = None,
|
||||
_cls: Type[NodeBase] = None,
|
||||
) -> NodeBase:
|
||||
self, _class: Type[NT], _id: int = None, options: NodeOptions = None
|
||||
) -> NT:
|
||||
"""
|
||||
Add a node to the session, based on the provided node data.
|
||||
|
||||
:param _type: type of node to create
|
||||
:param _class: node class to create
|
||||
:param _id: id for node, defaults to None for generated id
|
||||
:param options: data to create node with
|
||||
:param _cls: optional custom class to use for a created node
|
||||
:return: created node
|
||||
:raises core.CoreError: when an invalid node type is given
|
||||
"""
|
||||
# validate node type, get class, or throw error
|
||||
if _cls is None:
|
||||
node_class = self.get_node_class(_type)
|
||||
else:
|
||||
node_class = _cls
|
||||
|
||||
# set node start based on current session state, override and check when rj45
|
||||
start = self.state.should_start()
|
||||
enable_rj45 = self.options.get_config("enablerj45") == "1"
|
||||
if _type == NodeTypes.RJ45 and not enable_rj45:
|
||||
if _class == Rj45Node and not enable_rj45:
|
||||
start = False
|
||||
|
||||
# determine node id
|
||||
|
@ -703,7 +693,7 @@ class Session:
|
|||
options.set_position(0, 0)
|
||||
name = options.name
|
||||
if not name:
|
||||
name = f"{node_class.__name__}{_id}"
|
||||
name = f"{_class.__name__}{_id}"
|
||||
|
||||
# verify distributed server
|
||||
server = self.distributed.servers.get(options.server)
|
||||
|
@ -713,24 +703,15 @@ class Session:
|
|||
# create node
|
||||
logging.info(
|
||||
"creating node(%s) id(%s) name(%s) start(%s)",
|
||||
node_class.__name__,
|
||||
_class.__name__,
|
||||
_id,
|
||||
name,
|
||||
start,
|
||||
)
|
||||
if _type in [NodeTypes.DOCKER, NodeTypes.LXC]:
|
||||
node = self.create_node(
|
||||
cls=node_class,
|
||||
_id=_id,
|
||||
name=name,
|
||||
start=start,
|
||||
image=options.image,
|
||||
server=server,
|
||||
)
|
||||
else:
|
||||
node = self.create_node(
|
||||
cls=node_class, _id=_id, name=name, start=start, server=server
|
||||
)
|
||||
kwargs = dict(_id=_id, name=name, start=start, server=server)
|
||||
if _class in CONTAINER_NODES:
|
||||
kwargs["image"] = options.image
|
||||
node = self.create_node(_class, **kwargs)
|
||||
|
||||
# set node attributes
|
||||
node.icon = options.icon
|
||||
|
@ -1363,17 +1344,17 @@ class Session:
|
|||
break
|
||||
return node_id
|
||||
|
||||
def create_node(self, cls: Type[NodeBase], *args: Any, **kwargs: Any) -> NodeBase:
|
||||
def create_node(self, _class: Type[NT], *args: Any, **kwargs: Any) -> NT:
|
||||
"""
|
||||
Create an emulation node.
|
||||
|
||||
:param cls: node class to create
|
||||
:param _class: node class to create
|
||||
:param args: list of arguments for the class to create
|
||||
:param kwargs: dictionary of arguments for the class to create
|
||||
:return: the created node instance
|
||||
:raises core.CoreError: when id of the node to create already exists
|
||||
"""
|
||||
node = cls(self, *args, **kwargs)
|
||||
node = _class(self, *args, **kwargs)
|
||||
with self._nodes_lock:
|
||||
if node.id in self.nodes:
|
||||
node.shutdown()
|
||||
|
@ -1791,7 +1772,7 @@ class Session:
|
|||
server_interface,
|
||||
)
|
||||
control_net = self.create_node(
|
||||
cls=CtrlNet,
|
||||
_class=CtrlNet,
|
||||
_id=_id,
|
||||
prefix=prefix,
|
||||
assign_address=True,
|
||||
|
|
|
@ -840,6 +840,7 @@ class CoreXmlReader:
|
|||
node_type = NodeTypes.DOCKER
|
||||
elif clazz == "lxc":
|
||||
node_type = NodeTypes.LXC
|
||||
_class = self.session.get_node_class(node_type)
|
||||
|
||||
service_elements = device_element.find("services")
|
||||
if service_elements is not None:
|
||||
|
@ -865,12 +866,13 @@ class CoreXmlReader:
|
|||
options.set_location(lat, lon, alt)
|
||||
|
||||
logging.info("reading node id(%s) model(%s) name(%s)", node_id, model, name)
|
||||
self.session.add_node(_type=node_type, _id=node_id, options=options)
|
||||
self.session.add_node(_class, node_id, options)
|
||||
|
||||
def read_network(self, network_element: etree.Element) -> None:
|
||||
node_id = get_int(network_element, "id")
|
||||
name = network_element.get("name")
|
||||
node_type = NodeTypes[network_element.get("type")]
|
||||
_class = self.session.get_node_class(node_type)
|
||||
icon = network_element.get("icon")
|
||||
options = NodeOptions(name)
|
||||
options.icon = icon
|
||||
|
@ -891,7 +893,7 @@ class CoreXmlReader:
|
|||
logging.info(
|
||||
"reading node id(%s) node_type(%s) name(%s)", node_id, node_type, name
|
||||
)
|
||||
self.session.add_node(_type=node_type, _id=node_id, options=options)
|
||||
self.session.add_node(_class, node_id, options)
|
||||
|
||||
def read_configservice_configs(self) -> None:
|
||||
configservice_configs = self.scenario.find("configservice_configurations")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue