pmbootstrap-meow/pmb/chroot/initfs.py
Caleb Connolly 34dd9d42ba
WIP: start ripping out args (MR 2252)
Cease merging pmbootstrap.cfg into args, implement a Context type to let
us pull globals out of thin air (as an intermediate workaround) and rip
args out of a lot of the codebase.

This is just a first pass, after this we can split all the state that
leaked over into Context into types with narrower scopes (like a
BuildContext(), etc).

Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
2024-06-23 12:38:38 +02:00

123 lines
4.4 KiB
Python

# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
from pmb.helpers import logging
from pathlib import Path
import pmb.chroot.initfs_hooks
import pmb.chroot.other
import pmb.chroot.apk
import pmb.config.pmaports
from pmb.types import PmbArgs
import pmb.helpers.cli
from pmb.core import Chroot
def build(args: PmbArgs, flavor, chroot: Chroot):
# Update mkinitfs and hooks
pmb.chroot.apk.install(["postmarketos-mkinitfs"], chroot)
pmb.chroot.initfs_hooks.update(args, chroot)
pmaports_cfg = pmb.config.pmaports.read_config()
# Call mkinitfs
logging.info(f"({chroot}) mkinitfs {flavor}")
if pmaports_cfg.get("supported_mkinitfs_without_flavors", False):
pmb.chroot.root(["mkinitfs"], chroot)
else:
release_file = (chroot / "usr/share/kernel" / flavor / "kernel.release")
with release_file.open() as handle:
release = handle.read().rstrip()
pmb.chroot.root(["mkinitfs", "-o",
f"/boot/initramfs-{flavor}", release],
chroot)
def extract(args: PmbArgs, flavor, chroot: Chroot, extra=False):
"""
Extract the initramfs to /tmp/initfs-extracted or the initramfs-extra to
/tmp/initfs-extra-extracted and return the outside extraction path.
"""
# Extraction folder
inside = "/tmp/initfs-extracted"
pmaports_cfg = pmb.config.pmaports.read_config()
if pmaports_cfg.get("supported_mkinitfs_without_flavors", False):
initfs_file = "/boot/initramfs"
else:
initfs_file = f"/boot/initramfs-${flavor}"
if extra:
inside = "/tmp/initfs-extra-extracted"
initfs_file += "-extra"
outside = chroot / inside
if outside.exists():
if not pmb.helpers.cli.confirm(args, f"Extraction folder {outside}"
" already exists."
" Do you want to overwrite it?"):
raise RuntimeError("Aborted!")
pmb.chroot.root(["rm", "-r", inside], chroot)
# Extraction script (because passing a file to stdin is not allowed
# in pmbootstrap's chroot/shell functions for security reasons)
with (chroot / "tmp/_extract.sh").open("w") as handle:
handle.write(
"#!/bin/sh\n"
f"cd {inside} && cpio -i < _initfs\n")
# Extract
commands = [["mkdir", "-p", inside],
["cp", initfs_file, f"{inside}/_initfs.gz"],
["gzip", "-d", f"{inside}/_initfs.gz"],
["cat", "/tmp/_extract.sh"], # for the log
["sh", "/tmp/_extract.sh"],
["rm", "/tmp/_extract.sh", f"{inside}/_initfs"]
]
for command in commands:
pmb.chroot.root(command, chroot)
# Return outside path for logging
return outside
def ls(args: PmbArgs, flavor, suffix, extra=False):
tmp = "/tmp/initfs-extracted"
if extra:
tmp = "/tmp/initfs-extra-extracted"
extract(args, flavor, suffix, extra)
pmb.chroot.root(["ls", "-lahR", "."], suffix, Path(tmp), "stdout")
pmb.chroot.root(["rm", "-r", tmp], suffix)
def frontend(args: PmbArgs):
# Find the appropriate kernel flavor
chroot = Chroot.rootfs(args.device)
flavor = pmb.chroot.other.kernel_flavor_installed(args, chroot)
# Handle initfs actions
action = args.action_initfs
if action == "build":
build(args, flavor, chroot)
elif action == "extract":
dir = extract(args, flavor, chroot)
logging.info(f"Successfully extracted initramfs to: {dir}")
dir_extra = extract(args, flavor, chroot, True)
logging.info(f"Successfully extracted initramfs-extra to: {dir_extra}")
elif action == "ls":
logging.info("*** initramfs ***")
ls(args, flavor, chroot)
logging.info("*** initramfs-extra ***")
ls(args, flavor, chroot, True)
# Handle hook actions
elif action == "hook_ls":
pmb.chroot.initfs_hooks.ls(chroot)
else:
if action == "hook_add":
pmb.chroot.initfs_hooks.add(args.hook, chroot)
elif action == "hook_del":
pmb.chroot.initfs_hooks.delete(args.hook, chroot)
# Rebuild the initfs after adding/removing a hook
build(args, flavor, chroot)
if action in ["ls", "extract"]:
link = "https://wiki.postmarketos.org/wiki/Initramfs_development"
logging.info(f"See also: <{link}>")