2024-07-25 14:50:50 +02:00
|
|
|
from test_driver.machine import Machine, StartCommand, NixStartScript
|
|
|
|
from test_driver.logger import TerminalLogger
|
|
|
|
from pathlib import Path
|
2024-08-14 15:59:24 +02:00
|
|
|
from typing import Any
|
2024-07-25 14:50:50 +02:00
|
|
|
import os
|
2024-08-14 15:59:24 +02:00
|
|
|
import sys
|
|
|
|
import socket
|
|
|
|
import subprocess
|
|
|
|
import pty
|
|
|
|
import time
|
2024-07-25 14:50:50 +02:00
|
|
|
|
2024-08-14 15:59:24 +02:00
|
|
|
hela_system = os.getenv("HELA_SYSTEM")
|
|
|
|
client_system = os.getenv("CLIENT_SYSTEM")
|
|
|
|
jormungandr_system = os.getenv("JORMUNGANDR_SYSTEM")
|
|
|
|
interactive = os.getenv("ROUTER_INTERACTIVE")
|
2024-07-25 14:50:50 +02:00
|
|
|
|
2024-08-14 15:59:24 +02:00
|
|
|
class FileLogger(TerminalLogger):
|
|
|
|
@staticmethod
|
|
|
|
def _eprint(*args: object, **kwargs: Any) -> None:
|
|
|
|
return
|
|
|
|
|
|
|
|
class NixStartScriptSetsid(NixStartScript):
|
|
|
|
def run(
|
|
|
|
self,
|
|
|
|
state_dir: Path,
|
|
|
|
shared_dir: Path,
|
|
|
|
monitor_socket_path: Path,
|
|
|
|
qmp_socket_path: Path,
|
|
|
|
shell_socket_path: Path,
|
|
|
|
allow_reboot: bool,
|
|
|
|
) -> subprocess.Popen:
|
|
|
|
return subprocess.Popen(
|
|
|
|
self.cmd(
|
|
|
|
monitor_socket_path, qmp_socket_path, shell_socket_path, allow_reboot
|
|
|
|
),
|
|
|
|
stdin=subprocess.PIPE,
|
|
|
|
stdout=subprocess.PIPE,
|
|
|
|
shell=True,
|
|
|
|
cwd=state_dir,
|
|
|
|
env=self.build_environment(state_dir, shared_dir),
|
|
|
|
)
|
|
|
|
|
|
|
|
def make_machine(*, system: Path, name: str, out_dir: Path | None = None, tmp_dir: Path | None = None) -> Machine:
|
|
|
|
if out_dir is None:
|
|
|
|
out_dir = Path(f"{name}/out")
|
|
|
|
if tmp_dir is None:
|
|
|
|
tmp_dir = Path(f"{name}/tmp")
|
2024-07-25 14:50:50 +02:00
|
|
|
out_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
tmp_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
return Machine(
|
|
|
|
out_dir = out_dir.absolute(),
|
|
|
|
tmp_dir = tmp_dir.absolute(),
|
2024-08-14 15:59:24 +02:00
|
|
|
start_command = NixStartScript(system + f"/bin/run-{name}-vm") if not interactive else NixStartScriptSetsid(system + f"/bin/run-{name}-vm"),
|
|
|
|
logger = TerminalLogger() if not interactive else FileLogger(),
|
|
|
|
name = name,
|
|
|
|
keep_vm_state = True,
|
2024-07-25 14:50:50 +02:00
|
|
|
)
|
|
|
|
|
2024-08-14 15:59:24 +02:00
|
|
|
def vde_switch(control_socket: Path) -> subprocess.Popen:
|
|
|
|
control_socket.mkdir(parents = True, exist_ok = True)
|
|
|
|
pty_master, pty_slave = pty.openpty()
|
|
|
|
return subprocess.Popen(
|
|
|
|
["vde_switch", "-unix", str(control_socket.absolute()), "--dirmode", "0700"],
|
|
|
|
stdin=pty_slave,
|
|
|
|
)
|
|
|
|
|
|
|
|
def vde_plug_unix(path: Path, control_socket: Path, port: int | None = None) -> subprocess.Popen:
|
|
|
|
port = f"-p {port}" if port is not None else ""
|
|
|
|
return subprocess.Popen(
|
|
|
|
["socat", f"UNIX-LISTEN:{path.absolute()}", f"EXEC:vde_plug {port} {control_socket.absolute()}"],
|
|
|
|
stdin = subprocess.PIPE,
|
|
|
|
stdout = subprocess.PIPE,
|
|
|
|
stderr = subprocess.STDOUT,
|
|
|
|
)
|
|
|
|
|
|
|
|
out_dir = Path(os.getenv("out"))
|
|
|
|
def dump_to_out(path: str | Path, content: bytes):
|
|
|
|
global out_dir
|
|
|
|
|
|
|
|
if not isinstance(path, Path):
|
|
|
|
path = Path(path)
|
|
|
|
|
|
|
|
final_path = out_dir / path
|
|
|
|
final_path.parent.mkdir(parents = True, exist_ok = True)
|
|
|
|
|
|
|
|
fh = open(final_path, "w")
|
|
|
|
fh.write(content)
|
|
|
|
fh.close()
|
|
|
|
|
|
|
|
vde_hel_control_path = Path("hel/switch")
|
|
|
|
vde_hel = vde_switch(vde_hel_control_path)
|
|
|
|
|
|
|
|
vde_midgard_control_path = Path("midgard/switch")
|
|
|
|
vde_midgard = vde_switch(vde_midgard_control_path)
|
|
|
|
|
|
|
|
# kpn_link = subprocess.Popen(
|
|
|
|
# [
|
|
|
|
# "socat",
|
|
|
|
# f"UNIX-LISTEN:{Path('midgard/link.jormungandr').absolute()}",
|
|
|
|
# f"UNIX-LISTEN:{Path('midgard/link.hela').absolute()}"
|
|
|
|
# ]
|
|
|
|
# )
|
|
|
|
|
|
|
|
time.sleep(0.5)
|
|
|
|
|
|
|
|
hela = make_machine(system = hela_system, name = "hela")
|
|
|
|
hela.start()
|
|
|
|
|
|
|
|
time.sleep(0.5)
|
|
|
|
|
|
|
|
client = make_machine(system = client_system, name = "client")
|
|
|
|
client.start()
|
|
|
|
|
|
|
|
jormungandr = make_machine(system = jormungandr_system, name = "jormungandr")
|
|
|
|
jormungandr.start()
|
|
|
|
|
|
|
|
def finalize(exit_code: int) -> None:
|
|
|
|
global hela, client, jormungandr, vde_hel, vde_midgard
|
|
|
|
|
|
|
|
# subprocess.run(["cp", "hela/tmp/vm-state-hela/xchg/tcpdump-dmz-log:0.log", out_dir / "hela-tcpdump-dmz-log:0.log"], check=True)
|
|
|
|
# subprocess.run(["cp", "hela/tmp/vm-state-hela/xchg/tcpdump-dmz-log:1.log", out_dir / "hela-tcpdump-dmz-log:1.log"], check=True)
|
|
|
|
|
|
|
|
# subprocess.run(["cp", "jormungandr/tmp/vm-state-jormungandr/xchg/tcpdump-dmz-log:0.log", out_dir / "jormungandr-tcpdump-dmz-log:0.log"], check=True)
|
|
|
|
# subprocess.run(["cp", "jormungandr/tmp/vm-state-jormungandr/xchg/tcpdump-dmz-log:1.log", out_dir / "jormungandr-tcpdump-dmz-log:1.log"], check=True)
|
|
|
|
|
|
|
|
hela.shutdown()
|
|
|
|
client.shutdown()
|
|
|
|
jormungandr.shutdown()
|
|
|
|
|
|
|
|
vde_hel.terminate()
|
|
|
|
vde_midgard.terminate()
|
|
|
|
|
|
|
|
vde_hel.wait()
|
|
|
|
vde_midgard.wait()
|
|
|
|
|
|
|
|
sys.exit(exit_code)
|
|
|
|
|
|
|
|
try:
|
|
|
|
if interactive:
|
|
|
|
import ptpython
|
|
|
|
|
|
|
|
ptpython.repl.embed(globals(), locals())
|
|
|
|
else:
|
|
|
|
hela.wait_for_unit("multi-user.target")
|
|
|
|
client.wait_for_unit("multi-user.target")
|
|
|
|
jormungandr.wait_for_unit("multi-user.target")
|
|
|
|
|
|
|
|
# hela.wait_until_succeeds("ip netns exec dmz bash -c $'[ $(ip -f inet addr show ppp0 | sed -En -e \\'s/.*inet ([0-9.]+).*/\\1/p\\' | wc -l) -gt 0 ]'")
|
|
|
|
|
|
|
|
dump_to_out("client-default-route", client.succeed("ip route"))
|
|
|
|
dump_to_out("hela-default-route", hela.succeed("ip route"))
|
|
|
|
dump_to_out("hela-dmz-route", hela.succeed("ip netns exec dmz ip route"))
|
|
|
|
|
|
|
|
dump_to_out("client-default-if", client.succeed("ip addr"))
|
|
|
|
dump_to_out("hela-default-if", hela.succeed("ip addr"))
|
|
|
|
dump_to_out("hela-dmz-if", hela.succeed("ip netns exec dmz ip addr"))
|
|
|
|
|
|
|
|
client.succeed("ping -c 1 10.10.0.1")
|
|
|
|
hela.succeed("ping -c 1 10.10.0.2")
|
|
|
|
|
|
|
|
hela.succeed("ip netns exec dmz ping -c 1 10.0.0.1")
|
|
|
|
jormungandr.fail("ping -W 1 -c 1 10.67.15.1")
|
|
|
|
|
|
|
|
# client.succeed("ping -c 1 10.0.0.1")
|
|
|
|
|
|
|
|
# hela.succeed("systemd-run -u tcpdump-dmz-wan -p StandardOutput=append:/tmp/xchg/tcpdump-dmz-log:0.log -p StandardError=append:/tmp/xchg/tcpdump-dmz-log:1.log ip netns exec dmz tcpdump -i internet")
|
|
|
|
# jormungandr.succeed("systemd-run -u tcpdump-dmz-wan -p StandardOutput=append:/tmp/xchg/tcpdump-dmz-log:0.log -p StandardError=append:/tmp/xchg/tcpdump-dmz-log:1.log tcpdump -i internet")
|
|
|
|
|
|
|
|
except Exception as err:
|
|
|
|
print(err)
|
|
|
|
|
|
|
|
finalize(1)
|
|
|
|
|
|
|
|
finalize(0)
|