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())
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",
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,
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"],
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",
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,
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"),
*(
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",
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,
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),
],
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",
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,
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),
],
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:
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 []),
],
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 []),
],
),
[
"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),
],
):
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))
)
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:
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:
with complete_step("Generating volatile files"):
cmdline = [
"systemd-tmpfiles",
- f"--root={context.root}",
+ "--root=/buildroot",
"--boot",
"--create",
"--remove",
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)
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:
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)
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.
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)
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():
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)}",
]
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():
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")
]
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",