Add a context manager for dracut
dracut needs a reasonable chroot environment in order to run correctly.
This adds the DracutChroot context manager that sets up and tears down
mounts inside the root directory tree.
Switch to using it in creator.rebuild_initrds_for_live() and
TreeBuilder.rebuild_initrds()
(cherry picked from commit 322a810403
)
Resolves: rhbz#1982271
This commit is contained in:
parent
9f8df6b76c
commit
0485ef22f2
@ -36,8 +36,8 @@ from pykickstart.version import makeVersion
|
||||
# Use the Lorax treebuilder branch for iso creation
|
||||
from pylorax import ArchData
|
||||
from pylorax.base import DataHolder
|
||||
from pylorax.executils import execWithRedirect, runcmd
|
||||
from pylorax.imgutils import PartitionMount
|
||||
from pylorax.executils import execWithRedirect
|
||||
from pylorax.imgutils import DracutChroot, PartitionMount
|
||||
from pylorax.imgutils import mount, umount, Mount
|
||||
from pylorax.imgutils import mksquashfs, mkrootfsimg
|
||||
from pylorax.imgutils import copytree
|
||||
@ -243,7 +243,7 @@ def rebuild_initrds_for_live(opts, sys_root_dir, results_dir):
|
||||
# cmdline dracut args override the defaults, but need to be parsed
|
||||
log.info("dracut args = %s", dracut_args(opts))
|
||||
|
||||
dracut = ["dracut", "--nomdadmconf", "--nolvmconf"] + dracut_args(opts)
|
||||
args = ["--nomdadmconf", "--nolvmconf"] + dracut_args(opts)
|
||||
|
||||
kdir = "boot"
|
||||
if opts.ostree:
|
||||
@ -272,25 +272,18 @@ def rebuild_initrds_for_live(opts, sys_root_dir, results_dir):
|
||||
|
||||
# Write the new initramfs directly to the results directory
|
||||
os.mkdir(joinpaths(sys_root_dir, "results"))
|
||||
mount(results_dir, opts="bind", mnt=joinpaths(sys_root_dir, "results"))
|
||||
# Dracut runs out of space inside the minimal rootfs image
|
||||
mount("/var/tmp", opts="bind", mnt=joinpaths(sys_root_dir, "var/tmp"))
|
||||
for kernel in kernels:
|
||||
if hasattr(kernel, "initrd"):
|
||||
outfile = os.path.basename(kernel.initrd.path)
|
||||
else:
|
||||
# Construct an initrd from the kernel name
|
||||
outfile = os.path.basename(kernel.path.replace("vmlinuz-", "initrd-") + ".img")
|
||||
log.info("rebuilding %s", outfile)
|
||||
log.info("dracut warnings about /proc are safe to ignore")
|
||||
with DracutChroot(sys_root_dir, bind=[(results_dir, "/results")]) as dracut:
|
||||
for kernel in kernels:
|
||||
if hasattr(kernel, "initrd"):
|
||||
outfile = os.path.basename(kernel.initrd.path)
|
||||
else:
|
||||
# Construct an initrd from the kernel name
|
||||
outfile = os.path.basename(kernel.path.replace("vmlinuz-", "initrd-") + ".img")
|
||||
log.info("rebuilding %s", outfile)
|
||||
|
||||
kver = kernel.version
|
||||
cmd = dracut + ["/results/"+outfile, kver]
|
||||
runcmd(cmd, root=sys_root_dir)
|
||||
|
||||
shutil.copy2(joinpaths(sys_root_dir, kernel.path), results_dir)
|
||||
umount(joinpaths(sys_root_dir, "var/tmp"), delete=False)
|
||||
umount(joinpaths(sys_root_dir, "results"), delete=False)
|
||||
kver = kernel.version
|
||||
dracut.Run(args + ["/results/"+outfile, kver])
|
||||
shutil.copy2(joinpaths(sys_root_dir, kernel.path), results_dir)
|
||||
|
||||
def create_pxe_config(template, images_dir, live_image_name, add_args = None):
|
||||
"""
|
||||
|
@ -473,6 +473,42 @@ class PartitionMount(object):
|
||||
execWithRedirect("kpartx", ["-d", "-s", self.disk_img])
|
||||
|
||||
|
||||
class DracutChroot(object):
|
||||
"""Setup the chroot for running dracut inside it, cleanup when done
|
||||
|
||||
This mount /proc, /dev, and /var/tmp plus optional bind mounted directories
|
||||
as a list of (source, destination) tuples where destination is relative to the chroot.
|
||||
"""
|
||||
def __init__(self, root, bind=None):
|
||||
self.root = root
|
||||
self.bind = [("/var/tmp", "/var/tmp")] + (bind if bind else [])
|
||||
|
||||
def __enter__(self):
|
||||
for d in [d for _, d in self.bind] + ["/proc", "/dev"]:
|
||||
if not os.path.exists(self.root + d):
|
||||
logger.warning("Making missing dracut chroot directory: %s", d)
|
||||
os.makedirs(self.root + d)
|
||||
|
||||
runcmd(["mount", "-t", "proc", "-o", "nosuid,noexec,nodev", "proc", self.root + "/proc" ])
|
||||
runcmd(["mount", "-t", "devtmpfs", "-o", "mode=0755,noexec,nosuid,strictatime", "devtmpfs", self.root + "/dev" ])
|
||||
|
||||
for s, d in self.bind:
|
||||
runcmd(["mount", "-o", "bind", s, self.root + d])
|
||||
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_value, tracebk):
|
||||
runcmd(["umount", self.root + "/proc" ])
|
||||
runcmd(["umount", self.root + "/dev" ])
|
||||
|
||||
# cleanup bind mounts
|
||||
for _, d in self.bind:
|
||||
runcmd(["umount", self.root + d ])
|
||||
|
||||
def Run(self, args):
|
||||
runcmd(["dracut"] + args, root=self.root)
|
||||
|
||||
|
||||
######## Functions for making filesystem images ##########################
|
||||
|
||||
def mkfsimage(fstype, rootdir, outfile, size=None, mkfsargs=None, mountargs="", graft=None):
|
||||
|
@ -31,6 +31,7 @@ from pylorax.sysutils import joinpaths, remove
|
||||
from pylorax.base import DataHolder
|
||||
from pylorax.ltmpl import LoraxTemplateRunner
|
||||
import pylorax.imgutils as imgutils
|
||||
from pylorax.imgutils import DracutChroot
|
||||
from pylorax.executils import runcmd, runcmd_output, execWithCapture
|
||||
|
||||
templatemap = {
|
||||
@ -310,32 +311,31 @@ class TreeBuilder(object):
|
||||
name of the kernel.
|
||||
'''
|
||||
add_args = add_args or []
|
||||
dracut = ["dracut", "--nomdadmconf", "--nolvmconf"] + add_args
|
||||
args = ["--nomdadmconf", "--nolvmconf"] + add_args
|
||||
if not backup:
|
||||
dracut.append("--force")
|
||||
args.append("--force")
|
||||
|
||||
if not self.kernels:
|
||||
raise Exception("No kernels found, cannot rebuild_initrds")
|
||||
|
||||
for kernel in self.kernels:
|
||||
if prefix:
|
||||
idir = os.path.dirname(kernel.path)
|
||||
outfile = joinpaths(idir, prefix+'-'+kernel.version+'.img')
|
||||
elif hasattr(kernel, "initrd"):
|
||||
# If there is an existing initrd, use that
|
||||
outfile = kernel.initrd.path
|
||||
else:
|
||||
# Construct an initrd from the kernel name
|
||||
outfile = kernel.path.replace("vmlinuz-", "initrd-") + ".img"
|
||||
logger.info("rebuilding %s", outfile)
|
||||
logger.info("dracut warnings about /proc are safe to ignore")
|
||||
with DracutChroot(self.vars.inroot) as dracut:
|
||||
for kernel in self.kernels:
|
||||
if prefix:
|
||||
idir = os.path.dirname(kernel.path)
|
||||
outfile = joinpaths(idir, prefix+'-'+kernel.version+'.img')
|
||||
elif hasattr(kernel, "initrd"):
|
||||
# If there is an existing initrd, use that
|
||||
outfile = kernel.initrd.path
|
||||
else:
|
||||
# Construct an initrd from the kernel name
|
||||
outfile = kernel.path.replace("vmlinuz-", "initrd-") + ".img"
|
||||
logger.info("rebuilding %s", outfile)
|
||||
|
||||
if backup:
|
||||
initrd = joinpaths(self.vars.inroot, outfile)
|
||||
if os.path.exists(initrd):
|
||||
os.rename(initrd, initrd + backup)
|
||||
cmd = dracut + [outfile, kernel.version]
|
||||
runcmd(cmd, root=self.vars.inroot)
|
||||
if backup:
|
||||
initrd = joinpaths(self.vars.inroot, outfile)
|
||||
if os.path.exists(initrd):
|
||||
os.rename(initrd, initrd + backup)
|
||||
dracut.Run(args + [outfile, kernel.version])
|
||||
|
||||
def build(self):
|
||||
templatefile = templatemap[self.vars.arch.basearch]
|
||||
|
Loading…
Reference in New Issue
Block a user