From 04befb6328331a7002db66863bf3ce6304056b0b Mon Sep 17 00:00:00 2001 From: Else Someone Date: Mon, 23 Feb 2026 06:35:32 +0200 Subject: [PATCH] ch-runner: run CH in bwrap Albeit rather relaxed --- pkgs/taps/package.nix | 2 + profiles/ch-runner.nix | 104 ++++++++++++++++++++++++----------------- shell.nix | 33 +++++++++---- 3 files changed, 87 insertions(+), 52 deletions(-) diff --git a/pkgs/taps/package.nix b/pkgs/taps/package.nix index c666cd9..e396748 100644 --- a/pkgs/taps/package.nix +++ b/pkgs/taps/package.nix @@ -30,6 +30,8 @@ stdenv.mkDerivation { rustc ]; buildInputs = [ ch-proxy ]; + + meta.mainProgram = "taps"; } # { lib, rustPlatform }: # diff --git a/profiles/ch-runner.nix b/profiles/ch-runner.nix index b9e17cf..b82d700 100644 --- a/profiles/ch-runner.nix +++ b/profiles/ch-runner.nix @@ -278,6 +278,7 @@ in (lib.getBin package) (lib.getBin pkgs.virtiofsd) (lib.getBin pkgs.bubblewrap) + (lib.getBin pkgs.strace) uvmsPkgs.taps ]; @@ -403,7 +404,6 @@ in **kwargs, ) - @contextmanager def bwrap( self, *bwrap_args, @@ -420,20 +420,26 @@ in unshare_uts=None, unshare_cgroup_try=True, bind=(), - dev_bind=("/dev/kvm", "/dev/vfio"), + dev_bind=(), + dev_bind_implicit=("/dev/kvm", "/dev/vfio"), dev="/dev", proc="/proc", - ro_bind=( + ro_bind_implicit=( "/etc", "/sys", "/proc/sys", "/dev/null", "/proc/kallsyms", *CLOSURE), - ro_bind_extra=(), + ro_bind=(), remount_ro=("/proc/fs", "/proc/irq"), - tmpfs=("/dev/shm", "/tmp", "/var/tmp", "/proc/fs", "/proc/irq"), - tmpfs_extra=(), + tmpfs_implicit=( + "/dev/shm", + "/tmp", + "/var/tmp", + "/proc/fs", + "/proc/irq"), + tmpfs=(), pass_fds=(2,), **popen_kwargs): @@ -455,23 +461,29 @@ in print_arg("--unshare-pid") if unshare_net: print_arg("--unshare-net") + elif unshare_net is False: + print_arg("--share-net") if unshare_uts: print_arg("--unshare-uts") if unshare_cgroup_try: print_arg("--unshare-cgroup-try") if die_with_parent: print_arg("--die-with-parent") + if dev: + print_arg("--dev", dev) + if proc: + print_arg("--proc", proc) for p in bind: p1, p2 = (p, p) if isinstance(p, str) else p print_arg("--bind", p1, p2) - for p in (*ro_bind, *ro_bind_extra): + for p in (*ro_bind, *ro_bind_implicit): p1, p2 = (p, p) if isinstance(p, str) else p print_arg("--ro-bind", p1, p2) - for p in dev_bind: + for p in (*dev_bind, *dev_bind_implicit): p1, p2 = (p, p) if isinstance(p, str) else p print_arg("--dev-bind", p1, p2) - for p in (*tmpfs, *tmpfs_extra): + for p in (*tmpfs, *tmpfs_implicit): print_arg("--tmpfs", p) # Hunch: order might matter... for p in remount_ro: @@ -487,44 +499,48 @@ in pass_fds=(*pass_fds, remote.fileno()), ) - with proc as p: - try: - yield p - finally: - try: - p.poll() - except: # noqa: E722 - pass - if p.returncode is None: - p.terminate() - p.wait() + return proc @contextmanager def run_ch(self): - args = [ - SOCKETBINDER_PATH, - "-B", - self.prefix + "/vmm.sock", - CH_PATH, - "--api-socket", - "fd=0", - ] - p = self.popen( - *args, - shell=False, - stdin=subprocess.DEVNULL, - stdout=subprocess.DEVNULL, - pass_fds=()) - try: - p.wait(0.125) - needs_cleanup = False - except subprocess.TimeoutExpired: - needs_cleanup = True - if not os.path.exists(self.prefix + "/vmm.sock"): - raise RuntimeError(f"{self.prefix}/vmm.sock should exist by now") - if p.returncode is not None: - raise RuntimeError("CH exited early") try: + # s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM, 0) + # s.set_inheritable(True) + # s.setblocking(True) + # s.bind(self.prefix + "/vmm.sock") + args = [ + SOCKETBINDER_PATH, + "-B", + self.prefix + "/vmm.sock", + # "${lib.getExe pkgs.strace}", # noqa: E501 + # "-Z", + # "-ff", + CH_PATH, + "--api-socket", + "fd=0", + # f"fd={s.fileno()}" + ] + p = self.bwrap( + *args, + bind=[self.prefix], + # Probably just need the path to vmlinux + ro_bind=("/nix/store",), # A give up + unshare_net=False, + shell=False, + stderr=None, + # pass_fds=(s.fileno(),) + ) + # s.close() + try: + p.wait(0.125) + needs_cleanup = False + except subprocess.TimeoutExpired: + needs_cleanup = True + if not os.path.exists(self.prefix + "/vmm.sock"): + raise RuntimeError( + f"{self.prefix}/vmm.sock should exist by now") + if p.returncode is not None: + raise RuntimeError("CH exited early") yield p finally: try: @@ -598,7 +614,7 @@ in kwargs = { # If bwrap(): # "bind": [], - # ("ro_bind_extra" if ro else "bind"): + # ("ro_bind" if ro else "bind"): # [*subdirs] # if subdirs is not None # else [root_dir], diff --git a/shell.nix b/shell.nix index f8bb9a7..44fdd56 100644 --- a/shell.nix +++ b/shell.nix @@ -1,13 +1,30 @@ with import { }; +let + uvmPkgs = callPackage ./pkgs { }; +in mkShell.override { stdenv = stdenvNoCC; } { - packages = map lib.getBin [ - cloud-hypervisor - virtiofsd - crosvm # virtio-gpu - npins - ] ++ [ - man-pages - linux-manual + inputsFrom = with uvmPkgs; [ + ch-proxy + taps + writeErofsLayers + request-usb ]; + packages = + map lib.getBin [ + cloud-hypervisor + virtiofsd + crosvm # virtio-gpu + npins + strace + python3 + execline + s6 + wayland-proxy-virtwl + uvmPkgs.taps + ] + ++ [ + man-pages + linux-manual + ]; }