From: Daan De Meyer Date: Sat, 15 Feb 2025 20:15:15 +0000 (+0100) Subject: sysupdate: Don't use temporary directory for on demand split partitions X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F3516%2Fhead;p=thirdparty%2Fmkosi.git sysupdate: Don't use temporary directory for on demand split partitions Instead, we can easily find out the split partitions after running repart and just make sure to delete them again on exit. --- diff --git a/mkosi/sysupdate.py b/mkosi/sysupdate.py index 3a5c31ba5..6d18f5884 100644 --- a/mkosi/sysupdate.py +++ b/mkosi/sysupdate.py @@ -1,5 +1,6 @@ # SPDX-License-Identifier: LGPL-2.1-or-later +import contextlib import os import subprocess import sys @@ -9,7 +10,6 @@ from pathlib import Path from mkosi.config import Args, ArtifactOutput, Config, OutputFormat from mkosi.log import die from mkosi.run import run, workdir -from mkosi.tree import copy_tree from mkosi.user import become_root_cmd from mkosi.util import PathString, flatten @@ -25,33 +25,25 @@ def run_sysupdate(args: Args, config: Config) -> None: if not (sysupdate := config.find_binary("systemd-sysupdate", "/usr/lib/systemd/systemd-sysupdate")): die("Could not find systemd-sysupdate") - with tempfile.TemporaryDirectory(prefix="mkosi-tmp", dir=config.output_dir_or_cwd()) as tmp: + with contextlib.ExitStack() as stack: if config.tools() != Path("/"): # We explicitly run this without a sandbox, because / has to be the original root mountpoint for # bootctl --print-root-device to work properly. blockdev = run(["bootctl", "--print-root-device"], stdout=subprocess.PIPE).stdout.strip() + tmp = stack.enter_context(tempfile.TemporaryDirectory()) # If /run/systemd/volatile-root exists, systemd skips its root block device detection logic and # uses whatever block device /run/systemd/volatile-root points to instead. Let's make use of that # when using a tools tree as in that case the block device detection logic doesn't work properly. (Path(tmp) / "volatile-root").symlink_to(blockdev) + else: + tmp = None if ( config.output_format == OutputFormat.disk and ArtifactOutput.partitions not in config.split_artifacts ): - copy_tree( - config.output_dir_or_cwd() / config.output_with_format, - Path(tmp), - sandbox=config.sandbox, - ) - - if (config.output_dir_or_cwd() / config.output_split_uki).exists(): - copy_tree( - config.output_dir_or_cwd() / config.output_split_uki, - Path(tmp), - sandbox=config.sandbox, - ) + old = {p for p in config.output_dir_or_cwd().iterdir() if p.is_file()} # If we didn't generate split partitions as part of the image build, let's do it now. run( @@ -59,25 +51,24 @@ def run_sysupdate(args: Args, config: Config) -> None: "systemd-repart", "--split=yes", *([f"--definitions={workdir(d)}" for d in config.repart_dirs]), - workdir(Path(tmp) / config.output_with_format), + workdir(config.output_dir_or_cwd() / config.output_with_format), ], sandbox=config.sandbox( options=[ - "--ro-bind", config.output_dir_or_cwd(), workdir(config.output_dir_or_cwd()), - "--bind", tmp, workdir(Path(tmp)), + "--bind", config.output_dir_or_cwd(), workdir(config.output_dir_or_cwd()), *flatten(["--ro-bind", os.fspath(d), workdir(d)] for d in config.repart_dirs), ], ), ) # fmt: skip - source = Path(tmp) - else: - source = config.output_dir_or_cwd() + for p in config.output_dir_or_cwd().iterdir(): + if p not in old and p.is_file(): + stack.callback(p.unlink) cmd: list[PathString] = [ sysupdate, "--definitions", config.sysupdate_dir, - "--transfer-source", source, + "--transfer-source", config.output_dir_or_cwd(), *args.cmdline, ] # fmt: skip @@ -102,7 +93,7 @@ def run_sysupdate(args: Args, config: Config) -> None: "--bind", "/usr/lib/os-release", "/usr/lib/os-release", "--bind", tmp, "/run/systemd", ] - if config.tools() != Path("/") + if tmp else [] ), "--same-dir",