]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
Add RuntimeBuildSources= setting 2601/head
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Sun, 7 Apr 2024 17:23:02 +0000 (19:23 +0200)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Mon, 8 Apr 2024 09:33:47 +0000 (11:33 +0200)
This setting mounts the build sources and build directory into a
booted container/virtual machine in the same location that they were
mounted to do the build.

This helps both with making gdb more useful in the container as the
sources will be available for use by gdb without having to do any
source directory mapping. It also helps with doing incremental builds
inside the container.

mkosi/__init__.py
mkosi/config.py
mkosi/qemu.py
mkosi/resources/mkosi.md
mkosi/vmspawn.py
tests/test_json.py

index 0365b8f0451d773ec0d90438032251b4d2c3b00e..1044b08a087175c67cd48007e423510f5e73719c 100644 (file)
@@ -3851,6 +3851,15 @@ def run_shell(args: Args, config: Config) -> None:
         else:
             cmdline += ["--image", fname]
 
+        if config.runtime_build_sources:
+            with finalize_source_mounts(config, ephemeral=False) as mounts:
+                for mount in mounts:
+                    uidmap = "rootidmap" if Path(mount.src).stat().st_uid == INVOKING_USER.uid else "noidmap"
+                    cmdline += ["--bind", f"{mount.src}:{mount.dst}:norbind,{uidmap}"]
+
+            if config.build_dir:
+                cmdline += ["--bind", f"{config.build_dir}:/work/build:norbind,noidmap"]
+
         for tree in config.runtime_trees:
             target = Path("/root/src") / (tree.target or "")
             # We add norbind because very often RuntimeTrees= will be used to mount the source directory into the
index 4042c4a7e7e29454b7c38edc572de6ab95ca465b..4a8c92d1ab2c150dcdb9d586ddd55ebe5705449c 100644 (file)
@@ -1475,6 +1475,7 @@ class Config:
     runtime_size: Optional[int]
     runtime_scratch: ConfigFeature
     runtime_network: Network
+    runtime_build_sources: bool
     ssh_key: Optional[Path]
     ssh_certificate: Optional[Path]
     machine: Optional[str]
@@ -2794,6 +2795,13 @@ SETTINGS = (
         help="Set networking backend to use when booting the image",
         default=Network.user,
     ),
+    ConfigSetting(
+        dest="runtime_build_sources",
+        metavar="BOOL",
+        section="Host",
+        parse=config_parse_boolean,
+        help="Mount build sources and build directory in /work when booting the image",
+    ),
     ConfigSetting(
         dest="ssh_key",
         metavar="PATH",
@@ -3948,6 +3956,7 @@ def summary(config: Config) -> str:
                        Runtime Size: {format_bytes_or_none(config.runtime_size)}
                     Runtime Scratch: {config.runtime_scratch}
                     Runtime Network: {config.runtime_network}
+              Runtime Build Sources: {config.runtime_build_sources}
                     SSH Signing Key: {none_to_none(config.ssh_key)}
                     SSH Certificate: {none_to_none(config.ssh_certificate)}
                             Machine: {config.machine_or_name()}
index 75cb4df7602f25c0f934b57b295446cf5bfae0cf..07e4e46f337fcc741416315a2243dca954ce7286 100644 (file)
@@ -36,6 +36,7 @@ from mkosi.config import (
     want_selinux_relabel,
 )
 from mkosi.log import ARG_DEBUG, die
+from mkosi.mounts import finalize_source_mounts
 from mkosi.partition import finalize_root, find_partitions
 from mkosi.run import SD_LISTEN_FDS_START, AsyncioThread, find_binary, fork_and_wait, run, spawn
 from mkosi.sandbox import Mount
@@ -298,8 +299,8 @@ def find_virtiofsd(*, tools: Path = Path("/")) -> Optional[Path]:
 
 
 @contextlib.contextmanager
-def start_virtiofsd(config: Config, directory: Path, *, name: str, selinux: bool = False) -> Iterator[Path]:
-    uidmap = directory.stat().st_uid == INVOKING_USER.uid
+def start_virtiofsd(config: Config, directory: PathString, *, name: str, selinux: bool = False) -> Iterator[Path]:
+    uidmap = Path(directory).stat().st_uid == INVOKING_USER.uid
 
     virtiofsd = find_virtiofsd(tools=config.tools())
     if virtiofsd is None:
@@ -795,7 +796,7 @@ def run_qemu(args: Args, config: Config) -> None:
 
     # A shared memory backend might increase ram usage so only add one if actually necessary for virtiofsd.
     shm = []
-    if config.runtime_trees or config.output_format == OutputFormat.directory:
+    if config.runtime_trees or config.runtime_build_sources or config.output_format == OutputFormat.directory:
         shm = ["-object", f"memory-backend-memfd,id=mem,size={config.qemu_mem // 1024**2}M,share=on"]
 
     machine = f"type={config.architecture.default_qemu_machine()}"
@@ -953,15 +954,38 @@ def run_qemu(args: Args, config: Config) -> None:
                 ]
                 kcl += ["root=root", "rootfstype=virtiofs", "rw"]
 
