diff --git a/daemon/core/emulator/coreemu.py b/daemon/core/emulator/coreemu.py index 4041cf40..6c6f1418 100644 --- a/daemon/core/emulator/coreemu.py +++ b/daemon/core/emulator/coreemu.py @@ -61,6 +61,9 @@ class CoreEmu: self.service_manager = ConfigServiceManager() config_services_path = os.path.abspath(os.path.dirname(configservices.__file__)) self.service_manager.load(config_services_path) + custom_dir = self.config.get("custom_config_services_dir") + if custom_dir: + self.service_manager.load(custom_dir) # catch exit event atexit.register(self.shutdown) diff --git a/daemon/core/nodes/netclient.py b/daemon/core/nodes/netclient.py index 40d26f7f..0ad62e50 100644 --- a/daemon/core/nodes/netclient.py +++ b/daemon/core/nodes/netclient.py @@ -222,6 +222,7 @@ class LinuxNetClient: self.run(f"{IP_BIN} link set {name} type bridge stp_state 0") self.run(f"{IP_BIN} link set {name} type bridge forward_delay 0") self.run(f"{IP_BIN} link set {name} type bridge mcast_snooping 0") + self.run(f"{IP_BIN} link set {name} type bridge group_fwd_mask 65528") self.device_up(name) def delete_bridge(self, name: str) -> None: diff --git a/daemon/data/core.conf b/daemon/data/core.conf index aa1238d5..13b50785 100644 --- a/daemon/data/core.conf +++ b/daemon/data/core.conf @@ -14,6 +14,7 @@ frr_sbin_search = "/usr/local/sbin /usr/sbin /usr/lib/frr" # this may be a comma-separated list, and directory names should be unique # and not named 'services' #custom_services_dir = /home/username/.core/myservices +#custom_config_services_dir = /home/username/.coretk/custom_services # uncomment to establish a standalone control backchannel for accessing nodes # (overriden by the session option of the same name) diff --git a/daemon/scripts/core-service-update b/daemon/scripts/core-service-update new file mode 100755 index 00000000..6d0be06c --- /dev/null +++ b/daemon/scripts/core-service-update @@ -0,0 +1,51 @@ +#!/usr/bin/env python +import argparse +import re +from io import TextIOWrapper + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser( + description=f"Helps transition older CORE services to work with newer versions") + parser.add_argument("-f", "--file", dest="file", type=argparse.FileType("r"), + help=f"service file to update") + return parser.parse_args() + + +def update_service(service_file: TextIOWrapper) -> None: + update = [] + for line in service_file.readlines(): + # update service attributes + line = re.sub(r"^(\s+)_([a-z])", r"\1\2", line) + # rename dirs to directories + line = re.sub(r"^(\s+)dirs", r"\1directories", line) + # fix import states for service + line = re.sub(r"^.+import.+CoreService.+$", + r"from core.services.coreservices import CoreService", line) + # fix method signatures + line = re.sub(r"def generateconfig\(cls, node, filename, services\)", + r"def generate_config(cls, node, filename)", line) + line = re.sub(r"def getvalidate\(cls, node, services\)", + r"def get_validate(cls, node)", line) + line = re.sub(r"def getstartup\(cls, node, services\)", + r"def get_startup(cls, node)", line) + line = re.sub(r"def getconfigfilenames\(cls, nodenum, services\)", + r"def get_configs(cls, node)", line) + # remove unwanted lines + if re.search(r"addservice\(", line): + continue + if re.search(r"from.+\.ipaddr|import ipaddr", line): + continue + if re.search(r"from.+\.ipaddress|import ipaddress", line): + continue + # add modified line to make updated copy + update.append(line) + service_file.close() + + with open(f"{service_file.name}.update", "w") as f: + f.writelines(update) + + +if __name__ == "__main__": + args = parse_args() + update_service(args.file)