]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
Overlay /usr from package manager trees on top of /usr in bwrap()
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 22 Dec 2023 13:30:50 +0000 (14:30 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 22 Dec 2023 14:46:13 +0000 (15:46 +0100)
Let's allow package manager configuration to be put in /usr as well
by simply overlaying /usr from the package manager tree on top of
/usr.

mkosi/bubblewrap.py
mkosi/mounts.py
mkosi/resources/mkosi.md

index 18b6ed80f0c7e16594ff6c954790d8612eb3f0fc..937c60f7c06aab486fcc010dbe283094679bea41 100644 (file)
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: LGPL-2.1+
+import contextlib
 import enum
 import logging
 import os
@@ -9,7 +10,7 @@ from pathlib import Path
 from typing import Optional
 
 from mkosi.log import ARG_DEBUG_SHELL
-from mkosi.mounts import finalize_passwd_mounts
+from mkosi.mounts import finalize_passwd_mounts, mount_overlay
 from mkosi.run import find_binary, log_process_failure, run
 from mkosi.state import MkosiState
 from mkosi.types import _FILE, CompletedProcess, PathString
@@ -142,16 +143,21 @@ def bwrap(
         cmdline += [setpgid, "--foreground", "--"]
 
     try:
-        result = run(
-            [*cmdline, *cmd],
-            env=env,
-            log=False,
-            stdin=stdin,
-            stdout=stdout,
-            stderr=stderr,
-            input=input,
-            check=check,
-        )
+        with (
+            mount_overlay([Path("/usr"), state.pkgmngr / "usr"], where=Path("/usr"), lazy=True)
+            if (state.pkgmngr / "usr").exists()
+            else contextlib.nullcontext()
+        ):
+            return run(
+                [*cmdline, *cmd],
+                env=env,
+                log=False,
+                stdin=stdin,
+                stdout=stdout,
+                stderr=stderr,
+                input=input,
+                check=check,
+            )
     except subprocess.CalledProcessError as e:
         if log:
             log_process_failure([os.fspath(s) for s in cmd], e.returncode)
@@ -159,8 +165,6 @@ def bwrap(
             run([*cmdline, "sh"], stdin=sys.stdin, check=False, env=env, log=False)
         raise e
 
-    return result
-
 
 def apivfs_cmd(root: Path) -> list[PathString]:
     cmdline: list[PathString] = [
index 92e2785f402ebb4632d3327e50bf119052810a51..b3a0dc54b54a4b80beeeecd4fb6e39debdda9672 100644 (file)
@@ -75,6 +75,7 @@ def mount_overlay(
     lowerdirs: Sequence[Path],
     upperdir: Optional[Path] = None,
     where: Optional[Path] = None,
+    lazy: bool = False,
 ) -> Iterator[Path]:
     with contextlib.ExitStack() as stack:
         if upperdir is None:
@@ -114,7 +115,7 @@ def mount_overlay(
             options.append("userxattr")
 
         try:
-            with mount("overlay", where, options=options, type="overlay"):
+            with mount("overlay", where, options=options, type="overlay", lazy=lazy):
                 yield where
         finally:
             delete_whiteout_files(upperdir)
index 6664eac9ee946839937d1dc977369901a26773dc..ea55abf7560f8b5b72ae1e009b8471bb2bbe2189 100644 (file)
@@ -595,10 +595,10 @@ boolean argument: either `1`, `yes`, or `true` to enable, or `0`, `no`,
 
 : `mkosi` will look for the package manager configuration and related
   files in the configured package manager trees. Unless specified
-  otherwise, it will use the configuration file from its canonical
-  location in `/etc` in the package manager trees. For example, it will
-  look for `etc/dnf/dnf.conf` in the package manager trees if `dnf` is
-  used to install packages.
+  otherwise, it will use the configuration files from their canonical
+  locations in `/usr` or `/etc` in the package manager trees. For
+  example, it will look for `etc/dnf/dnf.conf` in the package manager
+  trees if `dnf` is used to install packages.
 
 : `SkeletonTrees=` and `PackageManagerTrees=` fulfill similar roles. Use
   `SkeletonTrees=` if you want the files to be present in the final image. Use