]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
tree-wide: Use workdir() everywhere 3103/head
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 4 Oct 2024 18:37:05 +0000 (20:37 +0200)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 4 Oct 2024 19:57:10 +0000 (21:57 +0200)
Let's make sure we mount inputs and outputs to various tools in a
completely separate directory than the base ones that are in the
sandbox.

12 files changed:
mkosi/__init__.py
mkosi/archive.py
mkosi/bootloader.py
mkosi/config.py
mkosi/curl.py
mkosi/distributions/debian.py
mkosi/installer/apt.py
mkosi/installer/dnf.py
mkosi/installer/pacman.py
mkosi/installer/zypper.py
mkosi/partition.py
mkosi/qemu.py

index b66a9b5390188a31a8eb2a39486985fc2c5b4d0c..58edc76816ba80e3463a3a167ed2b6cc3a730347 100644 (file)
@@ -1511,15 +1511,15 @@ def run_ukify(
         "build",
         *arguments,
         "--efi-arch", arch,
-        "--stub", stub,
+        "--stub", workdir(stub),
         "--output", workdir(output),
-        *(["--cmdline", f"@{context.workspace / 'cmdline'}"] if cmdline else []),
+        *(["--cmdline", f"@{workdir(context.workspace / 'cmdline')}"] if cmdline else []),
     ]  # fmt: skip
 
     opt: list[PathString] = [
-        "--ro-bind", stub, stub,
+        "--ro-bind", stub, workdir(stub),
         "--bind", output.parent, workdir(output.parent),
-        "--ro-bind", context.workspace / "cmdline", context.workspace / "cmdline",
+        "--ro-bind", context.workspace / "cmdline", workdir(context.workspace / "cmdline"),
     ]  # fmt: skip
 
     if sign and context.config.secure_boot:
@@ -1529,27 +1529,27 @@ def run_ukify(
         if context.config.secure_boot_sign_tool != SecureBootSignTool.pesign:
             cmd += [
                 "--signtool", "sbsign",
-                "--secureboot-private-key", context.config.secure_boot_key,
-                "--secureboot-certificate", context.config.secure_boot_certificate,
+                "--secureboot-certificate", workdir(context.config.secure_boot_certificate),
             ]  # fmt: skip
             opt += [
-                "--ro-bind", context.config.secure_boot_certificate, context.config.secure_boot_certificate,
+                "--ro-bind", context.config.secure_boot_certificate, workdir(context.config.secure_boot_certificate), # noqa
             ]  # fmt: skip
             if context.config.secure_boot_key_source.type == KeySourceType.engine:
                 cmd += ["--signing-engine", context.config.secure_boot_key_source.source]
                 opt += ["--bind-try", "/run/pcscd", "/run/pcscd"]
             if context.config.secure_boot_key.exists():
-                opt += ["--ro-bind", context.config.secure_boot_key, context.config.secure_boot_key]
+                cmd += ["--secureboot-private-key", workdir(context.config.secure_boot_key)]
+                opt += ["--ro-bind", context.config.secure_boot_key, workdir(context.config.secure_boot_key)]
+            else:
+                cmd += ["--secureboot-private-key", context.config.secure_boot_key]
         else:
             pesign_prepare(context)
             cmd += [
                 "--signtool", "pesign",
-                "--secureboot-certificate-dir",
-                context.workspace / "pesign",
-                "--secureboot-certificate-name",
-                certificate_common_name(context, context.config.secure_boot_certificate),
+                "--secureboot-certificate-dir", workdir(context.workspace / "pesign"),
+                "--secureboot-certificate-name", certificate_common_name(context, context.config.secure_boot_certificate), # noqa
             ]  # fmt: skip
-            opt += ["--ro-bind", context.workspace / "pesign", context.workspace / "pesign"]
+            opt += ["--ro-bind", context.workspace / "pesign", workdir(context.workspace / "pesign")]
 
     run(
         cmd,
@@ -1576,17 +1576,16 @@ def build_uki(
         die("Could not find ukify")
 
     arguments: list[PathString] = [
-        "--os-release", f"@{context.root / 'usr/lib/os-release'}",
+        "--os-release", f"@{workdir(context.root / 'usr/lib/os-release')}",
         "--uname", kver,
-        "--linux", kimg,
-        *flatten(["--join-profile", os.fspath(profile)] for profile in profiles),
+        "--linux", workdir(kimg),
+        *flatten(["--join-profile", os.fspath(workdir(profile))] for profile in profiles),
     ]  # fmt: skip
 
     options: list[PathString] = [
-        "--ro-bind", context.workspace / "cmdline", context.workspace / "cmdline",
-        "--ro-bind", context.root / "usr/lib/os-release", context.root / "usr/lib/os-release",
-        "--ro-bind", kimg, kimg,
-        *flatten(["--ro-bind", os.fspath(profile), os.fspath(profile)] for profile in profiles),
+        "--ro-bind", context.root / "usr/lib/os-release", workdir(context.root / "usr/lib/os-release"),
+        "--ro-bind", kimg, workdir(kimg),
+        *flatten(["--ro-bind", os.fspath(profile), os.fspath(workdir(profile))] for profile in profiles),
     ]  # fmt: skip
 
     if context.config.secure_boot:
@@ -1598,26 +1597,31 @@ def build_uki(
     if want_signed_pcrs(context.config):
         assert context.config.sign_expected_pcr_key
         assert context.config.sign_expected_pcr_certificate
+
         arguments += [
-            "--pcr-private-key", context.config.sign_expected_pcr_key,
             # SHA1 might be disabled in OpenSSL depending on the distro so we opt to not sign
             # for SHA1 to avoid having to manage a bunch of configuration to re-enable SHA1.
             "--pcr-banks", "sha256",
         ]  # fmt: skip
-        if context.config.sign_expected_pcr_key.exists():
-            options += ["--bind", context.config.sign_expected_pcr_key, context.config.sign_expected_pcr_key]
+
         if context.config.sign_expected_pcr_key_source.type == KeySourceType.engine:
             arguments += [
                 "--signing-engine", context.config.sign_expected_pcr_key_source.source,
-                "--pcr-public-key", context.config.sign_expected_pcr_certificate,
+                "--pcr-public-key", workdir(context.config.sign_expected_pcr_certificate),
             ]  # fmt: skip
             options += [
-                "--ro-bind",
-                context.config.sign_expected_pcr_certificate,
-                context.config.sign_expected_pcr_certificate,
+                "--ro-bind", context.config.sign_expected_pcr_certificate, workdir(context.config.sign_expected_pcr_certificate), # noqa
                 "--bind-try", "/run/pcscd", "/run/pcscd",
             ]  # fmt: skip
 
+        if context.config.sign_expected_pcr_key.exists():
+            arguments += ["--pcr-private-key", workdir(context.config.sign_expected_pcr_key)]
+            options += [
+                "--ro-bind", context.config.sign_expected_pcr_key, workdir(context.config.sign_expected_pcr_key), # noqa
+            ]  # fmt: skip
+        else:
+            arguments += ["--pcr-private-key", context.config.sign_expected_pcr_key]
+
     if microcodes:
         # new .ucode section support?
         if (
@@ -1631,14 +1635,14 @@ def build_uki(
             and version >= "256"
         ):
             for microcode in microcodes:
-                arguments += ["--microcode", microcode]
-                options += ["--ro-bind", microcode, microcode]
+                arguments += ["--microcode", workdir(microcode)]
+                options += ["--ro-bind", microcode, workdir(microcode)]
         else:
             initrds = microcodes + initrds
 
     for initrd in initrds:
-        arguments += ["--initrd", initrd]
-        options += ["--ro-bind", initrd, initrd]
+        arguments += ["--initrd", workdir(initrd)]
+        options += ["--ro-bind", initrd, workdir(initrd)]
 
     with complete_step(f"Generating unified kernel image for kernel version {kver}"):
         run_ukify(context, stub, output, cmdline=" ".join(cmdline), arguments=arguments, options=options)
@@ -1980,8 +1984,8 @@ def install_pe_addons(context: Context) -> None:
                 context,
                 stub,
                 output,
-                arguments=["--config", addon],
-                options=["--ro-bind", addon, addon],
+                arguments=["--config", workdir(addon)],
+                options=["--ro-bind", addon, workdir(addon)],
             )
 
 
@@ -2021,8 +2025,8 @@ def build_uki_profiles(context: Context, cmdline: Sequence[str]) -> list[Path]:
                 stub,
                 output,
                 cmdline=f"{' '.join(cmdline)} {profile_cmdline}",
-                arguments=["--config", profile],
-                options=["--ro-bind", profile, profile],
+                arguments=["--config", workdir(profile)],
+                options=["--ro-bind", profile, workdir(profile)],
                 sign=False,
             )
 
@@ -2248,12 +2252,12 @@ def calculate_signature(context: Context) -> None:
     if not home.exists():
         die(f"GPG home {home} not found")
 
-    env = dict(GNUPGHOME=os.fspath(home))
+    env = dict(GNUPGHOME=os.fspath(workdir(home)))
     if sys.stderr.isatty():
         env |= dict(GPG_TTY=os.ttyname(sys.stderr.fileno()))
 
     options: list[PathString] = [
-        "--bind", home, home,
+        "--bind", home, workdir(home),
         "--bind", context.staging, workdir(context.staging),
         "--bind", "/run", "/run",
     ]  # fmt: skip
@@ -2880,13 +2884,13 @@ def have_cache(config: Config) -> bool:
             logging.info("Cache manifest mismatch, not reusing cached images")
             if ARG_DEBUG.get():
                 run(
-                    ["diff", "--unified", manifest, "-"],
+                    ["diff", "--unified", workdir(manifest), "-"],
                     input=new,
                     check=False,
                     sandbox=config.sandbox(
                         binary="diff",
                         tools=False,
-                        options=["--bind", manifest, manifest],
+                        options=["--bind", manifest, workdir(manifest)],
                     ),
                 )
 
@@ -2999,7 +3003,7 @@ def make_image(
             "--ro-bind",
             context.config.verity_certificate,
             workdir(context.config.verity_certificate),
-        ]
+        ]  # noqa
     if skip:
         cmdline += ["--defer-partitions", ",".join(skip)]
     if split:
@@ -3274,7 +3278,7 @@ def make_extension_image(context: Context, output: Path) -> None:
         "--seed", str(context.config.seed) if context.config.seed else "random",
         "--empty=create",
         "--size=auto",
-        "--definitions", r,
+        "--definitions", workdir(r),
         workdir(output),
     ]  # fmt: skip
     options: list[PathString] = [
@@ -3283,23 +3287,29 @@ def make_extension_image(context: Context, output: Path) -> None:
         "--become-root",
         "--bind", output.parent, workdir(output.parent),
         "--ro-bind", context.root, "/buildroot",
-        "--ro-bind", r, r,
+        "--ro-bind", r, workdir(r),
     ]  # fmt: skip
 
     if not context.config.architecture.is_native():
         cmdline += ["--architecture", str(context.config.architecture)]
     if context.config.passphrase:
         cmdline += ["--key-file", context.config.passphrase]
-        options += ["--ro-bind", context.config.passphrase, context.config.passphrase]
+        options += ["--ro-bind", context.config.passphrase, workdir(context.config.passphrase)]
     if context.config.verity_key:
-        cmdline += ["--private-key", context.config.verity_key]
         if context.config.verity_key_source.type != KeySourceType.file:
             cmdline += ["--private-key-source", str(context.config.verity_key_source)]
         if context.config.verity_key.exists():
-            options += ["--ro-bind", context.config.verity_key, context.config.verity_key]
+            cmdline += ["--private-key", workdir(context.config.verity_key)]
+            options += ["--ro-bind", context.config.verity_key, workdir(context.config.verity_key)]
+        else:
+            cmdline += ["--private-key", context.config.verity_key]
     if context.config.verity_certificate:
-        cmdline += ["--certificate", context.config.verity_certificate]
-        options += ["--ro-bind", context.config.verity_certificate, context.config.verity_certificate]
+        cmdline += ["--certificate", workdir(context.config.verity_certificate)]
+        options += [
+            "--ro-bind",
+            context.config.verity_certificate,
+            workdir(context.config.verity_certificate),
+        ]  # noqa
     if context.config.sector_size:
         cmdline += ["--sector-size", str(context.config.sector_size)]
     if context.config.split_artifacts:
@@ -3421,12 +3431,12 @@ def copy_repository_metadata(config: Config, dst: Path) -> None:
                 exclude: list[PathString]
                 if d == "cache":
                     exclude = flatten(
-                        ("--ro-bind", tmp, p)
+                        ("--ro-bind", tmp, workdir(p))
                         for p in config.distribution.package_manager(config).cache_subdirs(src)
                     )
                 else:
                     exclude = flatten(
-                        ("--ro-bind", tmp, p)
+                        ("--ro-bind", tmp, workdir(p))
                         for p in config.distribution.package_manager(config).state_subdirs(src)
                     )
 
@@ -3683,13 +3693,13 @@ def run_shell(args: Args, config: Config) -> None:
             run(
                 [
                     "systemd-repart",
-                    "--image", fname,
+                    "--image", workdir(fname),
                     *([f"--size={config.runtime_size}"] if config.runtime_size else []),
                     "--no-pager",
                     "--dry-run=no",
                     "--offline=no",
                     "--pretty=no",
-                    fname,
+                    workdir(fname),
                 ],
                 stdin=sys.stdin,
                 env=config.environment,
@@ -3697,7 +3707,7 @@ def run_shell(args: Args, config: Config) -> None:
                     binary="systemd-repart",
                     network=True,
                     devices=True,
-                    options=["--bind", fname, fname],
+                    options=["--bind", fname, workdir(fname)],
                 ),
             )  # fmt: skip
 
index 6ad8df48a7843be50b20f8dd8ad5cf6019520b68..b735955bfb287c516ecd9fcb659b25e8d6f177f5 100644 (file)
@@ -6,7 +6,7 @@ from pathlib import Path
 from typing import Optional
 
 from mkosi.log import log_step
-from mkosi.run import SandboxProtocol, finalize_passwd_mounts, nosandbox, run
+from mkosi.run import SandboxProtocol, finalize_passwd_mounts, nosandbox, run, workdir
 from mkosi.sandbox import umask
 from mkosi.types import PathString
 from mkosi.util import chdir
@@ -32,7 +32,7 @@ def make_tar(src: Path, dst: Path, *, sandbox: SandboxProtocol = nosandbox) -> N
                 "tar",
                 "--create",
                 "--file", "-",
-                "--directory", src,
+                "--directory", workdir(src),
                 "--acls",
                 "--selinux",
                 # --xattrs implies --format=pax
@@ -49,7 +49,10 @@ def make_tar(src: Path, dst: Path, *, sandbox: SandboxProtocol = nosandbox) -> N
             ],
             stdout=f,
             # Make sure tar uses user/group information from the root directory instead of the host.
-            sandbox=sandbox(binary="tar", options=["--ro-bind", src, src, *finalize_passwd_mounts(src)]),
+            sandbox=sandbox(
+                binary="tar",
+                options=["--ro-bind", src, workdir(src), *finalize_passwd_mounts(src)],
+            ),
         )  # fmt: skip
 
 
@@ -75,8 +78,8 @@ def extract_tar(
         [
             "tar",
             "--extract",
-            "--file", src,
-            "--directory", dst,
+            "--file", workdir(src),
+            "--directory", workdir(dst),
             "--keep-directory-symlink",
             "--no-overwrite-dir",
             "--same-permissions",
@@ -92,7 +95,11 @@ def extract_tar(
         sandbox=sandbox(
             binary="tar",
             # Make sure tar uses user/group information from the root directory instead of the host.
-            options=["--ro-bind", src, src, "--bind", dst, dst, *finalize_passwd_mounts(dst)],
+            options=[
+                "--ro-bind", src, workdir(src),
+                "--bind", dst, workdir(dst),
+                *finalize_passwd_mounts(dst),
+            ],
         ),
     )  # fmt: skip
 
@@ -122,10 +129,13 @@ def make_cpio(
                 "--null",
                 "--format=newc",
                 "--quiet",
-                "--directory", src,
+                "--directory", workdir(src),
                 *(["--owner=0:0"] if os.getuid() != 0 else []),
             ],
             input="\0".join(os.fspath(f) for f in files),
             stdout=f,
-            sandbox=sandbox(binary="cpio", options=["--ro-bind", src, src, *finalize_passwd_mounts(src)]),
+            sandbox=sandbox(
+                binary="cpio",
+                options=["--ro-bind", src, workdir(src), *finalize_passwd_mounts(src)],
+            ),
         )  # fmt: skip
index 2569a7d8c5e4ab21b5905c473aefa118cdd0add3..2fc91691c369ae82dc7ba194dfa6c9d5e52401d2 100644 (file)
@@ -199,11 +199,11 @@ def grub_mkimage(
             [
                 mkimage,
                 "--directory", "/grub",
-                "--config", earlyconfig.name,
+                "--config", workdir(Path(earlyconfig.name)),
                 "--prefix", f"/{context.config.distribution.grub_prefix()}",
-                "--output", output or ("/grub/core.img"),
+                "--output", workdir(output) if output else "/grub/core.img",
                 "--format", target,
-                *(["--sbat", str(sbat)] if sbat else []),
+                *(["--sbat", str(workdir(sbat))] if sbat else []),
                 *(["--disable-shim-lock"] if context.config.shim_bootloader == ShimBootloader.none else []),
                 "cat",
                 "cmp",
@@ -232,9 +232,9 @@ def grub_mkimage(
                 binary=mkimage,
                 options=[
                     "--bind", directory, "/grub",
-                    "--ro-bind", earlyconfig.name, earlyconfig.name,
-                    *(["--bind", str(output.parent), str(output.parent)] if output else []),
-                    *(["--ro-bind", str(sbat), str(sbat)] if sbat else []),
+                    "--ro-bind", earlyconfig.name, workdir(Path(earlyconfig.name)),
+                    *(["--bind", str(output.parent), str(workdir(output.parent))] if output else []),
+                    *(["--ro-bind", str(sbat), str(workdir(sbat))] if sbat else []),
                 ],
             ),
         )  # fmt: skip
@@ -284,7 +284,7 @@ def extract_pe_section(context: Context, binary: Path, section: str, output: Pat
         import pefile
         import sys
         from pathlib import Path
-        pe = pefile.PE("{binary}", fast_load=True)
+        pe = pefile.PE("{workdir(binary)}", fast_load=True)
         section = {{s.Name.decode().strip("\\0"): s for s in pe.sections}}.get("{section}")
         if not section:
             sys.exit(67)
@@ -299,7 +299,7 @@ def extract_pe_section(context: Context, binary: Path, section: str, output: Pat
             stdout=f,
             sandbox=context.sandbox(
                 binary=python_binary(context.config, binary=None),
-                options=["--ro-bind", binary, binary],
+                options=["--ro-bind", binary, workdir(binary)],
             ),
             success_exit_status=(0, 67),
         )
@@ -377,20 +377,22 @@ def grub_bios_setup(context: Context, partitions: Sequence[Partition]) -> None:
         # the bios boot partition. To make installation work unprivileged, we trick grub to think that the
         # root device is our image by mounting over its /proc/self/mountinfo file (where it gets its
         # information from) with our own file correlating the root directory to our image file.
-        mountinfo.write(f"1 0 1:1 / / - fat {context.staging / context.config.output_with_format}\n")
+        mountinfo.write(
+            f"1 0 1:1 / / - fat {workdir(context.staging / context.config.output_with_format)}\n"
+        )
         mountinfo.flush()
 
         run(
             [
                 setup,
                 "--directory", "/grub",
-                context.staging / context.config.output_with_format,
+                workdir(context.staging / context.config.output_with_format),
             ],
             sandbox=context.sandbox(
                 binary=setup,
                 options=[
                     "--bind", directory, "/grub",
-                    "--bind", context.staging, context.staging,
+                    "--bind", context.staging, workdir(context.staging),
                     "--bind", mountinfo.name, "/proc/self/mountinfo",
                 ],
             ),
@@ -420,10 +422,10 @@ def certificate_common_name(context: Context, certificate: Path) -> str:
             "-noout",
             "-subject",
             "-nameopt", "multiline",
-            "-in", certificate,
+            "-in", workdir(certificate),
         ],
         stdout=subprocess.PIPE,
-        sandbox=context.sandbox(binary="openssl", options=["--ro-bind", certificate, certificate]),
+        sandbox=context.sandbox(binary="openssl", options=["--ro-bind", certificate, workdir(certificate)]),
     ).stdout  # fmt: skip
 
     for line in output.splitlines():
@@ -462,15 +464,15 @@ def pesign_prepare(context: Context) -> None:
                 "-certpbe", "NONE",
                 "-nomaciter",
                 "-passout", "pass:",
-                "-inkey", context.config.secure_boot_key,
-                "-in", context.config.secure_boot_certificate,
+                "-inkey", workdir(context.config.secure_boot_key),
+                "-in", workdir(context.config.secure_boot_certificate),
             ],
             stdout=f,
             sandbox=context.sandbox(
                 binary="openssl",
                 options=[
-                    "--ro-bind", context.config.secure_boot_key, context.config.secure_boot_key,
-                    "--ro-bind", context.config.secure_boot_certificate, context.config.secure_boot_certificate,  # noqa
+                    "--ro-bind", context.config.secure_boot_key, workdir(context.config.secure_boot_key),
+                    "--ro-bind", context.config.secure_boot_certificate, workdir(context.config.secure_boot_certificate), # noqa
                 ],
             ),
         )  # fmt: skip
@@ -482,14 +484,14 @@ def pesign_prepare(context: Context) -> None:
             "pk12util",
             "-K", "",
             "-W", "",
-            "-i", context.workspace / "secure-boot.p12",
-            "-d", context.workspace / "pesign",
+            "-i", workdir(context.workspace / "secure-boot.p12"),
+            "-d", workdir(context.workspace / "pesign"),
         ],
         sandbox=context.sandbox(
             binary="pk12util",
             options=[
-                "--ro-bind", context.workspace / "secure-boot.p12", context.workspace / "secure-boot.p12",
-                "--ro-bind", context.workspace / "pesign", context.workspace / "pesign",
+                "--ro-bind", context.workspace / "secure-boot.p12", workdir(context.workspace / "secure-boot.p12"), # noqa
+                "--ro-bind", context.workspace / "pesign", workdir(context.workspace / "pesign"),
             ],
         ),
     )  # fmt: skip
index 37782c40e71f76afb42c1bca5a98701360ec1eac..c7bed5374aeace33111c2d1d800e7f474396b136 100644 (file)
@@ -33,7 +33,7 @@ from typing import Any, Callable, Optional, TypeVar, Union, cast
 from mkosi.distributions import Distribution, detect_distribution
 from mkosi.log import ARG_DEBUG, ARG_DEBUG_SHELL, Style, die
 from mkosi.pager import page
-from mkosi.run import SandboxProtocol, find_binary, nosandbox, run, sandbox_cmd
+from mkosi.run import SandboxProtocol, find_binary, nosandbox, run, sandbox_cmd, workdir
 from mkosi.sandbox import __version__
 from mkosi.types import PathString, SupportsRead
 from mkosi.user import INVOKING_USER
