From: Antonio Alvarez Feijoo Date: Thu, 27 Jun 2024 14:37:00 +0000 (+0200) Subject: mkosi-initrd: provide a separate mkosi-initrd script X-Git-Tag: v24~81 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=99ca14cffb13309a0e6865b2724cc199916c753b;p=thirdparty%2Fmkosi.git mkosi-initrd: provide a separate mkosi-initrd script Extract the basic functionality implemented on the kernel-install plugin into a separate script. This allows to simplify the initrd/UKI build auto-filling arguments of the `mkosi` call, and also auto-include user/distro configuration from `/{etc,usr/lib}/mkosi-initrd`. --- diff --git a/.gitignore b/.gitignore index b821a7667..e8b7eab25 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ *.cache-pre-inst .cache .mkosi.1 +.mkosi-initrd.1 .mypy_cache/ .project .pydevproject diff --git a/kernel-install/50-mkosi.install b/kernel-install/50-mkosi.install index 7fc7e6ab1..b0922512e 100644 --- a/kernel-install/50-mkosi.install +++ b/kernel-install/50-mkosi.install @@ -14,7 +14,7 @@ from mkosi import identify_cpu from mkosi.archive import make_cpio from mkosi.config import OutputFormat, __version__ from mkosi.log import die, log_setup -from mkosi.run import find_binary, run, uncaught_exception_handler +from mkosi.run import run, uncaught_exception_handler from mkosi.types import PathString from mkosi.util import umask @@ -81,30 +81,42 @@ def main() -> None: usage='50-mkosi.install COMMAND KERNEL_VERSION ENTRY_DIR KERNEL_IMAGE INITRD…', ) - parser.add_argument("command", - metavar="COMMAND", - help="The action to perform. Only 'add' is supported.") - parser.add_argument("kernel_version", - metavar="KERNEL_VERSION", - help="Kernel version string") - parser.add_argument("entry_dir", - metavar="ENTRY_DIR", - type=Path, - nargs="?", - help="Type#1 entry directory (ignored)") - parser.add_argument("kernel_image", - metavar="KERNEL_IMAGE", - type=Path, - nargs="?", - help="Kernel image") - parser.add_argument("initrds", - metavar="INITRD…", - type=Path, - nargs="*", - help="Initrd files") - parser.add_argument("--version", - action="version", - version=f"mkosi {__version__}") + parser.add_argument( + "command", + metavar="COMMAND", + help="The action to perform. Only 'add' is supported.", + ) + parser.add_argument( + "kernel_version", + metavar="KERNEL_VERSION", + help="Kernel version string", + ) + parser.add_argument( + "entry_dir", + metavar="ENTRY_DIR", + type=Path, + nargs="?", + help="Type#1 entry directory (ignored)", + ) + parser.add_argument( + "kernel_image", + metavar="KERNEL_IMAGE", + type=Path, + nargs="?", + help="Kernel image", + ) + parser.add_argument( + "initrds", + metavar="INITRD…", + type=Path, + nargs="*", + help="Initrd files", + ) + parser.add_argument( + "--version", + action="version", + version=f"mkosi {__version__}", + ) context = Context( **vars(parser.parse_args()), @@ -131,65 +143,19 @@ def main() -> None: output = "initrd" if format == OutputFormat.cpio else "uki" cmdline: list[PathString] = [ - "mkosi", - "--directory", "", + "mkosi-initrd", + "--kernel-version", context.kernel_version, "--format", str(format), "--output", output, - "--workspace-dir=/var/tmp", - "--package-cache-dir=/var", - "--cache-only=metadata", "--output-dir", context.staging_area, - "--extra-tree", f"/usr/lib/modules/{context.kernel_version}:/usr/lib/modules/{context.kernel_version}", - "--extra-tree=/usr/lib/firmware:/usr/lib/firmware", - "--kernel-modules-exclude=.*", - "--kernel-modules-include=host", - "--include=mkosi-initrd", ] if context.verbose: cmdline += ["--debug"] - for d in ("/usr/lib/mkosi-initrd", "/etc/mkosi-initrd"): - if Path(d).exists(): - cmdline += ["--include", d] - - with tempfile.TemporaryDirectory() as d: - # Make sure we don't use any of mkosi's default repositories. - for p in ( - "yum.repos.d/mkosi.repo", - "apt/sources.list.d/mkosi.sources", - "zypp/repos.d/mkosi.repo", - "pacman.conf", - ): - (Path(d) / "etc" / p).parent.mkdir(parents=True, exist_ok=True) - (Path(d) / "etc" / p).touch() - - # Copy in the host's package manager configuration. - for p in ( - "dnf", - "yum.repos.d/", - "apt", - "zypp", - "pacman.conf", - "pacman.d/", - ): - if not (Path("/etc") / p).exists(): - continue - - (Path(d) / "etc" / p).parent.mkdir(parents=True, exist_ok=True) - if (Path("/etc") / p).resolve().is_file(): - shutil.copy2(Path("/etc") / p, Path(d) / "etc" / p) - else: - shutil.copytree(Path("/etc") / p, Path(d) / "etc" / p, - ignore=shutil.ignore_patterns("S.*"), dirs_exist_ok=True) - - cmdline += ["--package-manager-tree", d] - - logging.info(f"Building {output}") - - # Prefer dnf as dnf5 has not yet officially replaced it and there's a much bigger chance that there will be a - # populated dnf cache directory. - run(cmdline, env={"MKOSI_DNF": dnf.name} if (dnf := find_binary("dnf", "dnf5")) else {}) + logging.info(f"Building {output}") + + run(cmdline) (context.staging_area / output).unlink() diff --git a/mkosi/initrd/__main__.py b/mkosi/initrd/__main__.py new file mode 100644 index 000000000..acb85e622 --- /dev/null +++ b/mkosi/initrd/__main__.py @@ -0,0 +1,133 @@ +# SPDX-License-Identifier: LGPL-2.1+ + +import argparse +import os +import platform +import shutil +import tempfile +from pathlib import Path + +from mkosi.config import OutputFormat, __version__ +from mkosi.log import log_setup +from mkosi.run import find_binary, run, uncaught_exception_handler +from mkosi.types import PathString + + +@uncaught_exception_handler() +def main() -> None: + log_setup() + + parser = argparse.ArgumentParser( + prog="mkosi-initrd", + description="Build initrds or unified kernel images for the current system using mkosi", + allow_abbrev=False, + usage="mkosi-initrd [options...]", + ) + + parser.add_argument( + "--kernel-version", + metavar="KERNEL_VERSION", + help="Kernel version string", + default=platform.uname().release, + ) + parser.add_argument( + "-t", "--format", + choices=[str(OutputFormat.cpio), str(OutputFormat.uki), str(OutputFormat.directory)], + help="Output format (CPIO archive, UKI or local directory)", + default="cpio", + ) + parser.add_argument( + "-o", "--output", + metavar="NAME", + help="Output name", + default="initrd", + ) + parser.add_argument( + "-O", "--output-dir", + metavar="DIR", + help="Output directory", + default="", + ) + parser.add_argument( + "--debug", + help="Turn on debugging output", + action="store_true", + default=False, + ) + parser.add_argument( + "--version", + action="version", + version=f"mkosi {__version__}", + ) + + args = parser.parse_args() + + cmdline: list[PathString] = [ + "mkosi", + "--force", + "--directory", "", + "--format", str(args.format), + "--output", args.output, + "--output-dir", args.output_dir, + "--cache-only=metadata", + "--extra-tree", f"/usr/lib/modules/{args.kernel_version}:/usr/lib/modules/{args.kernel_version}", + "--extra-tree=/usr/lib/firmware:/usr/lib/firmware", + "--remove-files=/usr/lib/firmware/*-ucode", + "--kernel-modules-exclude=.*", + "--kernel-modules-include=host", + "--include=mkosi-initrd", + ] + + if args.debug: + cmdline += ["--debug"] + + if os.getuid() == 0: + cmdline += [ + "--workspace-dir=/var/tmp", + "--package-cache-dir=/var", + ] + + for d in ("/usr/lib/mkosi-initrd", "/etc/mkosi-initrd"): + if Path(d).exists(): + cmdline += ["--include", d] + + with tempfile.TemporaryDirectory() as d: + # Make sure we don't use any of mkosi's default repositories. + for p in ( + "yum.repos.d/mkosi.repo", + "apt/sources.list.d/mkosi.sources", + "zypp/repos.d/mkosi.repo", + "pacman.conf", + ): + (Path(d) / "etc" / p).parent.mkdir(parents=True, exist_ok=True) + (Path(d) / "etc" / p).touch() + + # Copy in the host's package manager configuration. + for p in ( + "dnf", + "yum.repos.d/", + "apt", + "zypp", + "pacman.conf", + "pacman.d/", + ): + if not (Path("/etc") / p).exists(): + continue + + (Path(d) / "etc" / p).parent.mkdir(parents=True, exist_ok=True) + if (Path("/etc") / p).resolve().is_file(): + shutil.copy2(Path("/etc") / p, Path(d) / "etc" / p) + else: + shutil.copytree(Path("/etc") / p, Path(d) / "etc" / p, + ignore=shutil.ignore_patterns("S.*"), dirs_exist_ok=True) + + cmdline += ["--package-manager-tree", d] + + # Prefer dnf as dnf5 has not yet officially replaced it and there's a much bigger chance that there will be a + # populated dnf cache directory. + run(cmdline, env={"MKOSI_DNF": dnf.name} if (dnf := find_binary("dnf", "dnf5")) else {}) + + +if __name__ == "__main__": + main() + diff --git a/mkosi/initrd/resources/mkosi-initrd.md b/mkosi/initrd/resources/mkosi-initrd.md new file mode 100644 index 000000000..3c4ac4bae --- /dev/null +++ b/mkosi/initrd/resources/mkosi-initrd.md @@ -0,0 +1,52 @@ +% mkosi-initrd(1) +% +% + +# NAME + +mkosi-initrd — Build initrds or unified kernel images for the current system +using mkosi + +# SYNOPSIS + +`mkosi-initrd [options…]` + +# DESCRIPTION + +`mkosi-initrd` is wrapper on top of `mkosi` to simplify the generation of +initrds and Unified Kernel Images for the current running system. + +# OPTIONS + +`--kernel-version=` +: Kernel version where to look for the kernel modules to include. Defaults to + the kernel version of the running system (`uname -r`). + +`--format=`, `-t` +: Output format. One of `cpio` (CPIO archive), `uki` (a unified kernel image + with the image in the `.initrd` PE section) or `directory` (for generating + an image directly in a local directory). Defaults to `cpio`. + +`--output=`, `-o` +: Name to use for the generated output image file or directory. Defaults + to `initrd`. + + Note that this only specifies the output prefix, depending on the + specific output format and compression used, the full output name might be + `initrd.cpio.zst`. + +`--output-dir=`, `-O` +: Path to a directory where to place all generated artifacts. Defaults to the + current working directory. + +`--debug=` +: Enable additional debugging output. + +`--version` +: Show package version. + +`--help`, `-h` +: Show brief usage information. + +# SEE ALSO +`mkosi(1)` diff --git a/pyproject.toml b/pyproject.toml index a44bfaae7..2ce33a919 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,17 +20,21 @@ bootable = [ [project.scripts] mkosi = "mkosi.__main__:main" +mkosi-initrd = "mkosi.initrd.__main__:main" [tool.setuptools] packages = [ "mkosi", "mkosi.distributions", + "mkosi.initrd", + "mkosi.initrd.resources", "mkosi.installer", "mkosi.resources", ] [tool.setuptools.package-data] "mkosi.resources" = ["repart/**/*", "mkosi.md", "mkosi.1", "mkosi-initrd/**/*", "mkosi-tools/**/*"] +"mkosi.initrd.resources" = ["mkosi-initrd.md", "mkosi-initrd.1"] [tool.isort] profile = "black" diff --git a/tools/make-man-page.sh b/tools/make-man-page.sh index 005404906..35321a930 100755 --- a/tools/make-man-page.sh +++ b/tools/make-man-page.sh @@ -3,3 +3,4 @@ set -ex pandoc -t man -s -o mkosi/resources/mkosi.1 mkosi/resources/mkosi.md +pandoc -t man -s -o mkosi/initrd/resources/mkosi-initrd.1 mkosi/initrd/resources/mkosi-initrd.md