daemon: removed node.startup from inside constructor, session is now responsible, providing more control and avoiding issues when using super calls where you dont want to start just yet

This commit is contained in:
Blake Harnden 2020-06-14 09:37:58 -07:00
parent 3243a69afa
commit c4c667bb74
7 changed files with 30 additions and 56 deletions

View file

@ -55,10 +55,9 @@ class EmaneNet(CoreNetworkBase):
session: "Session",
_id: int = None,
name: str = None,
start: bool = True,
server: DistributedServer = None,
) -> None:
super().__init__(session, _id, name, start, server)
super().__init__(session, _id, name, server)
self.conf: str = ""
self.nemidmap: Dict[CoreInterface, int] = {}
self.model: "OptionalEmaneModel" = None

View file

@ -257,7 +257,7 @@ class Session:
if isinstance(node1, CoreNodeBase) and isinstance(node2, CoreNodeBase):
logging.info("linking ptp: %s - %s", node1.name, node2.name)
start = self.state.should_start()
ptp = self.create_node(PtpNet, start=start)
ptp = self.create_node(PtpNet, start)
interface1 = node1.newnetif(ptp, interface1_data)
interface2 = node2.newnetif(ptp, interface2_data)
ptp.linkconfig(interface1, options)
@ -517,10 +517,10 @@ class Session:
name,
start,
)
kwargs = dict(_id=_id, name=name, start=start, server=server)
kwargs = dict(_id=_id, name=name, server=server)
if _class in CONTAINER_NODES:
kwargs["image"] = options.image
node = self.create_node(_class, **kwargs)
node = self.create_node(_class, start, **kwargs)
# set node attributes
node.icon = options.icon
@ -1056,11 +1056,14 @@ class Session:
logging.exception("failed to set permission on %s", self.session_dir)
self.user = user
def create_node(self, _class: Type[NT], *args: Any, **kwargs: Any) -> NT:
def create_node(
self, _class: Type[NT], start: bool, *args: Any, **kwargs: Any
) -> NT:
"""
Create an emulation node.
:param _class: node class to create
:param start: True to start node, False otherwise
: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
@ -1072,6 +1075,8 @@ class Session:
node.shutdown()
raise CoreError(f"duplicate node id {node.id} for {node.name}")
self.nodes[node.id] = node
if start:
node.startup()
return node
def get_node(self, _id: int, _class: Type[NT]) -> NT:
@ -1464,6 +1469,7 @@ class Session:
)
control_net = self.create_node(
CtrlNet,
True,
prefix,
_id=_id,
updown_script=updown_script,

View file

@ -7,7 +7,7 @@ import os
import shutil
import threading
from threading import RLock
from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, Type
from typing import TYPE_CHECKING, Dict, List, Optional, Set, Tuple, Type
import netaddr
@ -47,7 +47,6 @@ class NodeBase:
session: "Session",
_id: int = None,
name: str = None,
start: bool = True,
server: "DistributedServer" = None,
) -> None:
"""
@ -56,7 +55,6 @@ class NodeBase:
:param session: CORE session object
:param _id: id
:param name: object name
:param start: start value
:param server: remote server node
will run on, default is None for localhost
"""
@ -254,7 +252,6 @@ class CoreNodeBase(NodeBase):
session: "Session",
_id: int = None,
name: str = None,
start: bool = True,
server: "DistributedServer" = None,
) -> None:
"""
@ -263,11 +260,10 @@ class CoreNodeBase(NodeBase):
:param session: CORE session object
:param _id: object id
:param name: object name
:param start: boolean for starting
:param server: remote server node
will run on, default is None for localhost
"""
super().__init__(session, _id, name, start, server)
super().__init__(session, _id, name, server)
self.config_services: Dict[str, "ConfigService"] = {}
self.nodedir: Optional[str] = None
self.tmpnodedir: bool = False
@ -492,8 +488,8 @@ class CoreNode(CoreNodeBase):
Provides standard core node logic.
"""
apitype = NodeTypes.DEFAULT
valid_address_types = {"inet", "inet6", "inet6link"}
apitype: NodeTypes = NodeTypes.DEFAULT
valid_address_types: Set[str] = {"inet", "inet6", "inet6link"}
def __init__(
self,
@ -501,7 +497,6 @@ class CoreNode(CoreNodeBase):
_id: int = None,
name: str = None,
nodedir: str = None,
start: bool = True,
server: "DistributedServer" = None,
) -> None:
"""
@ -511,11 +506,10 @@ class CoreNode(CoreNodeBase):
:param _id: object id
:param name: object name
:param nodedir: node directory
:param start: start flag
:param server: remote server node
will run on, default is None for localhost
"""
super().__init__(session, _id, name, start, server)
super().__init__(session, _id, name, server)
self.nodedir: Optional[str] = nodedir
self.ctrlchnlname: str = os.path.abspath(
os.path.join(self.session.session_dir, self.name)
@ -526,8 +520,6 @@ class CoreNode(CoreNodeBase):
self._mounts: List[Tuple[str, str]] = []
use_ovs = session.options.get_config("ovs") == "True"
self.node_net_client: LinuxNetClient = self.create_node_net_client(use_ovs)
if start:
self.startup()
def create_node_net_client(self, use_ovs: bool) -> LinuxNetClient:
"""
@ -981,15 +973,14 @@ class CoreNetworkBase(NodeBase):
Base class for networks
"""
linktype = LinkTypes.WIRED
is_emane = False
linktype: LinkTypes = LinkTypes.WIRED
is_emane: bool = False
def __init__(
self,
session: "Session",
_id: int,
name: str,
start: bool = True,
server: "DistributedServer" = None,
) -> None:
"""
@ -998,11 +989,10 @@ class CoreNetworkBase(NodeBase):
:param session: CORE session object
:param _id: object id
:param name: object name
:param start: should object start
:param server: remote server node
will run on, default is None for localhost
"""
super().__init__(session, _id, name, start, server)
super().__init__(session, _id, name, server)
self.brname = None
self._linked = {}
self._linked_lock = threading.Lock()

View file

@ -77,7 +77,6 @@ class DockerNode(CoreNode):
_id: int = None,
name: str = None,
nodedir: str = None,
start: bool = True,
server: DistributedServer = None,
image: str = None
) -> None:
@ -88,7 +87,6 @@ class DockerNode(CoreNode):
:param _id: object id
:param name: object name
:param nodedir: node directory
:param start: start flag
:param server: remote server node
will run on, default is None for localhost
:param image: image to start container with
@ -96,7 +94,7 @@ class DockerNode(CoreNode):
if image is None:
image = "ubuntu"
self.image: str = image
super().__init__(session, _id, name, nodedir, start, server)
super().__init__(session, _id, name, nodedir, server)
def create_node_net_client(self, use_ovs: bool) -> LinuxNetClient:
"""

View file

@ -74,7 +74,6 @@ class LxcNode(CoreNode):
_id: int = None,
name: str = None,
nodedir: str = None,
start: bool = True,
server: DistributedServer = None,
image: str = None,
) -> None:
@ -85,7 +84,6 @@ class LxcNode(CoreNode):
:param _id: object id
:param name: object name
:param nodedir: node directory
:param start: start flag
:param server: remote server node
will run on, default is None for localhost
:param image: image to start container with
@ -93,7 +91,7 @@ class LxcNode(CoreNode):
if image is None:
image = "ubuntu"
self.image: str = image
super().__init__(session, _id, name, nodedir, start, server)
super().__init__(session, _id, name, nodedir, server)
def alive(self) -> bool:
"""

View file

@ -264,7 +264,6 @@ class CoreNetwork(CoreNetworkBase):
session: "Session",
_id: int = None,
name: str = None,
start: bool = True,
server: "DistributedServer" = None,
policy: NetworkPolicy = None,
) -> None:
@ -274,12 +273,11 @@ class CoreNetwork(CoreNetworkBase):
:param session: core session instance
:param _id: object id
:param name: object name
:param start: start flag
:param server: remote server node
will run on, default is None for localhost
:param policy: network policy
"""
super().__init__(session, _id, name, start, server)
super().__init__(session, _id, name, server)
if name is None:
name = str(self.id)
if policy is not None:
@ -288,9 +286,6 @@ class CoreNetwork(CoreNetworkBase):
sessionid = self.session.short_session_id()
self.brname: str = f"b.{self.id}.{sessionid}"
self.has_ebtables_chain: bool = False
if start:
self.startup()
ebq.startupdateloop(self)
def host_cmd(
self,
@ -327,6 +322,7 @@ class CoreNetwork(CoreNetworkBase):
self.net_client.create_bridge(self.brname)
self.has_ebtables_chain = False
self.up = True
ebq.startupdateloop(self)
def shutdown(self) -> None:
"""
@ -610,7 +606,6 @@ class GreTapBridge(CoreNetwork):
localip: str = None,
ttl: int = 255,
key: int = None,
start: bool = True,
server: "DistributedServer" = None,
) -> None:
"""
@ -628,7 +623,7 @@ class GreTapBridge(CoreNetwork):
:param server: remote server node
will run on, default is None for localhost
"""
CoreNetwork.__init__(self, session, _id, name, False, server, policy)
CoreNetwork.__init__(self, session, _id, name, server, policy)
if key is None:
key = self.session.id ^ self.id
self.grekey: int = key
@ -647,8 +642,6 @@ class GreTapBridge(CoreNetwork):
ttl=ttl,
key=self.grekey,
)
if start:
self.startup()
def startup(self) -> None:
"""
@ -734,7 +727,6 @@ class CtrlNet(CoreNetwork):
_id: int = None,
name: str = None,
hostid: int = None,
start: bool = True,
server: "DistributedServer" = None,
assign_address: bool = True,
updown_script: str = None,
@ -748,7 +740,6 @@ class CtrlNet(CoreNetwork):
:param name: node namee
:param prefix: control network ipv4 prefix
:param hostid: host id
:param start: start flag
:param server: remote server node
will run on, default is None for localhost
:param assign_address: assigned address
@ -761,7 +752,7 @@ class CtrlNet(CoreNetwork):
self.assign_address: bool = assign_address
self.updown_script: Optional[str] = updown_script
self.serverintf: Optional[str] = serverintf
super().__init__(session, _id, name, start, server)
super().__init__(session, _id, name, server)
def add_addresses(self, index: int) -> None:
"""
@ -1025,7 +1016,6 @@ class WlanNode(CoreNetwork):
session: "Session",
_id: int = None,
name: str = None,
start: bool = True,
server: "DistributedServer" = None,
policy: NetworkPolicy = None,
) -> None:
@ -1040,7 +1030,7 @@ class WlanNode(CoreNetwork):
will run on, default is None for localhost
:param policy: wlan policy
"""
super().__init__(session, _id, name, start, server, policy)
super().__init__(session, _id, name, server, policy)
# wireless and mobility models (BasicRangeModel, Ns2WaypointMobility)
self.model: Optional[WirelessModel] = None
self.mobility: Optional[WayPointMobility] = None

View file

@ -28,22 +28,19 @@ class PhysicalNode(CoreNodeBase):
_id: int = None,
name: str = None,
nodedir: str = None,
start: bool = True,
server: DistributedServer = None,
) -> None:
super().__init__(session, _id, name, start, server)
super().__init__(session, _id, name, server)
if not self.server:
raise CoreError("physical nodes must be assigned to a remote server")
self.nodedir: Optional[str] = nodedir
self.up: bool = start
self.lock: threading.RLock = threading.RLock()
self._mounts: List[Tuple[str, str]] = []
if start:
self.startup()
def startup(self) -> None:
with self.lock:
self.makenodedir()
self.up = True
def shutdown(self) -> None:
if not self.up:
@ -144,7 +141,7 @@ class PhysicalNode(CoreNodeBase):
"""
Apply tc queing disciplines using linkconfig.
"""
linux_bridge = CoreNetwork(session=self.session, start=False)
linux_bridge = CoreNetwork(self.session)
linux_bridge.up = True
linux_bridge.linkconfig(netif, options, netif2)
del linux_bridge
@ -244,7 +241,6 @@ class Rj45Node(CoreNodeBase):
_id: int = None,
name: str = None,
mtu: int = 1500,
start: bool = True,
server: DistributedServer = None,
) -> None:
"""
@ -254,19 +250,16 @@ class Rj45Node(CoreNodeBase):
:param _id: node id
:param name: node name
:param mtu: rj45 mtu
:param start: start flag
:param server: remote server node
will run on, default is None for localhost
"""
super().__init__(session, _id, name, start, server)
super().__init__(session, _id, name, server)
self.interface = CoreInterface(session, self, name, name, mtu, server)
self.interface.transport_type = TransportType.RAW
self.lock: threading.RLock = threading.RLock()
self.ifindex: Optional[int] = None
self.old_up: bool = False
self.old_addrs: List[Tuple[str, Optional[str]]] = []
if start:
self.startup()
def startup(self) -> None:
"""