From a840857ee511a25774de885589b49657d1e95eb5 Mon Sep 17 00:00:00 2001 From: Maria Matejka Date: Thu, 27 Mar 2025 14:53:44 +0100 Subject: [PATCH] machine setup --- tools/flock | 2 +- tools/netlabflock/Suite.py | 131 +++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 tools/netlabflock/Suite.py diff --git a/tools/flock b/tools/flock index 76391bf20..2c2930843 160000 --- a/tools/flock +++ b/tools/flock @@ -1 +1 @@ -Subproject commit 76391bf209d712b305743f1f2d5acbb214b0d6b6 +Subproject commit 2c2930843b59f81de2b08f3c94b1dfda6b4bf499 diff --git a/tools/netlabflock/Suite.py b/tools/netlabflock/Suite.py new file mode 100644 index 000000000..eb31f4705 --- /dev/null +++ b/tools/netlabflock/Suite.py @@ -0,0 +1,131 @@ +from . import NetlabFlock +from . import flock + +import asyncio +import os +import pathlib +import re + +class TaskTreeNode: + def __init__(self, run, *deps): + self.run = run + self.deps = deps + self.done = asyncio.get_event_loop().create_future() + + async def run(self, *args, **kwargs): + await asyncio.gather(*self.deps) + self.done.set_result(await self.run(*args, **kwargs)) + +class Suite: + def __init__(self, name: str): + self.name = name + self.dir = NetlabFlock.netlabdir / name + if not self.dir.exists(): + raise Exception(f"Suite dir {self.dir} not found") + + self.rundir = pathlib.Path(os.environ['XDG_RUNTIME_DIR']) / "netlabflock" + + def help(self, *args: str): + print("Usage: python3 -m netlabflock (start|stop|save|check) suitename [targetdir]") + + async def start(self): + # Load config + commands = [] + mach_setup = {} + + with open(self.dir / "config") as cf: + fixed = re.sub("\\\\\n", "", cf.read()) + + self.machines = None + + netlab_init_seen = False + + for cmd in fixed.split("\n"): + cmd = cmd.strip() + if cmd == "": + continue + + if cmd.startswith("NETLAB_NODES="): + assert(not netlab_init_seen) + self.machines = re.sub('^[^"]*"(.*?)"[^"]*', '\\1', cmd).split() + for m in self.machines: + ms = TaskTreeNode(self.machine_setup) + mach_setup[m] = ms + commands.append(ms.run(m)) + continue + + if cmd == "netlab_init": + assert(not netlab_init_seen) + netlab_init_seen = True + continue + + cmd, *args = cmd.split() + if cmd == "if_dummy": + commands.append(TaskTreeNode(self.if_dummy, mach_setup[args[0]].done).run(*args)) + elif cmd == "if_veth": + commands.append(TaskTreeNode(self.if_veth, mach_setup[args[0]].done, mach_setup[args[2]].done).run(*args)) + elif cmd == "netlab_start": + pass + else: + print(f"Unknown command {cmd}") + + assert(netlab_init_seen) + + # Prepare Flock simulation + flock.create(self.targetdir) + + await asyncio.gather(*commands) + + + async def stop(self): + print("stop", self.targetdir) + flock.delete(self.targetdir) + + async def save(self): + ... + + async def check(self): + ... + + async def exec(self, cmd: str, targetdir: str = None): + if targetdir is None: + if not self.rundir.exists(): + self.rundir.mkdir() + + self.targetdir = self.rundir / self.name + else: + self.targetdir = pathlib.Path(targetdir) + + await { + "start": self.start, + "stop": self.stop, + "save": self.save, + "check": self.check, + }[cmd]() + + async def machine_setup(self, machine: str): + # TODO: do this async + print(f"Start {machine}") + flock.start(self.targetdir, machine) + sp = await asyncio.create_subprocess_exec( + str(NetlabFlock.toolsdir / "flock" / "box" / "flock-shell"), + stdin=asyncio.subprocess.PIPE, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + cwd=str(self.targetdir / machine)) + + out, err = await sp.communicate(""" +sysctl net.ipv4.ip_forward=1 +sysctl net.ipv4.tcp_l3mdev_accept=0 +sysctl net.ipv6.conf.all.forwarding=1 +sysctl net.mpls.platform_labels=16384 +ip link set lo up +""".encode()) + + return (out, err) + + async def if_dummy(self, machine: str, name: str, ip4pref: str, ip6pref: str): + ... + + async def if_veth(self, m1: str, n1: str, m2: str, n2: str, ip4pref: str, ip6pref: str = None): + ... -- 2.47.2