added config service manager to CoreEmu and made it possible to create a session and nodes with config services from a script
This commit is contained in:
parent
191a9e9909
commit
dcc683dd38
8 changed files with 41 additions and 37 deletions
|
@ -40,12 +40,6 @@ class ConfigService(abc.ABC):
|
|||
configs = self.default_configs[:]
|
||||
self._define_config(configs)
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash(self.name)
|
||||
|
||||
def __eq__(self, other: "ConfigService") -> bool:
|
||||
return self.name == other.name
|
||||
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def name(self) -> str:
|
||||
|
|
|
@ -1,23 +1,21 @@
|
|||
import logging
|
||||
import pathlib
|
||||
from typing import List
|
||||
from typing import List, Type
|
||||
|
||||
from core import utils
|
||||
from core.configservice.base import ConfigService
|
||||
from core.errors import CoreError
|
||||
from core.nodes.base import CoreNode
|
||||
|
||||
|
||||
class ConfigServiceManager:
|
||||
def __init__(self):
|
||||
self.services = {}
|
||||
|
||||
def set_service(self, node: CoreNode, name: str) -> None:
|
||||
def get_service(self, name: str) -> Type[ConfigService]:
|
||||
service_class = self.services.get(name)
|
||||
if service_class in node.config_services:
|
||||
raise CoreError(f"node already has service {name}")
|
||||
service = service_class(node)
|
||||
node.config_services.add(service)
|
||||
if service_class is None:
|
||||
raise CoreError(f"service does not exit {name}")
|
||||
return service_class
|
||||
|
||||
def add(self, service: ConfigService) -> None:
|
||||
name = service.name
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#!/bin/sh
|
||||
# auto-generated by DefaultRoute service
|
||||
# config: ${config}
|
||||
% for address in addresses:
|
||||
ip route add default via ${address}
|
||||
% endfor
|
||||
|
|
|
@ -6,6 +6,8 @@ import sys
|
|||
from typing import Mapping, Type
|
||||
|
||||
import core.services
|
||||
from core import configservices
|
||||
from core.configservice.manager import ConfigServiceManager
|
||||
from core.emulator.session import Session
|
||||
from core.services.coreservices import ServiceManager
|
||||
|
||||
|
@ -55,6 +57,11 @@ class CoreEmu:
|
|||
self.service_errors = []
|
||||
self.load_services()
|
||||
|
||||
# config services
|
||||
self.service_manager = ConfigServiceManager()
|
||||
config_services_path = os.path.abspath(os.path.dirname(configservices.__file__))
|
||||
self.service_manager.load(config_services_path)
|
||||
|
||||
# catch exit event
|
||||
atexit.register(self.shutdown)
|
||||
|
||||
|
@ -97,6 +104,7 @@ class CoreEmu:
|
|||
while _id in self.sessions:
|
||||
_id += 1
|
||||
session = _cls(_id, config=self.config)
|
||||
session.service_manager = self.service_manager
|
||||
logging.info("created session: %s", _id)
|
||||
self.sessions[_id] = session
|
||||
return session
|
||||
|
|
|
@ -75,6 +75,7 @@ class NodeOptions:
|
|||
self.icon = None
|
||||
self.opaque = None
|
||||
self.services = []
|
||||
self.config_services = []
|
||||
self.x = None
|
||||
self.y = None
|
||||
self.lat = None
|
||||
|
|
|
@ -161,6 +161,9 @@ class Session:
|
|||
"host": ("DefaultRoute", "SSH"),
|
||||
}
|
||||
|
||||
# config services
|
||||
self.service_manager = None
|
||||
|
||||
@classmethod
|
||||
def get_node_class(cls, _type: NodeTypes) -> Type[NodeBase]:
|
||||
"""
|
||||
|
@ -726,6 +729,11 @@ class Session:
|
|||
logging.debug("set node type: %s", node.type)
|
||||
self.services.add_services(node, node.type, options.services)
|
||||
|
||||
# add config services
|
||||
for name in options.config_services:
|
||||
service_class = self.service_manager.get_service(name)
|
||||
node.add_config_service(service_class)
|
||||
|
||||
# ensure default emane configuration
|
||||
if isinstance(node, EmaneNet) and options.emane:
|
||||
self.emane.set_model_config(_id, options.emane)
|
||||
|
@ -1602,7 +1610,8 @@ class Session:
|
|||
logging.info("booting node(%s): %s", node.name, [x.name for x in node.services])
|
||||
self.add_remove_control_interface(node=node, remove=False)
|
||||
self.services.boot_services(node)
|
||||
node.start_config_services()
|
||||
for service in node.config_services.values():
|
||||
service.start()
|
||||
|
||||
def boot_nodes(self) -> List[Exception]:
|
||||
"""
|
||||
|
|
|
@ -6,7 +6,7 @@ import logging
|
|||
import os
|
||||
import shutil
|
||||
import threading
|
||||
from typing import TYPE_CHECKING, Dict, List, Optional, Tuple
|
||||
from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, Type
|
||||
|
||||
import netaddr
|
||||
|
||||
|
@ -14,7 +14,7 @@ from core import utils
|
|||
from core.constants import MOUNT_BIN, VNODED_BIN
|
||||
from core.emulator.data import LinkData, NodeData
|
||||
from core.emulator.enumerations import LinkTypes, NodeTypes
|
||||
from core.errors import CoreCommandError
|
||||
from core.errors import CoreCommandError, CoreError
|
||||
from core.nodes import client
|
||||
from core.nodes.interface import CoreInterface, TunTap, Veth
|
||||
from core.nodes.netclient import LinuxNetClient, get_net_client
|
||||
|
@ -22,6 +22,9 @@ from core.nodes.netclient import LinuxNetClient, get_net_client
|
|||
if TYPE_CHECKING:
|
||||
from core.emulator.distributed import DistributedServer
|
||||
from core.emulator.session import Session
|
||||
from core.configservice.base import ConfigService
|
||||
|
||||
ConfigServiceType = Type[ConfigService]
|
||||
|
||||
_DEFAULT_MTU = 1500
|
||||
|
||||
|
@ -277,18 +280,21 @@ class CoreNodeBase(NodeBase):
|
|||
"""
|
||||
super().__init__(session, _id, name, start, server)
|
||||
self.services = []
|
||||
self.config_services = set()
|
||||
self.config_services = {}
|
||||
self.nodedir = None
|
||||
self.tmpnodedir = False
|
||||
|
||||
def start_config_services(self) -> None:
|
||||
"""
|
||||
Start configuration services for this node.
|
||||
def add_config_service(self, service_class: "ConfigServiceType"):
|
||||
name = service_class.name
|
||||
if name in self.config_services:
|
||||
raise CoreError(f"node({self.name}) already has service({name})")
|
||||
self.config_services[name] = service_class(self)
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
for service in self.config_services:
|
||||
service.start()
|
||||
def set_service_config(self, name: str, data: Dict[str, str]) -> None:
|
||||
service = self.config_services.get(name)
|
||||
if service is None:
|
||||
raise CoreError(f"node({self.name}) does not have service({name})")
|
||||
service.set_config(data)
|
||||
|
||||
def makenodedir(self) -> None:
|
||||
"""
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
import logging
|
||||
import os
|
||||
|
||||
from core import configservices
|
||||
from core.configservice.manager import ConfigServiceManager
|
||||
from core.emulator.coreemu import CoreEmu
|
||||
from core.emulator.emudata import IpPrefixes, NodeOptions
|
||||
from core.emulator.enumerations import EventTypes, NodeTypes
|
||||
|
@ -13,13 +10,13 @@ if __name__ == "__main__":
|
|||
# setup basic network
|
||||
prefixes = IpPrefixes(ip4_prefix="10.83.0.0/16")
|
||||
options = NodeOptions(model="nothing")
|
||||
# options.services = []
|
||||
coreemu = CoreEmu()
|
||||
session = coreemu.create_session()
|
||||
session.set_state(EventTypes.CONFIGURATION_STATE)
|
||||
switch = session.add_node(_type=NodeTypes.SWITCH)
|
||||
|
||||
# node one
|
||||
options.config_services = ["DefaultRoute", "IPForward"]
|
||||
node_one = session.add_node(options=options)
|
||||
interface = prefixes.create_interface(node_one)
|
||||
session.add_link(node_one.id, switch.id, interface_one=interface)
|
||||
|
@ -29,14 +26,6 @@ if __name__ == "__main__":
|
|||
interface = prefixes.create_interface(node_two)
|
||||
session.add_link(node_two.id, switch.id, interface_one=interface)
|
||||
|
||||
# manager load config services
|
||||
manager = ConfigServiceManager()
|
||||
path = os.path.dirname(os.path.abspath(configservices.__file__))
|
||||
manager.load(path)
|
||||
|
||||
manager.set_service(node_one, "DefaultRoute")
|
||||
manager.set_service(node_one, "IPForward")
|
||||
|
||||
# start session and run services
|
||||
session.instantiate()
|
||||
|
||||
|
|
Loading…
Reference in a new issue