Skip to content

Commit

Permalink
sysupdate: Make it work in combination with a tools tree
Browse files Browse the repository at this point in the history
- 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.
  • Loading branch information
DaanDeMeyer committed Nov 22, 2024
1 parent 6a1f166 commit b8d8a7c
Showing 1 changed file with 49 additions and 26 deletions.
75 changes: 49 additions & 26 deletions mkosi/sysupdate.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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

0 comments on commit b8d8a7c

Please sign in to comment.