diff --git a/stages/org.osbuild.dracut b/stages/org.osbuild.dracut index 16bc379a..36f853fe 100755 --- a/stages/org.osbuild.dracut +++ b/stages/org.osbuild.dracut @@ -1,4 +1,5 @@ #!/usr/bin/python3 +import os import subprocess import sys @@ -10,6 +11,36 @@ def yesno(name: str, value: bool) -> str: return f"--{prefix}{name}" +class DracutMounts: + """ + Setup the mounts inside a chroot root directory, which will be used + for running dracut inside it. Cleanup mounts when done. + This mounts /proc, /dev, and /sys. + """ + + def __init__(self, root: str): + self.root = root + + def __enter__(self): + for d in ["/proc", "/dev", "/sys"]: + if not os.path.exists(self.root + d): + print(f"Making missing dracut chroot directory: {d}") + os.makedirs(self.root + d) + + subprocess.check_call(["/usr/bin/mount", "-t", "proc", "-o", + "nosuid,noexec,nodev", "proc", f"{self.root}/proc"]) + subprocess.check_call(["/usr/bin/mount", "-t", "devtmpfs", "-o", + "mode=0755,noexec,nosuid,strictatime", "devtmpfs", f"{self.root}/dev"]) + subprocess.check_call(["/usr/bin/mount", "-t", "sysfs", "-o", + "nosuid,noexec,nodev", "sysfs", f"{self.root}/sys"]) + + return self + + def __exit__(self, exc_type, exc_value, tracebk): + for d in ["/proc", "/dev", "/sys"]: + subprocess.check_call(["/usr/bin/umount", self.root + d]) + + # pylint: disable=too-many-branches def main(tree, options): kernels = options["kernel"] @@ -82,11 +113,12 @@ def main(tree, options): if initoverlayfs: initfs_bin = "/usr/bin/initoverlayfs-install" - subprocess.run(["/usr/sbin/chroot", tree, initfs_bin, - "--no-hostonly", - "--kver", kver] - + opts, - check=True) + with DracutMounts(tree): + subprocess.run(["/usr/sbin/chroot", tree, initfs_bin, + "--no-hostonly", + "--kver", kver] + + opts, + check=True) return 0 diff --git a/stages/test/test_dracut.py b/stages/test/test_dracut.py index c1e0f6a2..7e019f8b 100644 --- a/stages/test/test_dracut.py +++ b/stages/test/test_dracut.py @@ -20,7 +20,7 @@ def test_dracut_with_initoverlayfs(mocked_run, tmp_path, stage_module, with_init "initoverlayfs": with_initoverlayfs, } - stage_module.main(tmp_path, options) + stage_module.main(str(tmp_path), options) assert len(mocked_run.call_args_list) == 1 args, kwargs = mocked_run.call_args_list[0]