5 from pathlib
import Path
7 from test_driver
.logger
import AbstractLogger
11 """This class handles a VLAN that the run-vm scripts identify via its
12 number handles. The network's lifetime equals the object's lifetime.
18 process
: subprocess
.Popen
22 logger
: AbstractLogger
24 def __repr__(self
) -> str:
25 return f
"<Vlan Nr. {self.nr}>"
27 def __init__(self
, nr
: int, tmp_dir
: Path
, logger
: AbstractLogger
):
29 self
.socket_dir
= tmp_dir
/ f
"vde{self.nr}.ctl"
32 # TODO: don't side-effect environment here
33 os
.environ
[f
"QEMU_VDE_SOCKET_{self.nr}"] = str(self
.socket_dir
)
35 self
.logger
.info("start vlan")
36 pty_master
, pty_slave
= pty
.openpty()
38 # The --hub is required for the scenario determined by
39 # nixos/tests/networking.nix vlan-ping.
40 # VLAN Tagged traffic (802.1Q) seams to be blocked if a vde_switch is
41 # used without the hub mode (flood packets to all ports).
42 self
.process
= subprocess
.Popen(
43 ["vde_switch", "-s", self
.socket_dir
, "--dirmode", "0700", "--hub"],
45 stdout
=subprocess
.PIPE
,
46 stderr
=subprocess
.PIPE
,
49 self
.pid
= self
.process
.pid
50 self
.fd
= os
.fdopen(pty_master
, "w")
51 self
.fd
.write("version\n")
53 # TODO: perl version checks if this can be read from
54 # an if not, dies. we could hang here forever. Fix it.
55 assert self
.process
.stdout
is not None
56 self
.process
.stdout
.readline()
57 if not (self
.socket_dir
/ "ctl").exists():
58 self
.logger
.error("cannot start vde_switch")
60 self
.logger
.info(f
"running vlan (pid {self.pid}; ctl {self.socket_dir})")
62 def __del__(self
) -> None:
63 self
.logger
.info(f
"kill vlan (pid {self.pid})")
65 self
.process
.terminate()