From 397ca3ce43a7870039e8df6f7ccfb68b5f2bc1c7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 Nov 2023 10:00:19 +0100 Subject: [PATCH] =?UTF-8?q?mkosi:=20add=20"burn"=20verb=20=F0=9F=94=A5?= =?UTF-8?q?=F0=9F=94=A5=F0=9F=94=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This simply dd's the resulting image to a block device. (Doesn't actually dd though, uses systemd-repart --copy-from) i.e. run "mkosi -f burn /dev/sda" --- mkosi/__init__.py | 4 ++++ mkosi/burn.py | 40 ++++++++++++++++++++++++++++++++++++++++ mkosi/config.py | 7 ++++--- mkosi/resources/mkosi.md | 9 +++++++++ 4 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 mkosi/burn.py diff --git a/mkosi/__init__.py b/mkosi/__init__.py index 6343595a0..6900d453b 100644 --- a/mkosi/__init__.py +++ b/mkosi/__init__.py @@ -23,6 +23,7 @@ from mkosi.architecture import Architecture from mkosi.archive import extract_tar, make_cpio, make_tar +from mkosi.burn import run_burn from mkosi.config import ( BiosBootloader, Bootloader, @@ -2868,3 +2869,6 @@ def run_verb(args: MkosiArgs, images: Sequence[MkosiConfig]) -> None: if args.verb == Verb.coredumpctl: run_coredumpctl(args, last) + + if args.verb == Verb.burn: + run_burn(args, last) diff --git a/mkosi/burn.py b/mkosi/burn.py new file mode 100644 index 000000000..08908e9e1 --- /dev/null +++ b/mkosi/burn.py @@ -0,0 +1,40 @@ +# SPDX-License-Identifier: LGPL-2.1+ + +import os +import sys + +from mkosi.config import MkosiArgs, MkosiConfig, OutputFormat +from mkosi.log import complete_step, die +from mkosi.run import run + + +def run_burn(args: MkosiArgs, config: MkosiConfig) -> None: + if config.output_format not in (OutputFormat.disk, OutputFormat.esp): + die(f"{config.output_format} images cannot be burned to disk") + + fname = config.output_dir_or_cwd() / config.output + + if len(args.cmdline) != 1: + die("Expected device argument."); + + device = args.cmdline[0] + + cmd = [ + "systemd-repart", + "--no-pager", + "--pretty=no", + "--offline=yes", + "--empty=force", + "--dry-run=no", + f"--copy-from={fname}", + device, + ] + + with complete_step("Burning 🔥🔥🔥 to medium…", "Burnt. 🔥🔥🔥"): + run( + cmd, + stdin=sys.stdin, + stdout=sys.stdout, + env=os.environ, + log=False, + ) diff --git a/mkosi/config.py b/mkosi/config.py index 2da446fb2..482fba8be 100644 --- a/mkosi/config.py +++ b/mkosi/config.py @@ -58,15 +58,16 @@ class Verb(StrEnum): documentation = enum.auto() journalctl = enum.auto() coredumpctl = enum.auto() + burn = enum.auto() def supports_cmdline(self) -> bool: - return self in (Verb.build, Verb.shell, Verb.boot, Verb.qemu, Verb.ssh, Verb.journalctl, Verb.coredumpctl) + return self in (Verb.build, Verb.shell, Verb.boot, Verb.qemu, Verb.ssh, Verb.journalctl, Verb.coredumpctl, Verb.burn) def needs_build(self) -> bool: - return self in (Verb.build, Verb.shell, Verb.boot, Verb.qemu, Verb.serve, Verb.journalctl, Verb.coredumpctl) + return self in (Verb.build, Verb.shell, Verb.boot, Verb.qemu, Verb.serve, Verb.journalctl, Verb.coredumpctl, Verb.burn) def needs_root(self) -> bool: - return self in (Verb.shell, Verb.boot) + return self in (Verb.shell, Verb.boot, Verb.burn) class ConfigFeature(StrEnum): diff --git a/mkosi/resources/mkosi.md b/mkosi/resources/mkosi.md index 6bfeb37a7..46e5d8b2e 100644 --- a/mkosi/resources/mkosi.md +++ b/mkosi/resources/mkosi.md @@ -28,6 +28,8 @@ mkosi — Build Bespoke OS Images `mkosi [options…] serve` +`mkosi [options…] burn ` + `mkosi [options…] bump` `mkosi [options…] genkey` @@ -125,6 +127,13 @@ The following command line verbs are known: OS images, for example via `machinectl pull-raw …` and `machinectl pull-tar …`. +`burn ` + +: This builds the image if it is not built yet, and then writes it to the + specified block device. The partition contents are written as-is, but the GPT + partition table is corrected to match sector and disk size of the specified + medium. + `bump` : Bumps the image version from `mkosi.version` and writes the resulting