From: Daan De Meyer Date: Fri, 6 Sep 2024 15:19:06 +0000 (+0200) Subject: Add RuntimeHome= option X-Git-Tag: v25~309^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=00cec4cbcafa65ac62b2fa040ea2a03415b763ef;p=thirdparty%2Fmkosi.git Add RuntimeHome= option --- diff --git a/mkosi/__init__.py b/mkosi/__init__.py index 11c19ac9f..34edee726 100644 --- a/mkosi/__init__.py +++ b/mkosi/__init__.py @@ -115,6 +115,7 @@ from mkosi.tree import copy_tree, make_tree, move_tree, rmtree from mkosi.types import PathString from mkosi.user import INVOKING_USER from mkosi.util import ( + current_home_dir, flatten, flock, flock_or_die, @@ -3392,6 +3393,10 @@ def run_shell(args: Args, config: Config) -> None: uidmap = "rootidmap" if tree.source.stat().st_uid != 0 else "noidmap" cmdline += ["--bind", f"{tree.source}:{target}:norbind,{uidmap}"] + if config.runtime_home and (path := current_home_dir()): + uidmap = "rootidmap" if path.stat().st_uid != 0 else "noidmap" + cmdline += ["--bind", f"{path}:/root:norbind,{uidmap}"] + if config.runtime_scratch == ConfigFeature.enabled or ( config.runtime_scratch == ConfigFeature.auto and config.output_format == OutputFormat.disk diff --git a/mkosi/config.py b/mkosi/config.py index 3fa839ed0..c59703345 100644 --- a/mkosi/config.py +++ b/mkosi/config.py @@ -1563,6 +1563,7 @@ class Config: runtime_scratch: ConfigFeature runtime_network: Network runtime_build_sources: bool + runtime_home: bool unit_properties: list[str] ssh_key: Optional[Path] ssh_certificate: Optional[Path] @@ -3005,6 +3006,13 @@ SETTINGS = ( parse=config_parse_boolean, help="Mount build sources and build directory in /work when booting the image", ), + ConfigSetting( + dest="runtime_home", + metavar="BOOL", + section="Host", + parse=config_parse_boolean, + help="Mount current home directory to /root when booting the image", + ), ConfigSetting( dest="unit_properties", long="--unit-property", @@ -4307,6 +4315,7 @@ def summary(config: Config) -> str: Runtime Scratch: {config.runtime_scratch} Runtime Network: {config.runtime_network} Runtime Build Sources: {config.runtime_build_sources} + Runtime Home or Working Directory: {yes_no(config.runtime_home)} Unit Properties: {line_join_list(config.unit_properties)} SSH Signing Key: {none_to_none(config.ssh_key)} SSH Certificate: {none_to_none(config.ssh_certificate)} diff --git a/mkosi/qemu.py b/mkosi/qemu.py index a6d84d931..78ce4da42 100644 --- a/mkosi/qemu.py +++ b/mkosi/qemu.py @@ -45,7 +45,7 @@ from mkosi.run import SD_LISTEN_FDS_START, AsyncioThread, find_binary, fork_and_ from mkosi.tree import copy_tree, rmtree from mkosi.types import PathString from mkosi.user import INVOKING_USER, become_root_in_subuid_range, become_root_in_subuid_range_cmd -from mkosi.util import StrEnum, flock, flock_or_die, groupby, round_up, try_or +from mkosi.util import StrEnum, current_home_dir, flock, flock_or_die, groupby, round_up, try_or from mkosi.versioncomp import GenericVersion QEMU_KVM_DEVICE_VERSION = GenericVersion("9.0") @@ -900,7 +900,12 @@ 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.runtime_build_sources or config.output_format == OutputFormat.directory: + if ( + config.runtime_trees or + config.runtime_build_sources or + config.runtime_home 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()}" @@ -1109,6 +1114,16 @@ def run_qemu(args: Args, config: Config) -> None: tag=tree.target.name if tree.target else tree.source.name, ) + if config.runtime_home and (p := current_home_dir()): + sock = stack.enter_context(start_virtiofsd(config, p)) + add_virtiofs_mount( + sock, + Path("/root"), + cmdline, + credentials, + tag="user-home", + ) + if want_scratch(config) or config.output_format in (OutputFormat.disk, OutputFormat.esp): cmdline += ["-device", "virtio-scsi-pci,id=mkosi"] diff --git a/mkosi/resources/man/mkosi.md b/mkosi/resources/man/mkosi.md index 7e80cc589..c78db5268 100644 --- a/mkosi/resources/man/mkosi.md +++ b/mkosi/resources/man/mkosi.md @@ -1635,6 +1635,10 @@ boolean argument: either `1`, `yes`, or `true` to enable, or `0`, `no`, they were mounted to when running the build script when using `mkosi boot` or `mkosi qemu`. +`RuntimeHome=`, `--runtime-home=` +: Mount the current home directory from which mkosi is running to + `/root` when using `mkosi boot` or `mkosi qemu`. + `UnitProperties=`, `--unit-property=` : Configure systemd unit properties to add to the systemd scopes allocated when using `mkosi boot` or `mkosi qemu`. These are passed diff --git a/mkosi/run.py b/mkosi/run.py index fd660670f..73d15e211 100644 --- a/mkosi/run.py +++ b/mkosi/run.py @@ -26,7 +26,7 @@ import mkosi.sandbox from mkosi.log import ARG_DEBUG, ARG_DEBUG_SHELL, die from mkosi.sandbox import joinpath, umask from mkosi.types import _FILE, CompletedProcess, PathString, Popen -from mkosi.util import flatten, one_zero +from mkosi.util import current_home_dir, flatten, one_zero SD_LISTEN_FDS_START = 3 @@ -503,23 +503,14 @@ def sandbox_cmd( if Path(d).exists(): cmdline += ["--bind", d, d] + path = current_home_dir() + if not path and Path.cwd() not in (Path("/"), Path("/home")): + path = Path.cwd() + # Either add the home directory we're running from or the current working directory if we're not running from # inside a home directory. - if Path.cwd() == Path("/"): - d = "" - if Path.cwd().is_relative_to("/root"): - d = "/root" - elif Path.cwd() == Path("/home"): - d = "/home" - elif Path.cwd().is_relative_to("/home"): - # `Path.parents` only supports slices and negative indexing from Python 3.10 onwards. - # TODO: Remove list() when we depend on Python 3.10 or newer. - d = os.fspath(list(Path.cwd().parents)[-2]) - else: - d = os.fspath(Path.cwd()) - - if d and not any(Path(d).is_relative_to(dir) for dir in (*dirs, "/usr", "/nix", "/tmp")): - cmdline += ["--bind", d, d] + if path and not any(path.is_relative_to(dir) for dir in (*dirs, "/usr", "/nix", "/tmp")): + cmdline += ["--bind", path, path] else: cmdline += ["--dir", "/var/tmp", "--unshare-ipc"] @@ -531,9 +522,7 @@ def sandbox_cmd( if network and Path("/etc/resolv.conf").exists(): cmdline += ["--ro-bind", "/etc/resolv.conf", "/etc/resolv.conf"] - path = "/usr/bin:/usr/sbin" if tools != Path("/") else os.environ["PATH"] - - cmdline += ["--setenv", "PATH", f"/scripts:{path}"] + cmdline += ["--setenv", "PATH", f"/scripts:{'/usr/bin:/usr/sbin' if tools != Path('/') else os.environ['PATH']}"] if scripts: cmdline += ["--ro-bind", scripts, "/scripts"] diff --git a/mkosi/util.py b/mkosi/util.py index e55b54d3b..1afabdb0a 100644 --- a/mkosi/util.py +++ b/mkosi/util.py @@ -233,3 +233,18 @@ def groupby(seq: Sequence[T], key: Callable[[T], S]) -> list[tuple[S, list[T]]]: grouped[k].append(i) return [(key, group) for key, group in grouped.items()] + + +def current_home_dir() -> Optional[Path]: + if Path.cwd() in (Path("/"), Path("/home")): + return None + + if Path.cwd().is_relative_to("/root"): + return Path("/root") + + if Path.cwd().is_relative_to("/home"): + # `Path.parents` only supports slices and negative indexing from Python 3.10 onwards. + # TODO: Remove list() when we depend on Python 3.10 or newer. + return list(Path.cwd().parents)[-3] + + return None diff --git a/mkosi/vmspawn.py b/mkosi/vmspawn.py index 26de1f6aa..78bbaec4d 100644 --- a/mkosi/vmspawn.py +++ b/mkosi/vmspawn.py @@ -21,6 +21,7 @@ from mkosi.qemu import ( ) from mkosi.run import run from mkosi.types import PathString +from mkosi.util import current_home_dir def run_vmspawn(args: Args, config: Config) -> None: @@ -84,6 +85,9 @@ def run_vmspawn(args: Args, config: Config) -> None: target = Path("/root/src") / (tree.target or "") cmdline += ["--bind", f"{tree.source}:{target}"] + if config.runtime_home and (p := current_home_dir()): + cmdline += ["--bind", f"{p}:/root"] + if kernel: cmdline += ["--linux", kernel] diff --git a/tests/test_json.py b/tests/test_json.py index f4236608d..72c36a74a 100644 --- a/tests/test_json.py +++ b/tests/test_json.py @@ -268,6 +268,7 @@ def test_config() -> None: ], "RootShell": "/bin/tcsh", "RuntimeBuildSources": true, + "RuntimeHome": true, "RuntimeNetwork": "interface", "RuntimeScratch": "enabled", "RuntimeSize": 8589934592, @@ -473,6 +474,7 @@ def test_config() -> None: root_password=("test1234", False), root_shell="/bin/tcsh", runtime_build_sources=True, + runtime_home=True, runtime_network=Network.interface, runtime_scratch=ConfigFeature.enabled, runtime_size=8589934592,