forked from Mirror/pmbootstrap
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>
123 lines
4.4 KiB
Python
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}>")
|