@@ -4732,8 +4732,8 @@ def want_selinux_relabel(
         return None
 
     policy = run(
-        ["sh", "-c", f". {selinux} && echo $SELINUXTYPE"],
-        sandbox=config.sandbox(binary="sh", options=["--ro-bind", selinux, selinux]),
+        ["sh", "-c", f". {workdir(selinux)} && echo $SELINUXTYPE"],
+        sandbox=config.sandbox(binary="sh", options=["--ro-bind", selinux, workdir(selinux)]),
         stdout=subprocess.PIPE,
     ).stdout.strip()
     if not policy:
index 5d792af13510281ba065dc4374c3fe1e9f861b82..2aa91749a3b3454d4aaf5aaca7f95b280529b94a 100644 (file)
@@ -4,7 +4,7 @@ from pathlib import Path
 
 from mkosi.config import Config
 from mkosi.mounts import finalize_crypto_mounts
-from mkosi.run import run
+from mkosi.run import run, workdir
 
 
 def curl(config: Config, url: str, output_dir: Path) -> None:
@@ -12,7 +12,7 @@ def curl(config: Config, url: str, output_dir: Path) -> None:
         [
             "curl",
             "--location",
-            "--output-dir", output_dir,
+            "--output-dir", workdir(output_dir),
             "--remote-name",
             "--no-progress-meter",
             "--fail",
@@ -26,6 +26,6 @@ def curl(config: Config, url: str, output_dir: Path) -> None:
         sandbox=config.sandbox(
             binary="curl",
             network=True,
-            options=["--bind", output_dir, output_dir, *finalize_crypto_mounts(config)],
+            options=["--bind", output_dir, workdir(output_dir), *finalize_crypto_mounts(config)],
         ),
     )  # fmt: skip
index 80875f85acb9ae157ac028f84fc2af00c43a8bf9..7720f583f5fb77ab1ac18001a587c0e28cf47184 100644 (file)
@@ -11,7 +11,7 @@ from mkosi.distributions import DistributionInstaller, PackageType
 from mkosi.installer import PackageManager
 from mkosi.installer.apt import Apt, AptRepository
 from mkosi.log import die
-from mkosi.run import run
+from mkosi.run import run, workdir
 from mkosi.sandbox import umask
 
 
@@ -140,12 +140,12 @@ class Installer(DistributionInstaller):
                 "install",
                 [
                     "-oDebug::pkgDPkgPm=1",
-                    f"-oDPkg::Pre-Install-Pkgs::=cat >{f.name}",
+                    f"-oDPkg::Pre-Install-Pkgs::=cat >{workdir(Path(f.name))}",
                     "?essential",
                     "?exact-name(usr-is-merged)",
                     "base-files",
                 ],
-                options=["--bind", f.name, f.name],
+                options=["--bind", f.name, workdir(Path(f.name))],
             )
 
             essential = f.read().strip().splitlines()
index ab71473b6f81c96213b98dd45f1b78a397677871..c1dbec6fcc49d8fdbec6b6d09057ef637452f843 100644 (file)
@@ -10,7 +10,7 @@ from mkosi.config import PACKAGE_GLOBS, Config, ConfigFeature
 from mkosi.context import Context
 from mkosi.installer import PackageManager
 from mkosi.log import die
-from mkosi.run import run
+from mkosi.run import run, workdir
 from mkosi.sandbox import umask
 from mkosi.types import _FILE, CompletedProcess, PathString
 
@@ -256,9 +256,12 @@ class Apt(PackageManager):
             ],
             sandbox=context.sandbox(
                 binary="reprepro",
-                options=["--bind", context.repository, context.repository, "--chdir", context.repository],
+                options=[
+                    "--bind", context.repository, workdir(context.repository),
+                    "--chdir", workdir(context.repository),
+                ],
             ),
