daemon: added usage of ABC to NodeBase, CoreNodeBase, and CoreNetworkBase to help enforce accounting for abstract functions

This commit is contained in:
Blake Harnden 2020-06-14 13:35:06 -07:00
parent f5916fab5b
commit 0462c1b084
3 changed files with 92 additions and 76 deletions

View file

@ -88,6 +88,9 @@ class EmaneNet(CoreNetworkBase):
def unlink(self, netif1: CoreInterface, netif2: CoreInterface) -> None: def unlink(self, netif1: CoreInterface, netif2: CoreInterface) -> None:
pass pass
def linknet(self, net: "CoreNetworkBase") -> CoreInterface:
raise CoreError("emane networks cannot be linked to other networks")
def updatemodel(self, config: Dict[str, str]) -> None: def updatemodel(self, config: Dict[str, str]) -> None:
if not self.model: if not self.model:
raise CoreError(f"no model set to update for node({self.name})") raise CoreError(f"no model set to update for node({self.name})")

View file

@ -1,7 +1,7 @@
""" """
Defines the base logic for nodes used within core. Defines the base logic for nodes used within core.
""" """
import abc
import logging import logging
import os import os
import shutil import shutil
@ -34,7 +34,7 @@ if TYPE_CHECKING:
_DEFAULT_MTU = 1500 _DEFAULT_MTU = 1500
class NodeBase: class NodeBase(abc.ABC):
""" """
Base class for CORE nodes (nodes and networks) Base class for CORE nodes (nodes and networks)
""" """
@ -78,6 +78,7 @@ class NodeBase:
use_ovs = session.options.get_config("ovs") == "True" use_ovs = session.options.get_config("ovs") == "True"
self.net_client: LinuxNetClient = get_net_client(use_ovs, self.host_cmd) self.net_client: LinuxNetClient = get_net_client(use_ovs, self.host_cmd)
@abc.abstractmethod
def startup(self) -> None: def startup(self) -> None:
""" """
Each object implements its own startup method. Each object implements its own startup method.
@ -86,6 +87,7 @@ class NodeBase:
""" """
raise NotImplementedError raise NotImplementedError
@abc.abstractmethod
def shutdown(self) -> None: def shutdown(self) -> None:
""" """
Each object implements its own shutdown method. Each object implements its own shutdown method.
@ -267,12 +269,74 @@ class CoreNodeBase(NodeBase):
self.nodedir: Optional[str] = None self.nodedir: Optional[str] = None
self.tmpnodedir: bool = False self.tmpnodedir: bool = False
@abc.abstractmethod
def startup(self) -> None: def startup(self) -> None:
raise NotImplementedError raise NotImplementedError
@abc.abstractmethod
def shutdown(self) -> None: def shutdown(self) -> None:
raise NotImplementedError raise NotImplementedError
@abc.abstractmethod
def nodefile(self, filename: str, contents: str, mode: int = 0o644) -> None:
"""
Create a node file with a given mode.
:param filename: name of file to create
:param contents: contents of file
:param mode: mode for file
:return: nothing
"""
raise NotImplementedError
@abc.abstractmethod
def addfile(self, srcname: str, filename: str) -> None:
"""
Add a file.
:param srcname: source file name
:param filename: file name to add
:return: nothing
:raises CoreCommandError: when a non-zero exit status occurs
"""
raise NotImplementedError
@abc.abstractmethod
def cmd(self, args: str, wait: bool = True, shell: bool = False) -> str:
"""
Runs a command within a node container.
:param args: command to run
:param wait: True to wait for status, False otherwise
:param shell: True to use shell, False otherwise
:return: combined stdout and stderr
:raises CoreCommandError: when a non-zero exit status occurs
"""
raise NotImplementedError
@abc.abstractmethod
def termcmdstring(self, sh: str) -> str:
"""
Create a terminal command string.
:param sh: shell to execute command in
:return: str
"""
raise NotImplementedError
@abc.abstractmethod
def newnetif(
self, net: "CoreNetworkBase", interface_data: InterfaceData
) -> CoreInterface:
"""
Create a new network interface.
:param net: network to associate with
:param interface_data: interface data for new interface
:return: interface index
"""
raise NotImplementedError
def add_config_service(self, service_class: "ConfigServiceType") -> None: def add_config_service(self, service_class: "ConfigServiceType") -> None:
""" """
Adds a configuration service to the node. Adds a configuration service to the node.
@ -432,61 +496,6 @@ class CoreNodeBase(NodeBase):
common.append((netif1.net, netif1, netif2)) common.append((netif1.net, netif1, netif2))
return common return common
def nodefile(self, filename: str, contents: str, mode: int = 0o644) -> None:
"""
Create a node file with a given mode.
:param filename: name of file to create
:param contents: contents of file
:param mode: mode for file
:return: nothing
"""
raise NotImplementedError
def addfile(self, srcname: str, filename: str) -> None:
"""
Add a file.
:param srcname: source file name
:param filename: file name to add
:return: nothing
:raises CoreCommandError: when a non-zero exit status occurs
"""
raise NotImplementedError
def cmd(self, args: str, wait: bool = True, shell: bool = False) -> str:
"""
Runs a command within a node container.
:param args: command to run
:param wait: True to wait for status, False otherwise
:param shell: True to use shell, False otherwise
:return: combined stdout and stderr
:raises CoreCommandError: when a non-zero exit status occurs
"""
raise NotImplementedError
def termcmdstring(self, sh: str) -> str:
"""
Create a terminal command string.
:param sh: shell to execute command in
:return: str
"""
raise NotImplementedError
def newnetif(
self, net: "CoreNetworkBase", interface_data: InterfaceData
) -> CoreInterface:
"""
Create a new network interface.
:param net: network to associate with
:param interface_data: interface data for new interface
:return: interface index
"""
raise NotImplementedError
class CoreNode(CoreNodeBase): class CoreNode(CoreNodeBase):
""" """
@ -1002,6 +1011,7 @@ class CoreNetworkBase(NodeBase):
self._linked = {} self._linked = {}
self._linked_lock = threading.Lock() self._linked_lock = threading.Lock()
@abc.abstractmethod
def startup(self) -> None: def startup(self) -> None:
""" """
Each object implements its own startup method. Each object implements its own startup method.
@ -1010,6 +1020,7 @@ class CoreNetworkBase(NodeBase):
""" """
raise NotImplementedError raise NotImplementedError
@abc.abstractmethod
def shutdown(self) -> None: def shutdown(self) -> None:
""" """
Each object implements its own shutdown method. Each object implements its own shutdown method.
@ -1018,6 +1029,7 @@ class CoreNetworkBase(NodeBase):
""" """
raise NotImplementedError raise NotImplementedError
@abc.abstractmethod
def linknet(self, net: "CoreNetworkBase") -> CoreInterface: def linknet(self, net: "CoreNetworkBase") -> CoreInterface:
""" """
Link network to another. Link network to another.
@ -1025,7 +1037,21 @@ class CoreNetworkBase(NodeBase):
:param net: network to link with :param net: network to link with
:return: created interface :return: created interface
""" """
pass raise NotImplementedError
@abc.abstractmethod
def linkconfig(
self, netif: CoreInterface, options: LinkOptions, netif2: CoreInterface = None
) -> None:
"""
Configure link parameters by applying tc queuing disciplines on the interface.
:param netif: interface one
:param options: options for configuring link
:param netif2: interface two
:return: nothing
"""
raise NotImplementedError
def getlinknetif(self, net: "CoreNetworkBase") -> Optional[CoreInterface]: def getlinknetif(self, net: "CoreNetworkBase") -> Optional[CoreInterface]:
""" """
@ -1156,19 +1182,6 @@ class CoreNetworkBase(NodeBase):
return all_links return all_links
def linkconfig(
self, netif: CoreInterface, options: LinkOptions, netif2: CoreInterface = None
) -> None:
"""
Configure link parameters by applying tc queuing disciplines on the interface.
:param netif: interface one
:param options: options for configuring link
:param netif2: interface two
:return: nothing
"""
raise NotImplementedError
class Position: class Position:
""" """

