diff options
author | Helmut Grohne <helmut@subdivi.de> | 2024-02-21 11:20:44 +0100 |
---|---|---|
committer | Helmut Grohne <helmut@subdivi.de> | 2024-02-21 11:20:44 +0100 |
commit | 1de72653e0b9dcf41576b75bda7d08f76c525847 (patch) | |
tree | 7b523d8acaf0a3b98cae02ab2c8153db7d7d5085 /linuxnamespaces/__init__.py | |
parent | b64313d313723c62f173f750f2d699ebf169e01f (diff) | |
download | python-linuxnamespaces-1de72653e0b9dcf41576b75bda7d08f76c525847.tar.gz |
add function linuxnamespaces.populate_sys
Diffstat (limited to 'linuxnamespaces/__init__.py')
-rw-r--r-- | linuxnamespaces/__init__.py | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/linuxnamespaces/__init__.py b/linuxnamespaces/__init__.py index f2e54ce..0fb54fb 100644 --- a/linuxnamespaces/__init__.py +++ b/linuxnamespaces/__init__.py @@ -6,6 +6,7 @@ Python. """ import bisect +import contextlib import dataclasses import os import pathlib @@ -314,6 +315,53 @@ def populate_dev( bind_mount(origdev / node, newdev / node, True) +def populate_sys( + origroot: AtLocationLike, + newroot: PathConvertible, + rootcgroup: PathConvertible | None = None, + module: bool = True, +) -> None: + """Create a /sys hierarchy below newroot. Bind the cgroup hiearchy. The + cgroup hierarchy will be mounted read-only if mounting the root group. + """ + newsys = AtLocation(newroot) / "sys" + mflags = MountFlags.NOSUID | MountFlags.NOEXEC | MountFlags.NODEV + if rootcgroup is None: + rootcgroup = "" + else: + rootcgroup = pathlib.PurePath(rootcgroup).relative_to("/") + with contextlib.ExitStack() as exitstack: + cgfd = exitstack.enter_context( + open_tree( + AtLocation(origroot) / "sys/fs/cgroup" / rootcgroup, + OpenTreeFlags.OPEN_TREE_CLONE | OpenTreeFlags.AT_RECURSIVE, + ), + ) + if rootcgroup: + mount_setattr(cgfd, True, MountAttrFlags.RDONLY) + if module: + modfd = exitstack.enter_context( + open_tree( + AtLocation(origroot) / "sys/module", + OpenTreeFlags.OPEN_TREE_CLONE | OpenTreeFlags.AT_RECURSIVE, + ), + ) + mount_setattr(modfd, True, MountAttrFlags.RDONLY) + mount("sysfs", newsys, "tmpfs", mflags, "mode=0755") + try: + for subdir in ("fs", "fs/cgroup", "module"): + (newsys / subdir).mkdir() + (newsys / subdir).chmod(0o755) + mflags |= MountFlags.REMOUNT | MountFlags.RDONLY + mount("sysfs", newsys, "tmpfs", mflags, "mode=0755") + move_mount(cgfd, newsys / "fs/cgroup") + if module: + move_mount(modfd, newsys / "module") + except: + umount(newsys, UmountFlags.DETACH) + raise + + def unshare_user_idmap( uidmap: list[IDMapping], gidmap: list[IDMapping], |