From: Daan De Meyer Date: Thu, 21 Nov 2024 20:51:43 +0000 (+0100) Subject: sysupdate: Make it work in combination with a tools tree X-Git-Tag: v25~153 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b8d8a7c94d3a849020858affef040fbcf21fe1e4;p=thirdparty%2Fmkosi.git sysupdate: Make it work in combination with a tools tree - We have to make sure systemd-sysupdate looks at the os-release from the host even when using a tools tree. - systemd-sysupdate can't detect the root block device when running with a tools tree. Let's abuse /run/systemd/volatile-root to shortcut the detection logic instead. --- diff --git a/mkosi/sysupdate.py b/mkosi/sysupdate.py index 5bc737f77..f23c2edfa 100644 --- a/mkosi/sysupdate.py +++ b/mkosi/sysupdate.py @@ -1,7 +1,9 @@ # SPDX-License-Identifier: LGPL-2.1-or-later import os +import subprocess import sys +import tempfile from pathlib import Path from mkosi.config import Args, ArtifactOutput, Config @@ -24,29 +26,50 @@ 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") - cmd: list[PathString] = [ - sysupdate, - "--definitions", config.sysupdate_dir, - "--transfer-source", config.output_dir_or_cwd(), - *args.cmdline, - ] # fmt: skip - - run( - cmd, - stdin=sys.stdin, - stdout=sys.stdout, - env=os.environ | config.environment, - log=False, - sandbox=config.sandbox( - binary=sysupdate, - devices=True, - network=True, - relaxed=True, - setup=["run0"] if os.getuid() != 0 else [], - options=[ - *(["--bind", "/boot", "/boot"] if Path("/boot").exists() else []), - *(["--bind", "/efi", "/efi"] if Path("/efi").exists() else []), - "--same-dir", - ], - ), - ) + with tempfile.TemporaryDirectory() as tmp: + 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() + + # 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) + + cmd: list[PathString] = [ + sysupdate, + "--definitions", config.sysupdate_dir, + "--transfer-source", config.output_dir_or_cwd(), + *args.cmdline, + ] # fmt: skip + + run( + cmd, + stdin=sys.stdin, + stdout=sys.stdout, + env=os.environ | config.environment, + log=False, + sandbox=config.sandbox( + binary=sysupdate, + devices=True, + network=True, + relaxed=True, + setup=["run0"] if os.getuid() != 0 else [], + options=[ + *(["--bind", "/boot", "/boot"] if Path("/boot").exists() else []), + *(["--bind", "/efi", "/efi"] if Path("/efi").exists() else []), + *( + [ + # Make sure systemd-sysupdate parses os-release from the host and not the tools + # tree. + "--bind", "/usr/lib/os-release", "/usr/lib/os-release", + "--bind", tmp, "/run/systemd", + ] + if config.tools() != Path("/") + else [] + ), + "--same-dir", + ], + ), + ) # fmt: skip