-        )
+        )  # fmt: skip
 
         (context.sandbox_tree / "etc/apt/sources.list.d").mkdir(parents=True, exist_ok=True)
         (context.sandbox_tree / "etc/apt/sources.list.d/mkosi-local.sources").write_text(
index 63f4db2a55fff85bd1114d99ea0da9d2b4d94a10..aa70f756ee00af23a14c4ce243b69904859d96c2 100644 (file)
@@ -8,7 +8,7 @@ from mkosi.context import Context
 from mkosi.installer import PackageManager
 from mkosi.installer.rpm import RpmRepository, rpm_cmd
 from mkosi.log import ARG_DEBUG
-from mkosi.run import run
+from mkosi.run import run, workdir
 from mkosi.types import _FILE, CompletedProcess, PathString
 
 
@@ -217,9 +217,9 @@ class Dnf(PackageManager):
     @classmethod
     def createrepo(cls, context: Context) -> None:
         run(
-            ["createrepo_c", context.repository],
+            ["createrepo_c", workdir(context.repository)],
             sandbox=context.sandbox(
-                binary="createrepo_c", options=["--bind", context.repository, context.repository]
+                binary="createrepo_c", options=["--bind", context.repository, workdir(context.repository)]
             ),
         )
 
index 729bbac8c5f171141f99543f2133187d5f0ebf6c..63d08a6c28e85a689c35d409282d02161da6e3d9 100644 (file)
@@ -9,7 +9,7 @@ from pathlib import Path
 from mkosi.config import Config
 from mkosi.context import Context
 from mkosi.installer import PackageManager
-from mkosi.run import run
+from mkosi.run import run, workdir
 from mkosi.sandbox import umask
 from mkosi.types import _FILE, CompletedProcess, PathString
 from mkosi.versioncomp import GenericVersion
@@ -181,11 +181,15 @@ class Pacman(PackageManager):
             [
                 "repo-add",
                 "--quiet",
-                context.repository / "mkosi.db.tar",
-                *sorted(context.repository.glob("*.pkg.tar*"), key=lambda p: GenericVersion(Path(p).name)),
+                workdir(context.repository / "mkosi.db.tar"),
+                *sorted(
+                    (workdir(p) for p in context.repository.glob("*.pkg.tar*")),
+                    key=lambda p: GenericVersion(Path(p).name),
+                ),
             ],
             sandbox=context.sandbox(
-                binary="repo-add", options=["--bind", context.repository, context.repository]
+                binary="repo-add",
+                options=["--bind", context.repository, workdir(context.repository)],
             ),
         )
 
index 90f78a990946c7505d21ca76f67d057d0dfdd552..16ad76d49e4a5c2434f9fb4afe7631f5db925c41 100644 (file)
@@ -8,7 +8,7 @@ from mkosi.config import Config, yes_no
 from mkosi.context import Context
 from mkosi.installer import PackageManager
 from mkosi.installer.rpm import RpmRepository, rpm_cmd
-from mkosi.run import run
+from mkosi.run import run, workdir
 from mkosi.types import _FILE, CompletedProcess, PathString
 
 
@@ -138,9 +138,10 @@ class Zypper(PackageManager):
     @classmethod
     def createrepo(cls, context: Context) -> None:
         run(
-            ["createrepo_c", context.repository],
+            ["createrepo_c", workdir(context.repository)],
             sandbox=context.sandbox(
-                binary="createrepo_c", options=["--bind", context.repository, context.repository]
+                binary="createrepo_c",
+                options=["--bind", context.repository, workdir(context.repository)],
             ),
         )
 
index 58949216ecadbcca8237549353aa9d9f9d3af50d..e6972de56228a2816f7bd52b7f3a5bfa72f335d2 100644 (file)
@@ -6,7 +6,7 @@ from pathlib import Path
 from typing import Any, Final, Optional
 
 from mkosi.log import die
-from mkosi.run import SandboxProtocol, nosandbox, run
+from mkosi.run import SandboxProtocol, nosandbox, run, workdir
 
 
 @dataclasses.dataclass(frozen=True)
@@ -33,10 +33,10 @@ class Partition:
 def find_partitions(image: Path, *, sandbox: SandboxProtocol = nosandbox) -> list[Partition]:
     output = json.loads(
         run(
-            ["systemd-repart", "--json=short", image],
+            ["systemd-repart", "--json=short", workdir(image)],
             stdout=subprocess.PIPE,
             stderr=subprocess.DEVNULL,
-            sandbox=sandbox(binary="systemd-repart", options=["--ro-bind", image, image]),
+            sandbox=sandbox(binary="systemd-repart", options=["--ro-bind", image, workdir(image)]),
         ).stdout
     )
     return [Partition.from_dict(d) for d in output]
index 260afe3eb9b00bec9e0b9faa19b3f391ddb1cb93..93ce6b247c55d039d1a124c86f1a92cc56f906c8 100644 (file)
@@ -158,9 +158,9 @@ class KernelType(StrEnum):
             return KernelType.unknown
 
         type = run(
-            ["bootctl", "kernel-identify", path],
+            ["bootctl", "kernel-identify", workdir(path)],
             stdout=subprocess.PIPE,
-            sandbox=config.sandbox(binary="bootctl", options=["--ro-bind", path, path]),
+            sandbox=config.sandbox(binary="bootctl", options=["--ro-bind", path, workdir(path)]),
         ).stdout.strip()
 
         try:
@@ -253,7 +253,7 @@ def start_swtpm(config: Config) -> Iterator[Path]:
         run(
             [
                 "swtpm_setup",
-                "--tpm-state", state,
+                "--tpm-state", workdir(Path(state)),
                 "--tpm2",
                 "--pcr-banks",
                 "sha256",
@@ -261,12 +261,12 @@ def start_swtpm(config: Config) -> Iterator[Path]:
             ],
             sandbox=config.sandbox(
                 binary="swtpm_setup",
-                options=["--bind", state, state],
+                options=["--bind", state, workdir(Path(state))],
             ),
             stdout=None if ARG_DEBUG.get() else subprocess.DEVNULL,
         )  # fmt: skip
 
-        cmdline = ["swtpm", "socket", "--tpm2", "--tpmstate", f"dir={state}"]
+        cmdline = ["swtpm", "socket", "--tpm2", "--tpmstate", f"dir={workdir(Path(state))}"]
 
         # We create the socket ourselves and pass the fd to swtpm to avoid race conditions where we start
         # qemu before swtpm has had the chance to create the socket (or where we try to chown it first).
@@ -282,7 +282,7 @@ def start_swtpm(config: Config) -> Iterator[Path]:
                 pass_fds=(sock.fileno(),),
                 sandbox=config.sandbox(
                     binary="swtpm",
-                    options=["--bind", state, state],
+                    options=["--bind", state, workdir(Path(state))],
                     setup=scope_cmd(
                         name=f"mkosi-swtpm-{config.machine_or_name()}",
                         description=f"swtpm for {config.machine_or_name()}",
@@ -578,16 +578,16 @@ def copy_ephemeral(config: Config, src: Path) -> Iterator[Path]:
                 become_root_in_subuid_range()
             elif config.output_format in (OutputFormat.disk, OutputFormat.esp):
                 attr = run(
-                    ["lsattr", "-l", src],
-                    sandbox=config.sandbox(binary="lsattr", options=["--ro-bind", src, src]),
+                    ["lsattr", "-l", workdir(src)],
+                    sandbox=config.sandbox(binary="lsattr", options=["--ro-bind", src, workdir(src)]),
                     stdout=subprocess.PIPE,
                 ).stdout
 
                 if "No_COW" in attr:
                     tmp.touch()
                     run(
-                        ["chattr", "+C", tmp],
-                        sandbox=config.sandbox(binary="chattr", options=["--bind", tmp, tmp]),
+                        ["chattr", "+C", workdir(tmp)],
+                        sandbox=config.sandbox(binary="chattr", options=["--bind", tmp, workdir(tmp)]),
                     )
 
             copy_tree(
@@ -638,9 +638,12 @@ def generate_scratch_fs(config: Config) -> Iterator[Path]:
         fs = config.distribution.filesystem()
         extra = config.environment.get(f"SYSTEMD_REPART_MKFS_OPTIONS_{fs.upper()}", "")
         run(
-            [f"mkfs.{fs}", "-L", "scratch", *extra.split(), scratch.name],
+            [f"mkfs.{fs}", "-L", "scratch", *extra.split(), workdir(Path(scratch.name))],
             stdout=subprocess.DEVNULL,
-            sandbox=config.sandbox(binary=f"mkfs.{fs}", options=["--bind", scratch.name, scratch.name]),
+            sandbox=config.sandbox(
+                binary=f"mkfs.{fs}",
+                options=["--bind", scratch.name, workdir(Path(scratch.name))],
+            ),
         )
         yield Path(scratch.name)
 
@@ -686,10 +689,10 @@ def finalize_firmware_variables(
         run(
             [
                 "virt-fw-vars",
-                "--input", ovmf.vars,
-                "--output", ovmf_vars.name,
-                "--enroll-cert", config.secure_boot_certificate,
-                "--add-db", "OvmfEnrollDefaultKeys", config.secure_boot_certificate,
+                "--input", workdir(ovmf.vars),
+                "--output", workdir(Path(ovmf_vars.name)),
+                "--enroll-cert", workdir(config.secure_boot_certificate),
+                "--add-db", "OvmfEnrollDefaultKeys", workdir(config.secure_boot_certificate),
                 "--no-microsoft",
                 "--secure-boot",
                 "--loglevel", "WARNING",
@@ -697,8 +700,9 @@ def finalize_firmware_variables(
             sandbox=config.sandbox(
                 binary=qemu,
                 options=[
-                    "--bind", ovmf_vars.name, ovmf_vars.name,
-                    "--ro-bind", config.secure_boot_certificate, config.secure_boot_certificate,
+                    "--bind", ovmf_vars.name, workdir(Path(ovmf_vars.name)),
+                    "--ro-bind", ovmf.vars, workdir(ovmf.vars),
+                    "--ro-bind", config.secure_boot_certificate, workdir(config.secure_boot_certificate),
                 ],
             ),
         )  # fmt: skip
@@ -729,9 +733,9 @@ def apply_runtime_size(config: Config, image: Path) -> None:
             f"--size={round_up(config.runtime_size, resource.getpagesize())}",
             "--pretty=no",
             "--offline=yes",
-            image,
+            workdir(image),
         ],
-        sandbox=config.sandbox(binary="systemd-repart", options=["--bind", image, image]),
+        sandbox=config.sandbox(binary="systemd-repart", options=["--bind", image, workdir(image)]),
     )  # fmt: skip