]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
Always mount context.root to /buildroot 2513/head
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 15 Mar 2024 12:09:39 +0000 (13:09 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 15 Mar 2024 16:25:48 +0000 (17:25 +0100)
Let's leak fewer host specific details into the sandbox by always
mounting the image root directory to /buildroot in the sandbox. This
also simplifies debugging as the image rootfs will always be at /rootfs
instead of in some host specific path.

mkosi/__init__.py
mkosi/installer/apt.py
mkosi/installer/dnf.py
mkosi/installer/pacman.py
mkosi/installer/rpm.py
mkosi/installer/zypper.py
mkosi/manifest.py
mkosi/sandbox.py

index 47741e762cb3be1b6b1a409745f34e92cbfb8468..67cc46d4342b40f5b52cc054fc9dde69a345a974 100644 (file)
@@ -404,7 +404,7 @@ def finalize_host_scripts(
         scripts["git"] = GIT_COMMAND
     for binary in ("useradd", "groupadd"):
         if find_binary(binary, root=context.config.tools()):
-            scripts[binary] = (binary, "--root", context.root)
+            scripts[binary] = (binary, "--root", "/buildroot")
     return finalize_scripts(scripts | dict(helpers), root=context.config.tools())
 
 
@@ -487,7 +487,7 @@ def run_prepare_scripts(context: Context, build: bool) -> None:
         DISTRIBUTION=str(context.config.distribution),
         RELEASE=context.config.release,
         ARCHITECTURE=str(context.config.architecture),
-        BUILDROOT=str(context.root),
+        BUILDROOT="/buildroot",
         SRCDIR="/work/src",
         CHROOT_SRCDIR="/work/src",
         PACKAGEDIR="/work/packages",
@@ -517,7 +517,7 @@ def run_prepare_scripts(context: Context, build: bool) -> None:
             arg = "final"
 
         for script in context.config.prepare_scripts:
-            chroot = chroot_cmd(context.root, resolve=True)
+            chroot = chroot_cmd(resolve=True)
 
             helpers = {
                 "mkosi-chroot": chroot,
@@ -541,7 +541,7 @@ def run_prepare_scripts(context: Context, build: bool) -> None:
                             Mount(script, "/work/prepare", ro=True),
                             Mount(json, "/work/config.json", ro=True),
                             Mount(cd, "/work/scripts", ro=True),
-                            Mount(context.root, context.root),
+                            Mount(context.root, "/buildroot"),
                             *context.config.distribution.package_manager(context.config).mounts(context),
                         ],
                         options=["--dir", "/work/src", "--chdir", "/work/src"],
@@ -558,7 +558,7 @@ def run_build_scripts(context: Context) -> None:
         DISTRIBUTION=str(context.config.distribution),
         RELEASE=context.config.release,
         ARCHITECTURE=str(context.config.architecture),
-        BUILDROOT=str(context.root),
+        BUILDROOT="/buildroot",
         DESTDIR="/work/dest",
         CHROOT_DESTDIR="/work/dest",
         OUTPUTDIR="/work/out",
@@ -591,7 +591,7 @@ def run_build_scripts(context: Context) -> None:
         finalize_source_mounts(context.config, ephemeral=context.config.build_sources_ephemeral) as sources,
     ):
         for script in context.config.build_scripts:
-            chroot = chroot_cmd(context.root, resolve=context.config.with_network)
+            chroot = chroot_cmd(resolve=context.config.with_network)
 
             helpers = {
                 "mkosi-chroot": chroot,
@@ -617,7 +617,7 @@ def run_build_scripts(context: Context) -> None:
                             Mount(script, "/work/build-script", ro=True),
                             Mount(json, "/work/config.json", ro=True),
                             Mount(cd, "/work/scripts", ro=True),
-                            Mount(context.root, context.root),
+                            Mount(context.root, "/buildroot"),
                             Mount(context.install_dir, "/work/dest"),
                             Mount(context.staging, "/work/out"),
                             *(
@@ -645,7 +645,7 @@ def run_postinst_scripts(context: Context) -> None:
         DISTRIBUTION=str(context.config.distribution),
         RELEASE=context.config.release,
         ARCHITECTURE=str(context.config.architecture),
-        BUILDROOT=str(context.root),
+        BUILDROOT="/buildroot",
         OUTPUTDIR="/work/out",
         CHROOT_OUTPUTDIR="/work/out",
         SCRIPT="/work/postinst",
@@ -666,7 +666,7 @@ def run_postinst_scripts(context: Context) -> None:
         finalize_source_mounts(context.config, ephemeral=context.config.build_sources_ephemeral) as sources,
     ):
         for script in context.config.postinst_scripts:
-            chroot = chroot_cmd(context.root, resolve=context.config.with_network)
+            chroot = chroot_cmd(resolve=context.config.with_network)
 
             helpers = {
                 "mkosi-chroot": chroot,
@@ -690,7 +690,7 @@ def run_postinst_scripts(context: Context) -> None:
                             Mount(script, "/work/postinst", ro=True),
                             Mount(json, "/work/config.json", ro=True),
                             Mount(cd, "/work/scripts", ro=True),
-                            Mount(context.root, context.root),
+                            Mount(context.root, "/buildroot"),
                             Mount(context.staging, "/work/out"),
                             *context.config.distribution.package_manager(context.config).mounts(context),
                         ],
@@ -708,7 +708,7 @@ def run_finalize_scripts(context: Context) -> None:
         DISTRIBUTION=str(context.config.distribution),
         RELEASE=context.config.release,
         ARCHITECTURE=str(context.config.architecture),
-        BUILDROOT=str(context.root),
+        BUILDROOT="/buildroot",
         OUTPUTDIR="/work/out",
         CHROOT_OUTPUTDIR="/work/out",
         SRCDIR="/work/src",
@@ -729,7 +729,7 @@ def run_finalize_scripts(context: Context) -> None:
         finalize_source_mounts(context.config, ephemeral=context.config.build_sources_ephemeral) as sources,
     ):
         for script in context.config.finalize_scripts:
-            chroot = chroot_cmd(context.root, resolve=context.config.with_network)
+            chroot = chroot_cmd(resolve=context.config.with_network)
 
             helpers = {
                 "mkosi-chroot": chroot,
@@ -753,7 +753,7 @@ def run_finalize_scripts(context: Context) -> None:
                             Mount(script, "/work/finalize", ro=True),
                             Mount(json, "/work/config.json", ro=True),
                             Mount(cd, "/work/scripts", ro=True),
-                            Mount(context.root, context.root),
+                            Mount(context.root, "/buildroot"),
                             Mount(context.staging, "/work/out"),
                             *context.config.distribution.package_manager(context.config).mounts(context),
                         ],
@@ -960,9 +960,9 @@ def install_systemd_boot(context: Context) -> None:
 
     with complete_step("Installing systemd-boot…"):
         run(
-            ["bootctl", "install", "--root", context.root, "--all-architectures", "--no-variables"],
+            ["bootctl", "install", "--root=/buildroot", "--all-architectures", "--no-variables"],
             env={"SYSTEMD_ESP_PATH": "/efi", "SYSTEMD_XBOOTLDR_PATH": "/boot"},
-            sandbox=context.sandbox(mounts=[Mount(context.root, context.root)]),
+            sandbox=context.sandbox(mounts=[Mount(context.root, "/buildroot")]),
         )
 
         if context.config.shim_bootloader != ShimBootloader.none:
@@ -1276,10 +1276,10 @@ def grub_mkimage(
         run(
             [
                 mkimage,
-                "--directory", directory,
+                "--directory", "/grub",
                 "--config", earlyconfig.name,
                 "--prefix", f"/{context.config.distribution.grub_prefix()}",
-                "--output", output or (directory / "core.img"),
+                "--output", output or ("/grub/core.img"),
                 "--format", target,
                 *(["--sbat", str(sbat)] if sbat else []),
                 *(["--disable-shim-lock"] if context.config.shim_bootloader == ShimBootloader.none else []),
@@ -1308,8 +1308,9 @@ def grub_mkimage(
             ],
             sandbox=context.sandbox(
                 mounts=[
-                    Mount(context.root, context.root),
+                    Mount(directory, "/grub"),
                     Mount(earlyconfig.name, earlyconfig.name, ro=True),
+                    *([Mount(output.parent, output.parent)] if output else []),
                     *([Mount(str(sbat), str(sbat), ro=True)] if sbat else []),
                 ],
             ),
@@ -1412,12 +1413,12 @@ def grub_bios_setup(context: Context, partitions: Sequence[Partition]) -> None:
             [
                 "sh", "-c", f"mount --bind {mountinfo.name} /proc/$$/mountinfo && exec $0 \"$@\"",
                 setup,
-                "--directory", directory,
+                "--directory", "/grub",
                 context.staging / context.config.output_with_format,
             ],
             sandbox=context.sandbox(
                 mounts=[
-                    Mount(context.root, context.root),
+                    Mount(directory, "/grub"),
                     Mount(context.staging, context.staging),
                     Mount(mountinfo.name, mountinfo.name),
                 ],
@@ -2046,8 +2047,8 @@ def find_entry_token(context: Context) -> str:
     ):
         return context.config.image_id or context.config.distribution.name
 
-    output = json.loads(run(["kernel-install", "--root", context.root, "--json=pretty", "inspect"],
-                            sandbox=context.sandbox(mounts=[Mount(context.root, context.root, ro=True)]),
+    output = json.loads(run(["kernel-install", "--root=/buildroot", "--json=pretty", "inspect"],
+                            sandbox=context.sandbox(mounts=[Mount(context.root, "/buildroot", ro=True)]),
                             stdout=subprocess.PIPE,
                             env={"SYSTEMD_ESP_PATH": "/efi", "SYSTEMD_XBOOTLDR_PATH": "/boot"}).stdout)
     logging.debug(json.dumps(output, indent=4))
@@ -2747,8 +2748,8 @@ def run_depmod(context: Context, *, cache: bool = False) -> None:
             )
 
         with complete_step(f"Running depmod for {kver}"):
-            run(["depmod", "--all", "--basedir", context.root, kver],
-                sandbox=context.sandbox(mounts=[Mount(context.root, context.root)]))
+            run(["depmod", "--all", "--basedir", "/buildroot", kver],
+                sandbox=context.sandbox(mounts=[Mount(context.root, "/buildroot")]))
 
 
 def run_sysusers(context: Context) -> None:
@@ -2757,8 +2758,8 @@ def run_sysusers(context: Context) -> None:
         return
 
     with complete_step("Generating system users"):
-        run(["systemd-sysusers", "--root", context.root],
-            sandbox=context.sandbox(mounts=[Mount(context.root, context.root)]))
+        run(["systemd-sysusers", "--root=/buildroot"],
+            sandbox=context.sandbox(mounts=[Mount(context.root, "/buildroot")]))
 
 
 def run_tmpfiles(context: Context) -> None:
@@ -2769,7 +2770,7 @@ def run_tmpfiles(context: Context) -> None:
     with complete_step("Generating volatile files"):
         cmdline = [
             "systemd-tmpfiles",
-            f"--root={context.root}",
+            "--root=/buildroot",
             "--boot",
             "--create",
             "--remove",
@@ -2779,7 +2780,7 @@ def run_tmpfiles(context: Context) -> None:
 
         sandbox = context.sandbox(
             mounts=[
-                Mount(context.root, context.root),
+                Mount(context.root, "/buildroot"),
                 # systemd uses acl.h to parse ACLs in tmpfiles snippets which uses the host's passwd so we have to
                 # mount the image's passwd over it to make ACL parsing work.
                 *finalize_passwd_mounts(context.root)
@@ -2805,10 +2806,10 @@ def run_preset(context: Context) -> None:
         return
 
     with complete_step("Applying presets…"):
-        run(["systemctl", "--root", context.root, "preset-all"],
-            sandbox=context.sandbox(mounts=[Mount(context.root, context.root)]))
-        run(["systemctl", "--root", context.root, "--global", "preset-all"],
-            sandbox=context.sandbox(mounts=[Mount(context.root, context.root)]))
+        run(["systemctl", "--root=/buildroot", "preset-all"],
+            sandbox=context.sandbox(mounts=[Mount(context.root, "/buildroot")]))
+        run(["systemctl", "--root=/buildroot", "--global", "preset-all"],
+            sandbox=context.sandbox(mounts=[Mount(context.root, "/buildroot")]))
 
 
 def run_hwdb(context: Context) -> None:
@@ -2820,8 +2821,8 @@ def run_hwdb(context: Context) -> None:
         return
 
     with complete_step("Generating hardware database"):
-        run(["systemd-hwdb", "--root", context.root, "--usr", "--strict", "update"],
-            sandbox=context.sandbox(mounts=[Mount(context.root, context.root)]))
+        run(["systemd-hwdb", "--root=/buildroot", "--usr", "--strict", "update"],
+            sandbox=context.sandbox(mounts=[Mount(context.root, "/buildroot")]))
 
     # Remove any existing hwdb in /etc in favor of the one we just put in /usr.
     (context.root / "etc/udev/hwdb.bin").unlink(missing_ok=True)
@@ -2867,8 +2868,8 @@ def run_firstboot(context: Context) -> None:
         return
 
     with complete_step("Applying first boot settings"):
-        run(["systemd-firstboot", "--root", context.root, "--force", *options],
-            sandbox=context.sandbox(mounts=[Mount(context.root, context.root)]))
+        run(["systemd-firstboot", "--root=/buildroot", "--force", *options],
+            sandbox=context.sandbox(mounts=[Mount(context.root, "/buildroot")]))
 
         # Initrds generally don't ship with only /usr so there's not much point in putting the credentials in
         # /usr/lib/credstore.
@@ -2888,8 +2889,8 @@ def run_selinux_relabel(context: Context) -> None:
     policy, fc, binpolicy = selinux
 
     with complete_step(f"Relabeling files using {policy} policy"):
-        run(["setfiles", "-mFr", context.root, "-c", binpolicy, fc, context.root],
-            sandbox=context.sandbox(mounts=[Mount(context.root, context.root)]),
+        run(["setfiles", "-mFr", "/buildroot", "-c", binpolicy, fc, "/buildroot"],
+            sandbox=context.sandbox(mounts=[Mount(context.root, "/buildroot")]),
             check=context.config.selinux_relabel == ConfigFeature.enabled)
 
 
@@ -3033,8 +3034,8 @@ def make_image(
     mounts = [Mount(context.staging, context.staging)]
 
     if root:
-        cmdline += ["--root", root]
-        mounts += [Mount(root, root)]
+        cmdline += ["--root=/buildroot"]
+        mounts += [Mount(root, "/buildroot")]
     if not context.config.architecture.is_native():
         cmdline += ["--architecture", str(context.config.architecture)]
     if not (context.staging / context.config.output_with_format).exists():
@@ -3210,7 +3211,7 @@ def make_esp(context: Context, uki: Path) -> list[Partition]:
 def make_extension_image(context: Context, output: Path) -> None:
     cmdline: list[PathString] = [
         "systemd-repart",
-        "--root", context.root,
+        "--root=/buildroot",
         "--dry-run=no",
         "--no-pager",
         f"--offline={yes_no(context.config.repart_offline)}",
@@ -3221,7 +3222,7 @@ def make_extension_image(context: Context, output: Path) -> None:
     ]
     mounts = [
         Mount(output.parent, output.parent),
-        Mount(context.root, context.root, ro=True),
+        Mount(context.root, "/buildroot", ro=True),
     ]
 
     if not context.config.architecture.is_native():
index 117b9d9fb7354720c95d52ab005188bbe4066dfe..fab81a8eccf3f27633f97d07f40c0c2b65c034c9 100644 (file)
@@ -52,7 +52,7 @@ class Apt(PackageManager):
     def scripts(cls, context: Context) -> dict[str, list[PathString]]:
         return {
             **{
-                command: apivfs_cmd(context.root) + cls.cmd(context, command) for command in (
+                command: apivfs_cmd() + cls.cmd(context, command) for command in (
                     "apt",
                     "apt-cache",
                     "apt-cdrom",
@@ -133,10 +133,10 @@ class Apt(PackageManager):
             "-o", "Dir::Cache=/var/cache/apt",
             "-o", "Dir::State=/var/lib/apt",
             "-o", "Dir::Log=/var/log/apt",
-            "-o", f"Dir::State::Status={context.root / 'var/lib/dpkg/status'}",
+            "-o", "Dir::State::Status=/buildroot/var/lib/dpkg/status",
             "-o", f"Dir::Bin::DPkg={find_binary('dpkg', root=context.config.tools())}",
             "-o", "Debug::NoLocking=true",
-            "-o", f"DPkg::Options::=--root={context.root}",
+            "-o", "DPkg::Options::=--root=/buildroot",
             "-o", "DPkg::Options::=--force-unsafe-io",
             "-o", "DPkg::Options::=--force-architecture",
             "-o", "DPkg::Options::=--force-depends",
@@ -184,9 +184,9 @@ class Apt(PackageManager):
                 sandbox=(
                     context.sandbox(
                         network=True,
-                        mounts=[Mount(context.root, context.root), *cls.mounts(context), *sources, *mounts],
+                        mounts=[Mount(context.root, "/buildroot"), *cls.mounts(context), *sources, *mounts],
                         options=["--dir", "/work/src", "--chdir", "/work/src"],
-                    ) + (apivfs_cmd(context.root) if apivfs else [])
+                    ) + (apivfs_cmd() if apivfs else [])
                 ),
                 env=context.config.environment,
                 stdout=stdout,
index 7b6fc0ede440462882e609864f9713b99602cdd1..2344ec926767a725d79981ccbf7209de340f62cf 100644 (file)
@@ -39,8 +39,8 @@ class Dnf(PackageManager):
     @classmethod
     def scripts(cls, context: Context) -> dict[str, list[PathString]]:
         return {
-            "dnf": apivfs_cmd(context.root) + cls.cmd(context),
-            "rpm": apivfs_cmd(context.root) + rpm_cmd(context),
+            "dnf": apivfs_cmd() + cls.cmd(context),
+            "rpm": apivfs_cmd() + rpm_cmd(),
             "mkosi-install"  : ["dnf", "install"],
             "mkosi-upgrade"  : ["dnf", "upgrade"],
             "mkosi-remove"   : ["dnf", "remove"],
@@ -105,7 +105,7 @@ class Dnf(PackageManager):
             "--assumeyes",
             "--best",
             f"--releasever={context.config.release}",
-            f"--installroot={context.root}",
+            "--installroot=/buildroot",
             "--setopt=keepcache=1",
             "--setopt=logdir=/var/log",
             f"--setopt=cachedir=/var/cache/{cls.subdir(context.config)}",
@@ -170,9 +170,9 @@ class Dnf(PackageManager):
                     sandbox=(
                         context.sandbox(
                             network=True,
-                            mounts=[Mount(context.root, context.root), *cls.mounts(context), *sources],
+                            mounts=[Mount(context.root, "/buildroot"), *cls.mounts(context), *sources],
                             options=["--dir", "/work/src", "--chdir", "/work/src"],
-                        ) + (apivfs_cmd(context.root) if apivfs else [])
+                        ) + (apivfs_cmd() if apivfs else [])
                     ),
                     env=context.config.environment,
                     stdout=stdout,
index e5faeff220844987384812ed1377a5f8322385c4..e700cd8f6e53d53de887a85e8cf6f612d54133ef 100644 (file)
@@ -37,7 +37,7 @@ class Pacman(PackageManager):
     @classmethod
     def scripts(cls, context: Context) -> dict[str, list[PathString]]:
         return {
-            "pacman": apivfs_cmd(context.root) + cls.cmd(context),
+            "pacman": apivfs_cmd() + cls.cmd(context),
             "mkosi-install"  : ["pacman", "--sync", "--needed"],
             "mkosi-upgrade"  : ["pacman", "--sync", "--sysupgrade", "--needed"],
             "mkosi-remove"   : ["pacman", "--remove", "--recursive", "--nosave"],
@@ -128,14 +128,14 @@ class Pacman(PackageManager):
     def cmd(cls, context: Context) -> list[PathString]:
         return [
             "pacman",
-            "--root", context.root,
+            "--root=/buildroot",
             "--logfile=/dev/null",
             "--dbpath=/var/lib/pacman",
             # Make sure pacman looks at our local repository first by putting it as the first cache directory. We mount
             # it read-only so the second directory will still be used for writing new cache entries.
             "--cachedir=/var/cache/pacman/mkosi",
             "--cachedir=/var/cache/pacman/pkg",
-            "--hookdir", context.root / "etc/pacman.d/hooks",
+            "--hookdir=/buildroot/etc/pacman.d/hooks",
             "--arch", context.config.distribution.architecture(context.config.architecture),
             "--color", "auto",
             "--noconfirm",
@@ -160,9 +160,9 @@ class Pacman(PackageManager):
                 sandbox=(
                     context.sandbox(
                         network=True,
-                        mounts=[Mount(context.root, context.root), *cls.mounts(context), *sources],
+                        mounts=[Mount(context.root, "/buildroot"), *cls.mounts(context), *sources],
                         options=["--dir", "/work/src", "--chdir", "/work/src"],
-                    ) + (apivfs_cmd(context.root) if apivfs else [])
+                    ) + (apivfs_cmd() if apivfs else [])
                 ),
                 env=context.config.environment,
                 stdout=stdout,
index 6fb1daab9a30c0167c6994e2b069c5ce983f2a4e..c0e0fe78ebffd57f7f1af31587f943894ddd6eb5 100644 (file)
@@ -67,5 +67,5 @@ def setup_rpm(context: Context, *, dbpath: str = "/usr/lib/sysimage/rpm") -> Non
         )
 
 
-def rpm_cmd(context: Context) -> list[PathString]:
-    return ["env", "HOME=/", "rpm", "--root", context.root]
+def rpm_cmd() -> list[PathString]:
+    return ["env", "HOME=/", "rpm", "--root=/buildroot"]
index 422ff7743a24fb80908646398fd8613e735a7da9..329059b9ecabf3bd54b1010971ab46ea5e3ccbac 100644 (file)
@@ -38,8 +38,8 @@ class Zypper(PackageManager):
         ]
 
         return {
-            "zypper": apivfs_cmd(context.root) + cls.cmd(context),
-            "rpm"   : apivfs_cmd(context.root) + rpm_cmd(context),
+            "zypper": apivfs_cmd() + cls.cmd(context),
+            "rpm"   : apivfs_cmd() + rpm_cmd(),
             "mkosi-install"  : install,
             "mkosi-upgrade"  : ["zypper", "update"],
             "mkosi-remove"   : ["zypper", "remove", "--clean-deps"],
@@ -105,7 +105,7 @@ class Zypper(PackageManager):
             "ZYPP_CONF=/etc/zypp/zypp.conf",
             "HOME=/",
             "zypper",
-            f"--installroot={context.root}",
+            "--installroot=/buildroot",
             "--cache-dir=/var/cache/zypp",
             "--gpg-auto-import-keys" if context.config.repository_key_check else "--no-gpg-checks",
             "--non-interactive",
@@ -131,9 +131,9 @@ class Zypper(PackageManager):
                 sandbox=(
                     context.sandbox(
                         network=True,
-                        mounts=[Mount(context.root, context.root), *cls.mounts(context), *sources],
+                        mounts=[Mount(context.root, "/buildroot"), *cls.mounts(context), *sources],
                         options=["--dir", "/work/src", "--chdir", "/work/src"],
-                    ) + (apivfs_cmd(context.root) if apivfs else [])
+                    ) + (apivfs_cmd() if apivfs else [])
                 ),
                 env=context.config.environment,
                 stdout=stdout,
index 4502dca06e90e6438c35b7e715e1504dab8203c3..9f041567315f4c774c1a048a879602e002b5a395 100644 (file)
@@ -105,13 +105,13 @@ class Manifest:
         c = run(
             [
                 "rpm",
-                f"--root={self.context.root}",
+                "--root=/buildroot",
                 "--query",
                 "--all",
                 "--queryformat", r"%{NEVRA}\t%{SOURCERPM}\t%{NAME}\t%{ARCH}\t%{LONGSIZE}\t%{INSTALLTIME}\n",
             ],
             stdout=subprocess.PIPE,
-            sandbox=self.context.sandbox(mounts=[Mount(self.context.root, self.context.root)]),
+            sandbox=self.context.sandbox(mounts=[Mount(self.context.root, "/buildroot")]),
         )
 
         packages = sorted(c.stdout.splitlines())
@@ -150,14 +150,14 @@ class Manifest:
                 c = run(
                     [
                         "rpm",
-                        f"--root={self.context.root}",
+                        "--root=/buildroot",
                         "--query",
                         "--changelog",
                         nevra,
                     ],
                     stdout=subprocess.PIPE,
                     stderr=subprocess.DEVNULL,
-                    sandbox=self.context.sandbox(mounts=[Mount(self.context.root, self.context.root, ro=True)]),
+                    sandbox=self.context.sandbox(mounts=[Mount(self.context.root, "/buildroot", ro=True)]),
                 )
                 changelog = c.stdout.strip()
                 source = SourcePackageManifest(srpm, changelog)
@@ -169,13 +169,13 @@ class Manifest:
         c = run(
             [
                 "dpkg-query",
-                f"--admindir={self.context.root / 'var/lib/dpkg'}",
+                "--admindir=/buildroot/var/lib/dpkg",
                 "--show",
                 "--showformat",
                     r'${Package}\t${source:Package}\t${Version}\t${Architecture}\t${Installed-Size}\t${db-fsys:Last-Modified}\n',
             ],
             stdout=subprocess.PIPE,
-            sandbox=self.context.sandbox(mounts=[Mount(self.context.root, self.context.root, ro=True)]),
+            sandbox=self.context.sandbox(mounts=[Mount(self.context.root, "/buildroot", ro=True)]),
         )
 
         packages = sorted(c.stdout.splitlines())
@@ -211,7 +211,7 @@ class Manifest:
                 result = Apt.invoke(
                     self.context,
                     "changelog",
-                    ["--quiet", "--quiet", "-o", f"Dir={self.context.root}", name],
+                    ["--quiet", "--quiet", "-o", "Dir=/buildroot", name],
                     stdout=subprocess.PIPE,
                 )
                 source_package = SourcePackageManifest(source, result.stdout.strip())
index fdad185d642d05f4ddd1ad3036321501eb2443ee..e1c34b0626c77dbc7112f6d3907fd311e04b32f3 100644 (file)
@@ -64,14 +64,14 @@ def have_effective_cap(capability: Capability) -> bool:
     return (int(hexcap, 16) & (1 << capability.value)) != 0
 
 
-def finalize_passwd_mounts(root: Path) -> list[Mount]:
+def finalize_passwd_mounts(root: PathString) -> list[Mount]:
     """
     If passwd or a related file exists in the apivfs directory, bind mount it over the host files while we
     run the command, to make sure that the command we run uses user/group information from the apivfs
     directory instead of from the host.
     """
     return [
-        Mount(root / "etc" / f, f"/etc/{f}", ro=True, required=False)
+        Mount(Path(root) / "etc" / f, f"/etc/{f}", ro=True, required=False)
         for f in ("passwd", "group", "shadow", "gshadow")
     ]
 
@@ -239,43 +239,52 @@ def sandbox_cmd(
     return cmdline
 
 
-def apivfs_cmd(root: Path) -> list[PathString]:
+def apivfs_cmd() -> list[PathString]:
     return [
         "bwrap",
         "--dev-bind", "/", "/",
-        "--tmpfs", root / "run",
-        "--tmpfs", root / "tmp",
-        "--bind", "/var/tmp", root / "var/tmp",
-        "--proc", root / "proc",
-        "--dev", root / "dev",
+        "--tmpfs", "/buildroot/run",
+        "--tmpfs", "/buildroot/tmp",
+        "--bind", "/var/tmp", "/buildroot/var/tmp",
+        "--proc", "/buildroot/proc",
+        "--dev", "/buildroot/dev",
         # Make sure /etc/machine-id is not overwritten by any package manager post install scripts.
-        "--ro-bind-try", root / "etc/machine-id", root / "etc/machine-id",
+        "--ro-bind-try", "/buildroot/etc/machine-id", "/buildroot/etc/machine-id",
         # Nudge gpg to create its sockets in /run by making sure /run/user/0 exists.
-        "--dir", root / "run/user/0",
-        *flatten(mount.options() for mount in finalize_passwd_mounts(root)),
+        "--dir", "/buildroot/run/user/0",
+        *flatten(mount.options() for mount in finalize_passwd_mounts("/buildroot")),
         "sh", "-c",
-        f"chmod 1777 {root / 'tmp'} {root / 'var/tmp'} {root / 'dev/shm'} && "
-        f"chmod 755 {root / 'run'} && "
-        # Make sure anything running in the root directory thinks it's in a container. $container can't always be
-        # accessed so we write /run/host/container-manager as well which is always accessible.
-        f"mkdir -m 755 {root}/run/host && echo mkosi >{root}/run/host/container-manager && "
-        "exec $0 \"$@\"",
+        " && ".join(
+            [
+                "chmod 1777 /buildroot/tmp /buildroot/var/tmp /buildroot/dev/shm",
+                "chmod 755 /buildroot/run",
+                # Make sure anything running in the root directory thinks it's in a container. $container can't always
+                # be accessed so we write /run/host/container-manager as well which is always accessible.
+                "mkdir -m 755 /buildroot/run/host",
+                "echo mkosi >/buildroot/run/host/container-manager",
+                "exec $0 \"$@\"",
+            ]
+        ),
     ]
 
 
-def chroot_cmd(root: Path, *, resolve: bool = False) -> list[PathString]:
-    return apivfs_cmd(root) + [
+def chroot_cmd(*, resolve: bool = False) -> list[PathString]:
+    return apivfs_cmd() + [
         "sh", "-c",
-        f"trap 'rm -rf {root / 'work'}' EXIT && "
-        # /etc/resolv.conf can be a dangling symlink to /run/systemd/resolve/stub-resolv.conf. Bubblewrap tries to call
-        # mkdir() on each component of the path which means it will try to call
-        # mkdir(/run/systemd/resolve/stub-resolv.conf) which will fail unless /run/systemd/resolve exists already so
-        # we make sure that it already exists.
-        f"mkdir -p -m 755 {root / 'work'} {root / 'run/systemd'} {root / 'run/systemd/resolve'} && "
-        # No exec here because we need to clean up the /work directory afterwards.
-        f"$0 \"$@\"",
+        " && ".join(
+            [
+                "trap 'rm -rf /buildroot/work' EXIT",
+                # /etc/resolv.conf can be a dangling symlink to /run/systemd/resolve/stub-resolv.conf. Bubblewrap tries
+                # to call mkdir() on each component of the path which means it will try to call
+                # mkdir(/run/systemd/resolve/stub-resolv.conf) which will fail unless /run/systemd/resolve exists
+                # already so we make sure that it already exists.
+                "mkdir -p -m 755 /buildroot/work /buildroot/run/systemd /buildroot/run/systemd/resolve",
+                # No exec here because we need to clean up the /work directory afterwards.
+                "$0 \"$@\"",
+            ]
+        ),
         "bwrap",
-        "--dev-bind", root, "/",
+        "--dev-bind", "/buildroot", "/",
         "--setenv", "container", "mkosi",
         "--setenv", "HOME", "/",
         "--setenv", "PATH", "/work/scripts:/usr/bin:/usr/sbin",