daemon: moved executable check to CoreEmu and separated them into their own module core.executables
This commit is contained in:
parent
c43dd60a42
commit
e0c9f9c832
13 changed files with 75 additions and 44 deletions
|
@ -52,10 +52,8 @@ class ConfigServiceManager:
|
||||||
for executable in service.executables:
|
for executable in service.executables:
|
||||||
try:
|
try:
|
||||||
utils.which(executable, required=True)
|
utils.which(executable, required=True)
|
||||||
except ValueError:
|
except CoreError as e:
|
||||||
raise CoreError(
|
raise CoreError(f"config service({service.name}): {e}")
|
||||||
f"service({service.name}) missing executable {executable}"
|
|
||||||
)
|
|
||||||
|
|
||||||
# make service available
|
# make service available
|
||||||
self.services[name] = service
|
self.services[name] = service
|
||||||
|
|
|
@ -1,17 +1,3 @@
|
||||||
from core.utils import which
|
|
||||||
|
|
||||||
COREDPY_VERSION = "@PACKAGE_VERSION@"
|
COREDPY_VERSION = "@PACKAGE_VERSION@"
|
||||||
CORE_CONF_DIR = "@CORE_CONF_DIR@"
|
CORE_CONF_DIR = "@CORE_CONF_DIR@"
|
||||||
CORE_DATA_DIR = "@CORE_DATA_DIR@"
|
CORE_DATA_DIR = "@CORE_DATA_DIR@"
|
||||||
|
|
||||||
VNODED_BIN = which("vnoded", required=True)
|
|
||||||
VCMD_BIN = which("vcmd", required=True)
|
|
||||||
SYSCTL_BIN = which("sysctl", required=True)
|
|
||||||
IP_BIN = which("ip", required=True)
|
|
||||||
ETHTOOL_BIN = which("ethtool", required=True)
|
|
||||||
TC_BIN = which("tc", required=True)
|
|
||||||
EBTABLES_BIN = which("ebtables", required=True)
|
|
||||||
MOUNT_BIN = which("mount", required=True)
|
|
||||||
UMOUNT_BIN = which("umount", required=True)
|
|
||||||
OVS_BIN = which("ovs-vsctl", required=False)
|
|
||||||
OVS_FLOW_BIN = which("ovs-ofctl", required=False)
|
|
||||||
|
|
|
@ -6,9 +6,10 @@ import sys
|
||||||
from typing import Dict, List, Type
|
from typing import Dict, List, Type
|
||||||
|
|
||||||
import core.services
|
import core.services
|
||||||
from core import configservices
|
from core import configservices, utils
|
||||||
from core.configservice.manager import ConfigServiceManager
|
from core.configservice.manager import ConfigServiceManager
|
||||||
from core.emulator.session import Session
|
from core.emulator.session import Session
|
||||||
|
from core.executables import COMMON_REQUIREMENTS, OVS_REQUIREMENTS, VCMD_REQUIREMENTS
|
||||||
from core.services.coreservices import ServiceManager
|
from core.services.coreservices import ServiceManager
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,10 +66,35 @@ class CoreEmu:
|
||||||
if custom_dir:
|
if custom_dir:
|
||||||
self.service_manager.load(custom_dir)
|
self.service_manager.load(custom_dir)
|
||||||
|
|
||||||
|
# check executables exist on path
|
||||||
|
self._validate_env()
|
||||||
|
|
||||||
# catch exit event
|
# catch exit event
|
||||||
atexit.register(self.shutdown)
|
atexit.register(self.shutdown)
|
||||||
|
|
||||||
|
def _validate_env(self) -> None:
|
||||||
|
"""
|
||||||
|
Validates executables CORE depends on exist on path.
|
||||||
|
|
||||||
|
:return: nothing
|
||||||
|
:raises core.errors.CoreError: when an executable does not exist on path
|
||||||
|
"""
|
||||||
|
for requirement in COMMON_REQUIREMENTS:
|
||||||
|
utils.which(requirement, required=True)
|
||||||
|
use_ovs = self.config.get("ovs") == "True"
|
||||||
|
if use_ovs:
|
||||||
|
for requirement in OVS_REQUIREMENTS:
|
||||||
|
utils.which(requirement, required=True)
|
||||||
|
else:
|
||||||
|
for requirement in VCMD_REQUIREMENTS:
|
||||||
|
utils.which(requirement, required=True)
|
||||||
|
|
||||||
def load_services(self) -> None:
|
def load_services(self) -> None:
|
||||||
|
"""
|
||||||
|
Loads default and custom services for use within CORE.
|
||||||
|
|
||||||
|
:return: nothing
|
||||||
|
"""
|
||||||
# load default services
|
# load default services
|
||||||
self.service_errors = core.services.load()
|
self.service_errors = core.services.load()
|
||||||
|
|
||||||
|
|
24
daemon/core/executables.py
Normal file
24
daemon/core/executables.py
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
VNODED_BIN: str = "vnoded"
|
||||||
|
VCMD_BIN: str = "vcmd"
|
||||||
|
SYSCTL_BIN: str = "sysctl"
|
||||||
|
IP_BIN: str = "ip"
|
||||||
|
ETHTOOL_BIN: str = "ethtool"
|
||||||
|
TC_BIN: str = "tc"
|
||||||
|
EBTABLES_BIN: str = "ebtables"
|
||||||
|
MOUNT_BIN: str = "mount"
|
||||||
|
UMOUNT_BIN: str = "umount"
|
||||||
|
OVS_BIN: str = "ovs-vsctl"
|
||||||
|
|
||||||
|
COMMON_REQUIREMENTS: List[str] = [
|
||||||
|
SYSCTL_BIN,
|
||||||
|
IP_BIN,
|
||||||
|
ETHTOOL_BIN,
|
||||||
|
TC_BIN,
|
||||||
|
EBTABLES_BIN,
|
||||||
|
MOUNT_BIN,
|
||||||
|
UMOUNT_BIN,
|
||||||
|
]
|
||||||
|
VCMD_REQUIREMENTS: List[str] = [VNODED_BIN, VCMD_BIN]
|
||||||
|
OVS_REQUIREMENTS: List[str] = [OVS_BIN]
|
|
@ -13,10 +13,10 @@ import netaddr
|
||||||
|
|
||||||
from core import utils
|
from core import utils
|
||||||
from core.configservice.dependencies import ConfigServiceDependencies
|
from core.configservice.dependencies import ConfigServiceDependencies
|
||||||
from core.constants import MOUNT_BIN, VNODED_BIN
|
|
||||||
from core.emulator.data import InterfaceData, LinkData, LinkOptions
|
from core.emulator.data import InterfaceData, LinkData, LinkOptions
|
||||||
from core.emulator.enumerations import LinkTypes, MessageFlags, NodeTypes
|
from core.emulator.enumerations import LinkTypes, MessageFlags, NodeTypes
|
||||||
from core.errors import CoreCommandError, CoreError
|
from core.errors import CoreCommandError, CoreError
|
||||||
|
from core.executables import MOUNT_BIN, VNODED_BIN
|
||||||
from core.nodes.client import VnodeClient
|
from core.nodes.client import VnodeClient
|
||||||
from core.nodes.interface import CoreInterface, TunTap, Veth
|
from core.nodes.interface import CoreInterface, TunTap, Veth
|
||||||
from core.nodes.netclient import LinuxNetClient, get_net_client
|
from core.nodes.netclient import LinuxNetClient, get_net_client
|
||||||
|
@ -753,7 +753,7 @@ class CoreNode(CoreNodeBase):
|
||||||
iface = self.get_iface(iface_id)
|
iface = self.get_iface(iface_id)
|
||||||
iface.set_mac(mac)
|
iface.set_mac(mac)
|
||||||
if self.up:
|
if self.up:
|
||||||
self.node_net_client.device_mac(iface.name, mac)
|
self.node_net_client.device_mac(iface.name, str(iface.mac))
|
||||||
|
|
||||||
def add_ip(self, iface_id: int, ip: str) -> None:
|
def add_ip(self, iface_id: int, ip: str) -> None:
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -5,7 +5,7 @@ The control channel can be accessed via calls using the vcmd shell.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from core import utils
|
from core import utils
|
||||||
from core.constants import VCMD_BIN
|
from core.executables import VCMD_BIN
|
||||||
|
|
||||||
|
|
||||||
class VnodeClient:
|
class VnodeClient:
|
||||||
|
|
|
@ -5,7 +5,7 @@ from typing import Callable
|
||||||
|
|
||||||
import netaddr
|
import netaddr
|
||||||
|
|
||||||
from core.constants import ETHTOOL_BIN, IP_BIN, OVS_BIN, SYSCTL_BIN, TC_BIN
|
from core.executables import ETHTOOL_BIN, IP_BIN, OVS_BIN, SYSCTL_BIN, TC_BIN
|
||||||
|
|
||||||
|
|
||||||
class LinuxNetClient:
|
class LinuxNetClient:
|
||||||
|
|
|
@ -10,7 +10,6 @@ from typing import TYPE_CHECKING, Callable, Dict, List, Optional, Type
|
||||||
import netaddr
|
import netaddr
|
||||||
|
|
||||||
from core import utils
|
from core import utils
|
||||||
from core.constants import EBTABLES_BIN, TC_BIN
|
|
||||||
from core.emulator.data import InterfaceData, LinkData, LinkOptions
|
from core.emulator.data import InterfaceData, LinkData, LinkOptions
|
||||||
from core.emulator.enumerations import (
|
from core.emulator.enumerations import (
|
||||||
LinkTypes,
|
LinkTypes,
|
||||||
|
@ -20,6 +19,7 @@ from core.emulator.enumerations import (
|
||||||
RegisterTlvs,
|
RegisterTlvs,
|
||||||
)
|
)
|
||||||
from core.errors import CoreCommandError, CoreError
|
from core.errors import CoreCommandError, CoreError
|
||||||
|
from core.executables import EBTABLES_BIN, TC_BIN
|
||||||
from core.nodes.base import CoreNetworkBase
|
from core.nodes.base import CoreNetworkBase
|
||||||
from core.nodes.interface import CoreInterface, GreTap, Veth
|
from core.nodes.interface import CoreInterface, GreTap, Veth
|
||||||
from core.nodes.netclient import get_net_client
|
from core.nodes.netclient import get_net_client
|
||||||
|
|
|
@ -7,11 +7,11 @@ import os
|
||||||
import threading
|
import threading
|
||||||
from typing import IO, TYPE_CHECKING, List, Optional, Tuple
|
from typing import IO, TYPE_CHECKING, List, Optional, Tuple
|
||||||
|
|
||||||
from core.constants import MOUNT_BIN, UMOUNT_BIN
|
|
||||||
from core.emulator.data import InterfaceData, LinkOptions
|
from core.emulator.data import InterfaceData, LinkOptions
|
||||||
from core.emulator.distributed import DistributedServer
|
from core.emulator.distributed import DistributedServer
|
||||||
from core.emulator.enumerations import NodeTypes, TransportType
|
from core.emulator.enumerations import NodeTypes, TransportType
|
||||||
from core.errors import CoreCommandError, CoreError
|
from core.errors import CoreCommandError, CoreError
|
||||||
|
from core.executables import MOUNT_BIN, UMOUNT_BIN
|
||||||
from core.nodes.base import CoreNetworkBase, CoreNodeBase
|
from core.nodes.base import CoreNetworkBase, CoreNodeBase
|
||||||
from core.nodes.interface import CoreInterface
|
from core.nodes.interface import CoreInterface
|
||||||
from core.nodes.network import CoreNetwork, GreTap
|
from core.nodes.network import CoreNetwork, GreTap
|
||||||
|
@ -76,7 +76,7 @@ class PhysicalNode(CoreNodeBase):
|
||||||
iface = self.get_iface(iface_id)
|
iface = self.get_iface(iface_id)
|
||||||
iface.set_mac(mac)
|
iface.set_mac(mac)
|
||||||
if self.up:
|
if self.up:
|
||||||
self.net_client.device_mac(iface.name, mac)
|
self.net_client.device_mac(iface.name, str(iface.mac))
|
||||||
|
|
||||||
def add_ip(self, iface_id: int, ip: str) -> None:
|
def add_ip(self, iface_id: int, ip: str) -> None:
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -13,10 +13,9 @@ import time
|
||||||
from typing import TYPE_CHECKING, Dict, Iterable, List, Optional, Set, Tuple, Type
|
from typing import TYPE_CHECKING, Dict, Iterable, List, Optional, Set, Tuple, Type
|
||||||
|
|
||||||
from core import utils
|
from core import utils
|
||||||
from core.constants import which
|
|
||||||
from core.emulator.data import FileData
|
from core.emulator.data import FileData
|
||||||
from core.emulator.enumerations import ExceptionLevels, MessageFlags, RegisterTlvs
|
from core.emulator.enumerations import ExceptionLevels, MessageFlags, RegisterTlvs
|
||||||
from core.errors import CoreCommandError
|
from core.errors import CoreCommandError, CoreError
|
||||||
from core.nodes.base import CoreNode
|
from core.nodes.base import CoreNode
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
@ -262,7 +261,10 @@ class ServiceManager:
|
||||||
|
|
||||||
# validate dependent executables are present
|
# validate dependent executables are present
|
||||||
for executable in service.executables:
|
for executable in service.executables:
|
||||||
which(executable, required=True)
|
try:
|
||||||
|
utils.which(executable, required=True)
|
||||||
|
except CoreError as e:
|
||||||
|
raise CoreError(f"service({name}): {e}")
|
||||||
|
|
||||||
# validate service on load succeeds
|
# validate service on load succeeds
|
||||||
try:
|
try:
|
||||||
|
@ -300,7 +302,7 @@ class ServiceManager:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cls.add(service)
|
cls.add(service)
|
||||||
except ValueError as e:
|
except (CoreError, ValueError) as e:
|
||||||
service_errors.append(service.name)
|
service_errors.append(service.name)
|
||||||
logging.debug("not loading service(%s): %s", service.name, e)
|
logging.debug("not loading service(%s): %s", service.name, e)
|
||||||
return service_errors
|
return service_errors
|
||||||
|
|
|
@ -5,8 +5,9 @@ from typing import Optional, Tuple
|
||||||
|
|
||||||
import netaddr
|
import netaddr
|
||||||
|
|
||||||
from core import constants, utils
|
from core import utils
|
||||||
from core.errors import CoreCommandError
|
from core.errors import CoreCommandError
|
||||||
|
from core.executables import SYSCTL_BIN
|
||||||
from core.nodes.base import CoreNode
|
from core.nodes.base import CoreNode
|
||||||
from core.services.coreservices import CoreService, ServiceMode
|
from core.services.coreservices import CoreService, ServiceMode
|
||||||
|
|
||||||
|
@ -47,19 +48,13 @@ class IPForwardService(UtilService):
|
||||||
%(sysctl)s -w net.ipv4.conf.all.rp_filter=0
|
%(sysctl)s -w net.ipv4.conf.all.rp_filter=0
|
||||||
%(sysctl)s -w net.ipv4.conf.default.rp_filter=0
|
%(sysctl)s -w net.ipv4.conf.default.rp_filter=0
|
||||||
""" % {
|
""" % {
|
||||||
"sysctl": constants.SYSCTL_BIN
|
"sysctl": SYSCTL_BIN
|
||||||
}
|
}
|
||||||
for iface in node.get_ifaces():
|
for iface in node.get_ifaces():
|
||||||
name = utils.sysctl_devname(iface.name)
|
name = utils.sysctl_devname(iface.name)
|
||||||
cfg += "%s -w net.ipv4.conf.%s.forwarding=1\n" % (
|
cfg += "%s -w net.ipv4.conf.%s.forwarding=1\n" % (SYSCTL_BIN, name)
|
||||||
constants.SYSCTL_BIN,
|
cfg += "%s -w net.ipv4.conf.%s.send_redirects=0\n" % (SYSCTL_BIN, name)
|
||||||
name,
|
cfg += "%s -w net.ipv4.conf.%s.rp_filter=0\n" % (SYSCTL_BIN, name)
|
||||||
)
|
|
||||||
cfg += "%s -w net.ipv4.conf.%s.send_redirects=0\n" % (
|
|
||||||
constants.SYSCTL_BIN,
|
|
||||||
name,
|
|
||||||
)
|
|
||||||
cfg += "%s -w net.ipv4.conf.%s.rp_filter=0\n" % (constants.SYSCTL_BIN, name)
|
|
||||||
return cfg
|
return cfg
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ from typing import (
|
||||||
|
|
||||||
import netaddr
|
import netaddr
|
||||||
|
|
||||||
from core.errors import CoreCommandError
|
from core.errors import CoreCommandError, CoreError
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from core.emulator.session import Session
|
from core.emulator.session import Session
|
||||||
|
@ -154,7 +154,7 @@ def which(command: str, required: bool) -> str:
|
||||||
"""
|
"""
|
||||||
found_path = shutil.which(command)
|
found_path = shutil.which(command)
|
||||||
if found_path is None and required:
|
if found_path is None and required:
|
||||||
raise ValueError(f"failed to find required executable({command}) in path")
|
raise CoreError(f"failed to find required executable({command}) in path")
|
||||||
return found_path
|
return found_path
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@ import netaddr
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
|
|
||||||
from core import utils
|
from core import utils
|
||||||
from core.constants import IP_BIN
|
|
||||||
from core.emane.nodes import EmaneNet
|
from core.emane.nodes import EmaneNet
|
||||||
|
from core.executables import IP_BIN
|
||||||
from core.nodes.base import CoreNodeBase, NodeBase
|
from core.nodes.base import CoreNodeBase, NodeBase
|
||||||
from core.nodes.interface import CoreInterface
|
from core.nodes.interface import CoreInterface
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue