pmbootstrap-meow/pmb/chroot/initfs.py
Caleb Connolly 71e7af57e6
pmb.helpers.logging: wrap logging module (MR 2252)
We use a custom verbose log level in pmbootstrap, unfortunately it isn't
possible to correctly type this due to some limitations in the logging
library [1], [2].

Given that our usecase is fairly simple, we can just wrap the module
with our own so we only have to tell mypy to ignore the error once
instead of at every callsite.

[1]: https://github.com/cryptax/droidlysis/issues/15
[2]: https://github.com/python/typing/discussions/980

Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
2024-06-23 12:38:37 +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.core.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(args, ["postmarketos-mkinitfs"], chroot)
pmb.chroot.initfs_hooks.update(args, chroot)
pmaports_cfg = pmb.config.pmaports.read_config(args)
# Call mkinitfs
logging.info(f"({chroot}) mkinitfs {flavor}")
if pmaports_cfg.get("supported_mkinitfs_without_flavors", False):
pmb.chroot.root(args, ["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(args, ["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(args)
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(args, ["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(args, 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(args, ["ls", "-lahR", "."], suffix, Path(tmp), "stdout")
pmb.chroot.root(args, ["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(args, chroot)
else:
if action == "hook_add":
pmb.chroot.initfs_hooks.add(args, args.hook, chroot)
elif action == "hook_del":
pmb.chroot.initfs_hooks.delete(args, 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}>")