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:
Blake Harnden 2020-01-17 21:09:51 -08:00
parent 191a9e9909
commit dcc683dd38
8 changed files with 41 additions and 37 deletions

View file

@ -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:

View file

@ -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

View file

@ -1,6 +1,5 @@
#!/bin/sh
# auto-generated by DefaultRoute service
# config: ${config}
% for address in addresses:
ip route add default via ${address}
% endfor

View file

@ -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

View file

@ -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

View file

@ -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]:
"""

View file

@ -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:
"""

View file

@ -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()