View file

@ -226,7 +226,7 @@ class PhysicalNode(CoreNodeBase):
return self.host_cmd(args, wait=wait) return self.host_cmd(args, wait=wait)
def addfile(self, srcname: str, filename: str) -> None: def addfile(self, srcname: str, filename: str) -> None:
raise NotImplementedError raise CoreError("physical node does not support addfile")
class Rj45Node(CoreNodeBase): class Rj45Node(CoreNodeBase):
@ -449,13 +449,13 @@ class Rj45Node(CoreNodeBase):
self.interface.setposition() self.interface.setposition()
def termcmdstring(self, sh: str) -> str: def termcmdstring(self, sh: str) -> str:
raise NotImplementedError raise CoreError("rj45 does not support terminal commands")
def addfile(self, srcname: str, filename: str) -> None: def addfile(self, srcname: str, filename: str) -> None:
raise NotImplementedError raise CoreError("rj45 does not support addfile")
def nodefile(self, filename: str, contents: str, mode: int = 0o644) -> None: def nodefile(self, filename: str, contents: str, mode: int = 0o644) -> None:
raise NotImplementedError raise CoreError("rj45 does not support nodefile")
def cmd(self, args: str, wait: bool = True, shell: bool = False) -> str: def cmd(self, args: str, wait: bool = True, shell: bool = False) -> str:
raise NotImplementedError raise CoreError("rj45 does not support cmds")