-        for tree in config.runtime_trees:
-            sock = stack.enter_context(start_virtiofsd(config, tree.source, name=os.fspath(tree.source)))
-            tag = tree.target.name if tree.target else tree.source.name
+        def add_virtiofs_mount(
+            sock: Path,
+            dst: PathString,
+            cmdline: list[PathString],
+            kcl: list[str],
+            *, tag: str
+        ) -> None:
             cmdline += [
                 "-chardev", f"socket,id={sock.name},path={sock}",
                 "-device", f"vhost-user-fs-pci,queue-size=1024,chardev={sock.name},tag={tag}",
             ]
-            target = Path("/root/src") / (tree.target or "")
-            kcl += [f"systemd.mount-extra={tag}:{target}:virtiofs"]
+            kcl += [f"systemd.mount-extra={tag}:{dst}:virtiofs"]
+
+        if config.runtime_build_sources:
+            with finalize_source_mounts(config, ephemeral=False) as mounts:
+                for mount in mounts:
+                    sock = stack.enter_context(start_virtiofsd(config, mount.src, name=os.fspath(mount.src)))
+                    add_virtiofs_mount(sock, mount.dst, cmdline, kcl, tag=Path(mount.src).name)
+
+            if config.build_dir:
+                sock = stack.enter_context(start_virtiofsd(config, config.build_dir, name=os.fspath(config.build_dir)))
+                add_virtiofs_mount(sock, "/work/build", cmdline, kcl, tag="build")
+
+        for tree in config.runtime_trees:
+            sock = stack.enter_context(start_virtiofsd(config, tree.source, name=os.fspath(tree.source)))
+            add_virtiofs_mount(
+                sock,
+                Path("/root/src") / (tree.target or ""),
+                cmdline,
+                kcl,
+                tag=tree.target.name if tree.target else tree.source.name,
+            )
 
         if want_scratch(config) or config.output_format in (OutputFormat.disk, OutputFormat.esp):
             cmdline += ["-device", "virtio-scsi-pci,id=scsi"]
index 4b08c2474712e0d3097e3c12898eb3da68abf530..04953b64a420d483dcd933218c75f1dacbf5774f 100644 (file)
@@ -1821,6 +1821,13 @@ boolean argument: either `1`, `yes`, or `true` to enable, or `0`, `no`,
   `systemd-networkd` is running on the host which will automatically
   configure the host interface of the link.
 
+`RuntimeBuildSources=`, `--runtime-build-sources=`
+
+: Mount the build sources configured with `BuildSources=` and the build
+  directory (if one is configured) to the same locations in `/work` that
+  they were mounted to when running the build script when using `mkosi
+  boot` or `mkosi qemu`.
+
 `SshKey=`, `--ssh-key=`
 
 : Path to the X509 private key in PEM format to use to connect to a
index 44ea057d77e053e6100655567d9f803b44b2b204..c1b910f99cdf43aeb25651ce61cb08750a861ee3 100644 (file)
@@ -14,6 +14,7 @@ from mkosi.config import (
     yes_no,
 )
 from mkosi.log import die
+from mkosi.mounts import finalize_source_mounts
 from mkosi.qemu import (
     apply_runtime_size,
     copy_ephemeral,
@@ -77,6 +78,14 @@ def run_vmspawn(args: Args, config: Config) -> None:
 
         apply_runtime_size(config, fname)
 
+        if config.runtime_build_sources:
+            with finalize_source_mounts(config, ephemeral=False) as mounts:
+                for mount in mounts:
+                    cmdline += ["--bind", f"{mount.src}:{mount.dst}"]
+
+            if config.build_dir:
+                cmdline += ["--bind", f"{config.build_dir}:/work/build"]
+
         for tree in config.runtime_trees:
             target = Path("/root/src") / (tree.target or "")
             cmdline += ["--bind", f"{tree.source}:{target}"]
index e36c41aed512584b4e348a32d68b8f44401c97b0..a4c961c1afd3009a8197534c1c73b96fdff3c117 100644 (file)
@@ -259,6 +259,7 @@ def test_config() -> None:
                 false
             ],
             "RootShell": "/bin/tcsh",
+            "RuntimeBuildSources": true,
             "RuntimeNetwork": "interface",
             "RuntimeScratch": "enabled",
             "RuntimeSize": 8589934592,
@@ -439,6 +440,7 @@ def test_config() -> None:
         repository_key_check = False,
         root_password = ("test1234", False),
         root_shell = "/bin/tcsh",
+        runtime_build_sources = True,
         runtime_network = Network.interface,
         runtime_scratch = ConfigFeature.enabled,
         runtime_size = 8589934592,