diff options
Diffstat (limited to 'examples/unschroot_proc.py')
-rwxr-xr-x | examples/unschroot_proc.py | 100 |
1 files changed, 69 insertions, 31 deletions
diff --git a/examples/unschroot_proc.py b/examples/unschroot_proc.py index 5894680..dc5cc94 100755 --- a/examples/unschroot_proc.py +++ b/examples/unschroot_proc.py @@ -24,6 +24,7 @@ import configparser import contextlib import errno import functools +import itertools import os import pathlib import pwd @@ -168,6 +169,50 @@ class SourceChroot(ChrootBase): assert False, f"unexpected chroot configuration {self.config!r}" return data + async def mount_fuse( + self, + proxy: asyncvarlink.VarlinkInterfaceProxy, + device: str, + target: str, + subtype: str, + options: list[str], + ) -> None: + """Mount a single fuse filesystem in the proxied process.""" + driver = { + "bind": "bindfs", + "erofs": "erofsfuse", + "ext4": "fuse2fs", + "squashfs": "squashfuse", + }[subtype] + with ( + await proxy.MountFuse( + source=device, + target=target, + options={ + "rootmode": "040755", + "user_id": 0, + "group_id": 0, + "allow_other": None, + }, + fstype=subtype, + ) as mountres, + mountres["fusefd"] as fusefd, + ): + @linuxnamespaces.run_in_fork.now + def _() -> None: + close_all_but([0, 1, 2, fusefd]) + os.execvp( + driver, + [ + driver, + *itertools.chain.from_iterable( + zip(itertools.repeat("-o"), options) + ), + str(pathlib.Path(device).expanduser()), + f"/dev/fd/{fusefd.fileno()}", + ], + ) + async def mount( self, proxy: asyncvarlink.VarlinkInterfaceProxy, @@ -197,37 +242,9 @@ class SourceChroot(ChrootBase): ], ) case ["fuse", subtype]: - driver = { - "erofs": "erofsfuse", - "ext4": "fuse2fs", - "squashfs": "squashfuse", - }[subtype] - device = pathlib.Path(self.config["rootfsdev"]) - with ( - await proxy.MountFuse( - source=str(device), - target="lower", - options={ - "rootmode": "040755", - "user_id": 0, - "group_id": 0, - "allow_other": None, - }, - fstype=subtype, - ) as mountres, - mountres["fusefd"] as fusefd, - ): - @linuxnamespaces.run_in_fork.now - def _() -> None: - close_all_but([0, 1, 2, fusefd]) - os.execvp( - driver, - [ - driver, - str(device.expanduser()), - f"/dev/fd/{fusefd.fileno()}", - ], - ) + await self.mount_fuse( + proxy, self.config["rootfsdev"], "lower", subtype, [] + ) case _: raise NotImplementedError("unsupported rootfstype") if self.config.get("overlayfs"): @@ -251,6 +268,27 @@ class SourceChroot(ChrootBase): extra["comptype"] = "zst" with tar.expanduser().open("rb") as tarf: await proxy.ExtractTar(tar=tarf, **extra) + for mount in self.config.get("mounts", "").split(): + [device, target, fstypestr, *options] = mount.split(",") + fstype = fstypestr.split(".", 1) + match fstype: + case ['bind']: + readonly = False + if options == ["ro"]: + readonly = True + elif options: + raise NotImplementedError( + "unsupported bind mount option" + ) + await proxy.BindMount( + source=str(pathlib.Path(device).expanduser()), + target=target, + readonly=readonly, + ) + case ['fuse', subtype]: + await self.mount_fuse( + proxy, device, target, subtype, options + ) class SessionChroot(ChrootBase): |