summaryrefslogtreecommitdiff
path: root/examples/unschroot_proc.py
diff options
context:
space:
mode:
Diffstat (limited to 'examples/unschroot_proc.py')
-rwxr-xr-xexamples/unschroot_proc.py100
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):