Stages/dracut: prepare environment for running dracut in chroot
dracut expects the environment, in which it is run, to have properly mounted /proc, /dev and /sys. Otherwise, some of its modules don't work properly. E.g. dracut fails to embed the CA cert bundle into the initram disk, which means that HTTPS won't work in it. dracut also prints a lot of errors and warnings about this, but we used to ignore them until now. The buildroot environment in which the stage runs is OK, but we actually run dracut using 'chroot', which is the core of the problem. The runtime environment in such case lacks the necessary mounts. Add a context manager for setting up and cleaning up all the necessary mounts in the image FS tree when running dracut. This change is related to: https://bugzilla.redhat.com/show_bug.cgi?id=1962975 And the implementation has been inspired by the fix in lorax: https://github.com/weldr/lorax/pull/1151 Signed-off-by: Tomáš Hozza <thozza@redhat.com>
This commit is contained in:
parent
a0b44c5c72
commit
e1df8cea8f
2 changed files with 38 additions and 6 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue