]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
Use /work for host scripts as well 2253/head
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Mon, 8 Jan 2024 15:56:31 +0000 (16:56 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Mon, 8 Jan 2024 17:57:54 +0000 (18:57 +0100)
Now that everything runs sandboxed, /work is free to use for host
scripts as well. At the same time, let's stop unconditionally
mounting the current working directory when running build scripts.

To keep things working smoothly, we'll make mounting the current
working directory the default value for BuildSources= instead.

NEWS.md
mkosi/__init__.py
mkosi/config.py
mkosi/resources/mkosi.md

diff --git a/NEWS.md b/NEWS.md
index df02819f6c38b4c9c883bdcd3ce37e1c671d4944..56d0f43cbca22f08cc575be188f539d04d978d7c 100644 (file)
--- a/NEWS.md
+++ b/NEWS.md
@@ -2,6 +2,11 @@
 
 ## v20
 
+- The current working directory is not mounted unconditionally to
+  `/work/src` anymore. Instead, the default value for `BuildSources=`
+  now mounts the current working directory to `/work/src`. This means
+  that the current working directory is no longer implicitly included
+  when `BuildSources=` is explicitly configured.
 - Assigning the empty string to a setting that takes a list of values
   now overrides any configured default value as well.
 - The github action does not build and install systemd from source
index 7694dcbc7eb4db3bee6a53147ac5404e144b5727..1ca597e7a4dfbd8d08231c03f1df48e01aaa0716 100644 (file)
@@ -350,10 +350,14 @@ def finalize_source_mounts(config: Config) -> Iterator[list[PathString]]:
         mounts = [
             (stack.enter_context(mount_overlay([source])) if config.build_sources_ephemeral else source, target)
             for source, target
-            in [(Path.cwd(), Path.cwd())] + [t.with_prefix(Path.cwd()) for t in config.build_sources]
+            in (t.with_prefix(Path("/work/src")) for t in config.build_sources)
         ]
 
-        yield flatten(["--bind", src, target] for src, target in sorted(set(mounts), key=lambda s: s[1]))
+        options: list[PathString] = ["--dir", "/work/src"]
+        for src, target in sorted(set(mounts), key=lambda s: s[1]):
+            options += ["--bind", src, target]
+
+        yield options
 
 
 @contextlib.contextmanager
@@ -416,7 +420,7 @@ def run_prepare_scripts(context: Context, build: bool) -> None:
         MKOSI_UID=str(INVOKING_USER.uid),
         MKOSI_GID=str(INVOKING_USER.gid),
         SCRIPT="/work/prepare",
-        SRCDIR=str(Path.cwd()),
+        SRCDIR="/work/src",
         WITH_DOCS=one_zero(context.config.with_docs),
         WITH_NETWORK=one_zero(context.config.with_network),
         WITH_TESTS=one_zero(context.config.with_tests),
@@ -440,11 +444,10 @@ def run_prepare_scripts(context: Context, build: bool) -> None:
                 resolve=True,
                 tools=context.config.tools(),
                 options=[
-                    "--bind", script, "/work/prepare",
-                    "--bind", Path.cwd(), "/work/src",
-                    "--bind", cd, "/work/scripts",
+                    "--bind", "/work/prepare", "/work/prepare",
+                    "--bind", "/work/src", "/work/src",
+                    "--bind", "/work/scripts", "/work/scripts",
                     "--chdir", "/work/src",
-                    "--setenv", "SRCDIR", "/work/src",
                     "--setenv", "BUILDROOT", "/",
                 ],
             )
@@ -458,7 +461,7 @@ def run_prepare_scripts(context: Context, build: bool) -> None:
 
             with complete_step(step_msg.format(script)):
                 run(
-                    ["/work/prepare" if script.suffix == ".chroot" else script, arg],
+                    ["/work/prepare", arg],
                     env=env | context.config.environment,
                     stdin=sys.stdin,
                     sandbox=context.sandbox(
@@ -468,11 +471,11 @@ def run_prepare_scripts(context: Context, build: bool) -> None:
                             # then all the files we mount here might be located in the configured cache directory, so
                             # we have to mount the cache directory first to not override all the other mounts.
                             "--bind", context.cache_dir, context.cache_dir,
-                            "--ro-bind", script, script,
-                            "--ro-bind", cd, cd,
+                            "--ro-bind", script, "/work/prepare",
+                            "--ro-bind", cd, "/work/scripts",
                             "--bind", context.root, context.root,
                             *finalize_crypto_mounts(tools=context.config.tools()),
-                            "--chdir", Path.cwd(),
+                            "--chdir", "/work/src",
                         ],
                         scripts=hd,
                     ) + (chroot if script.suffix == ".chroot" else []),
@@ -486,16 +489,16 @@ def run_build_scripts(context: Context) -> None:
     env = dict(
         ARCHITECTURE=str(context.config.architecture),
         BUILDROOT=str(context.root),
+        DESTDIR="/work/dest",
         CHROOT_DESTDIR="/work/dest",
+        OUTPUTDIR="/work/out",
         CHROOT_OUTPUTDIR="/work/out",
-        CHROOT_SCRIPT="/work/build-script",
+        SRCDIR="/work/src",
         CHROOT_SRCDIR="/work/src",
-        DESTDIR=str(context.install_dir),
+        SCRIPT="/work/build-script",
+        CHROOT_SCRIPT="/work/build-script",
         MKOSI_UID=str(INVOKING_USER.uid),
         MKOSI_GID=str(INVOKING_USER.gid),
-        OUTPUTDIR=str(context.staging),
-        SCRIPT="/work/build-script",
-        SRCDIR=str(Path.cwd()),
         WITH_DOCS=one_zero(context.config.with_docs),
         WITH_NETWORK=one_zero(context.config.with_network),
         WITH_TESTS=one_zero(context.config.with_tests),
@@ -503,7 +506,7 @@ def run_build_scripts(context: Context) -> None:
 
     if context.config.build_dir is not None:
         env |= dict(
-            BUILDDIR=str(context.config.build_dir),
+            BUILDDIR="/work/build",
             CHROOT_BUILDDIR="/work/build",
         )
 
@@ -518,20 +521,17 @@ def run_build_scripts(context: Context) -> None:
                 resolve=context.config.with_network,
                 tools=context.config.tools(),
                 options=[
-                    "--bind", script, "/work/build-script",
-                    "--bind", context.install_dir, "/work/dest",
-                    "--bind", context.staging, "/work/out",
-                    "--bind", Path.cwd(), "/work/src",
-                    "--bind", cd, "/work/scripts",
+                    "--bind", "/work/build-script", "/work/build-script",
+                    "--bind", "/work/dest", "/work/dest",
+                    "--bind", "/work/out", "/work/out",
+                    "--bind", "/work/src", "/work/src",
+                    "--bind", "/work/scripts", "/work/scripts",
                     *(
-                        ["--bind", os.fspath(context.config.build_dir), "/work/build"]
+                        ["--bind", "/work/build", "/work/build"]
                         if context.config.build_dir
                         else []
                     ),
                     "--chdir", "/work/src",
-                    "--setenv", "SRCDIR", "/work/src",
-                    "--setenv", "DESTDIR", "/work/dest",
-                    "--setenv", "OUTPUTDIR", "/work/out",
                     "--setenv", "BUILDROOT", "/",
                     *(["--setenv", "BUILDDIR", "/work/build"] if context.config.build_dir else []),
                 ],
@@ -549,24 +549,24 @@ def run_build_scripts(context: Context) -> None:
                 complete_step(f"Running build script {script}…"),
             ):
                 run(
-                    ["/work/build-script" if script.suffix == ".chroot" else script, *cmdline],
+                    ["/work/build-script", *cmdline],
                     env=env | context.config.environment,
                     stdin=sys.stdin,
                     sandbox=context.sandbox(
                         network=context.config.with_network,
                         options=sources + [
-                            "--ro-bind", script, script,
-                            "--ro-bind", cd, cd,
+                            "--ro-bind", script, "/work/build-script",
+                            "--ro-bind", cd, "/work/scripts",
                             "--bind", context.root, context.root,
-                            "--bind", context.install_dir, context.install_dir,
-                            "--bind", context.staging, context.staging,
+                            "--bind", context.install_dir, "/work/dest",
+                            "--bind", context.staging, "/work/out",
                             *(
-                                ["--bind", os.fspath(context.config.build_dir), os.fspath(context.config.build_dir)]
+                                ["--bind", os.fspath(context.config.build_dir), "/work/build"]
                                 if context.config.build_dir
                                 else []
                             ),
                             *finalize_crypto_mounts(tools=context.config.tools()),
-                            "--chdir", Path.cwd(),
+                            "--chdir", "/work/src",
                         ],
                         scripts=hd,
                     ) + (chroot if script.suffix == ".chroot" else []),
@@ -580,14 +580,14 @@ def run_postinst_scripts(context: Context) -> None:
     env = dict(
         ARCHITECTURE=str(context.config.architecture),
         BUILDROOT=str(context.root),
+        OUTPUTDIR="/work/out",
         CHROOT_OUTPUTDIR="/work/out",
+        SCRIPT="/work/postinst",
         CHROOT_SCRIPT="/work/postinst",
+        SRCDIR="/work/src",
         CHROOT_SRCDIR="/work/src",
         MKOSI_UID=str(INVOKING_USER.uid),
         MKOSI_GID=str(INVOKING_USER.gid),
-        OUTPUTDIR=str(context.staging),
-        SCRIPT="/work/postinst",
-        SRCDIR=str(Path.cwd()),
     )
 
     with (
@@ -600,13 +600,11 @@ def run_postinst_scripts(context: Context) -> None:
                 resolve=context.config.with_network,
                 tools=context.config.tools(),
                 options=[
-                    "--bind", script, "/work/postinst",
-                    "--bind", context.staging, "/work/out",
-                    "--bind", Path.cwd(), "/work/src",
-                    "--bind", cd, "/work/scripts",
+                    "--bind", "/work/postinst", "/work/postinst",
+                    "--bind", "/work/out", "/work/out",
+                    "--bind", "/work/src", "/work/src",
+                    "--bind", "/work/scripts", "/work/scripts",
                     "--chdir", "/work/src",
-                    "--setenv", "SRCDIR", "/work/src",
-                    "--setenv", "OUTPUTDIR", "/work/out",
                     "--setenv", "BUILDROOT", "/",
                 ],
             )
@@ -621,18 +619,18 @@ def run_postinst_scripts(context: Context) -> None:
                 complete_step(f"Running postinstall script {script}…"),
             ):
                 run(
-                    ["/work/postinst" if script.suffix == ".chroot" else script, "final"],
+                    ["/work/postinst", "final"],
                     env=env | context.config.environment,
                     stdin=sys.stdin,
                     sandbox=context.sandbox(
                         network=context.config.with_network,
                         options=sources + [
-                            "--ro-bind", script, script,
-                            "--ro-bind", cd, cd,
+                            "--ro-bind", script, "/work/postinst",
+                            "--ro-bind", cd, "/work/scripts",
                             "--bind", context.root, context.root,
-                            "--bind", context.staging, context.staging,
+                            "--bind", context.staging, "/work/out",
                             *finalize_crypto_mounts(tools=context.config.tools()),
-                            "--chdir", Path.cwd(),
+                            "--chdir", "/work/src",
                         ],
                         scripts=hd,
                     ) + (chroot if script.suffix == ".chroot" else []),
@@ -646,14 +644,14 @@ def run_finalize_scripts(context: Context) -> None:
     env = dict(
         ARCHITECTURE=str(context.config.architecture),
         BUILDROOT=str(context.root),
+        OUTPUTDIR="/work/out",
         CHROOT_OUTPUTDIR="/work/out",
-        CHROOT_SCRIPT="/work/finalize",
+        SRCDIR="/work/src",
         CHROOT_SRCDIR="/work/src",
+        SCRIPT="/work/finalize",
+        CHROOT_SCRIPT="/work/finalize",
         MKOSI_UID=str(INVOKING_USER.uid),
         MKOSI_GID=str(INVOKING_USER.gid),
-        OUTPUTDIR=str(context.staging),
-        SCRIPT="/work/finalize",
-        SRCDIR=str(Path.cwd()),
     )
 
     with (
@@ -666,13 +664,11 @@ def run_finalize_scripts(context: Context) -> None:
                 resolve=context.config.with_network,
                 tools=context.config.tools(),
                 options=[
-                    "--bind", script, "/work/finalize",
-                    "--bind", context.staging, "/work/out",
-                    "--bind", Path.cwd(), "/work/src",
-                    "--bind", cd, "/work/scripts",
+                    "--bind", "/work/finalize", "/work/finalize",
+                    "--bind", "/work/out", "/work/out",
+                    "--bind", "/work/src", "/work/src",
+                    "--bind", "/work/scripts", "/work/scripts",
                     "--chdir", "/work/src",
-                    "--setenv", "SRCDIR", "/work/src",
-                    "--setenv", "OUTPUTDIR", "/work/out",
                     "--setenv", "BUILDROOT", "/",
                 ],
             )
@@ -687,18 +683,18 @@ def run_finalize_scripts(context: Context) -> None:
                 complete_step(f"Running finalize script {script}…"),
             ):
                 run(
-                    ["/work/finalize" if script.suffix == ".chroot" else script],
+                    ["/work/finalize"],
                     env=env | context.config.environment,
                     stdin=sys.stdin,
                     sandbox=context.sandbox(
                         network=context.config.with_network,
                         options=sources + [
-                            "--ro-bind", script, script,
-                            "--ro-bind", cd, cd,
+                            "--ro-bind", script, "/work/finalize",
+                            "--ro-bind", cd, "/work/scripts",
                             "--bind", context.root, context.root,
-                            "--bind", context.staging, context.staging,
+                            "--bind", context.staging, "/work/out",
                             *finalize_crypto_mounts(tools=context.config.tools()),
-                            "--chdir", Path.cwd(),
+                            "--chdir", "/work/src",
                         ],
                         scripts=hd,
                     ) + (chroot if script.suffix == ".chroot" else []),
index 442c96a664918e2a88c9cff397c01124e879da5b..0b57548e8eb6e8088baee8d19f19616b2aa1d561 100644 (file)
@@ -1866,6 +1866,7 @@ SETTINGS = (
         section="Content",
         parse=config_make_list_parser(delimiter=",", parse=make_tree_parser(absolute=False)),
         match=config_match_build_sources,
+        default_factory=lambda _: [ConfigTree(Path.cwd(), None)],
         help="Path for sources to build",
     ),
     ConfigSetting(
index 76bc2ee141eb01dbf14a52a516b89cdf963e4184..f2fc21a4cf5e8d97e3dc5cd376f44e46acb844b5 100644 (file)
@@ -977,13 +977,11 @@ boolean argument: either `1`, `yes`, or `true` to enable, or `0`, `no`,
 : Takes a comma separated list of colon separated path pairs. The first
   path of each pair refers to a directory to mount from the host. The
   second path of each pair refers to the directory where the source
-  directory should be mounted when running scripts. Every target path
-  is prefixed with the current working directory and all build sources
-  are sorted lexicographically by their target before mounting so that
-  top level paths are mounted first. When using the `mkosi-chroot`
-  script ( see the **Scripts** section), the current working directory
-  with all build sources mounted in it is mounted to `/work/src` inside
-  the image's root directory.
+  directory should be mounted when running scripts. Every target path is
+  prefixed with `/work/src` and all build sources are sorted
+  lexicographically by their target before mounting, so that top level
+  paths are mounted first. If not configured explicitly, the current
+  working directory is mounted to `/work/src`.
 
 `BuildSourcesEphemeral=`, `--build-sources-ephemeral=`