]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
sysupdate: Don't use temporary directory for on demand split partitions 3516/head
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Sat, 15 Feb 2025 20:15:15 +0000 (21:15 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Sun, 16 Feb 2025 13:40:45 +0000 (14:40 +0100)
Instead, we can easily find out the split partitions after running repart
and just make sure to delete them again on exit.

mkosi/sysupdate.py

index 3a5c31ba5d5e66c100d80ac66bf8d24ef81f38b2..6d18f58841662dffa362cbc372ec2c54446709a8 100644 (file)
@@ -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",