mirror of
https://github.com/BigfootACA/arch-image-builder.git
synced 2024-11-11 07:57:53 +08:00
112 lines
3.0 KiB
Python
112 lines
3.0 KiB
Python
import os
|
|
from logging import getLogger
|
|
from tempfile import NamedTemporaryFile
|
|
from builder.build.filesystem import chroot_run
|
|
from builder.lib.context import ArchBuilderContext
|
|
from builder.lib.config import ArchBuilderConfigError
|
|
from builder.lib.utils import open_config
|
|
log = getLogger(__name__)
|
|
|
|
|
|
def add_values(ctx: ArchBuilderContext, key: str, arr: list[str]):
|
|
vals = ctx.get(key, [])
|
|
vt = type(vals)
|
|
if vt is list: arr.extend(vals)
|
|
elif vt is str: arr.extend(vals.split())
|
|
else: raise ArchBuilderConfigError(f"bad values for {key}")
|
|
|
|
|
|
def gen_config(ctx: ArchBuilderContext):
|
|
"""
|
|
Generate mkinitcpio.conf
|
|
"""
|
|
modules: list[str] = []
|
|
binaries: list[str] = []
|
|
files: list[str] = []
|
|
hooks: list[str] = []
|
|
|
|
# add default hooks
|
|
hooks.append("base")
|
|
hooks.append("systemd")
|
|
hooks.append("autodetect")
|
|
|
|
# add microcode if x86_64 (amd-ucode, intel-ucode)
|
|
if ctx.cur_arch in ["x86_64", "i386"]:
|
|
hooks.append("microcode")
|
|
|
|
hooks.append("modconf")
|
|
|
|
# do not add keymap by default
|
|
if ctx.get("mkinitcpio.hooks.keymap", False):
|
|
hooks.extend(["kms", "keymap", "consolefont"])
|
|
|
|
hooks.extend(["keyboard", "block", "filesystems", "fsck"])
|
|
|
|
# add others values
|
|
add_values(ctx, "mkinitcpio.modules", modules)
|
|
add_values(ctx, "mkinitcpio.binaries", binaries)
|
|
add_values(ctx, "mkinitcpio.files", files)
|
|
|
|
# write mkinitcpio.conf to rootfs
|
|
root = ctx.get_rootfs()
|
|
cfg = os.path.join(root, "etc/mkinitcpio.conf")
|
|
with open_config(cfg) as f:
|
|
f.write("MODULES=(%s)\n" % (" ".join(modules)))
|
|
f.write("BINARIES=(%s)\n" % (" ".join(binaries)))
|
|
f.write("FILES=(%s)\n" % (" ".join(files)))
|
|
f.write("HOOKS=(%s)\n" % (" ".join(hooks)))
|
|
# TODO: add more options
|
|
|
|
|
|
def recreate_initrd(ctx: ArchBuilderContext, path: str):
|
|
"""
|
|
Really run mkinitcpio
|
|
"""
|
|
chroot_run(ctx, ["mkinitcpio", "-p", path])
|
|
# do not check return value of mkinitcpio
|
|
|
|
|
|
def recreate_initrd_no_autodetect(ctx: ArchBuilderContext, path: str):
|
|
"""
|
|
Create a full initramfs without autodetect
|
|
In build stage, mkinitcpio can not find out needs modules, it will cause unbootable.
|
|
"""
|
|
tmp = os.path.join(ctx.get_rootfs(), "tmp")
|
|
with NamedTemporaryFile("w", dir=tmp) as temp:
|
|
|
|
# copy original preset
|
|
with open(path, "r") as f:
|
|
temp.write(f.read())
|
|
|
|
# skip autodetect
|
|
temp.write("\ndefault_options=\"-S autodetect\"\n")
|
|
temp.flush()
|
|
|
|
# run mkinitcpio (with path in rootfs)
|
|
path = os.path.join("/tmp", os.path.basename(temp.name))
|
|
recreate_initrd(ctx, path)
|
|
|
|
|
|
def recreate_initrds(ctx: ArchBuilderContext):
|
|
"""
|
|
Regenerate all initramfs
|
|
"""
|
|
root = ctx.get_rootfs()
|
|
no_autodetect = ctx.get("mkinitcpio.no_autodetect", True)
|
|
folder = os.path.join(root, "etc/mkinitcpio.d")
|
|
|
|
# scan all initramfs preset and regenerate them
|
|
for preset in os.listdir(folder):
|
|
if not preset.endswith(".preset"): continue
|
|
path = os.path.join(folder, preset)
|
|
if not no_autodetect: recreate_initrd(ctx, path)
|
|
else: recreate_initrd_no_autodetect(ctx, path)
|
|
|
|
|
|
def proc_mkinitcpio(ctx: ArchBuilderContext):
|
|
"""
|
|
Process mkinitcpio options
|
|
"""
|
|
gen_config(ctx)
|
|
recreate_initrds(ctx)
|