From: Daan De Meyer Date: Sat, 13 Apr 2024 14:18:03 +0000 (+0200) Subject: Add ToolsTreeCertificates= option X-Git-Tag: v23~4^2~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9e746da891f642ebc133b65ef13b90c7cb605e1a;p=thirdparty%2Fmkosi.git Add ToolsTreeCertificates= option When building an image using internal repositories, often various internal certificates are required to be able to access these. These are of course not going to be available in any default tools tree, so let's add an option to use certificates and keys from the host with a tools tree. --- diff --git a/mkosi/__init__.py b/mkosi/__init__.py index 0c6cb4c38..b41e1f1ae 100644 --- a/mkosi/__init__.py +++ b/mkosi/__init__.py @@ -58,7 +58,7 @@ from mkosi.installer import clean_package_manager_metadata from mkosi.kmod import gen_required_kernel_modules, process_kernel_modules from mkosi.log import ARG_DEBUG, complete_step, die, log_notice, log_step from mkosi.manifest import Manifest -from mkosi.mounts import finalize_source_mounts, mount_overlay +from mkosi.mounts import finalize_crypto_mounts, finalize_source_mounts, mount_overlay from mkosi.pager import page from mkosi.partition import Partition, finalize_root, finalize_roothash from mkosi.qemu import KernelType, copy_ephemeral, run_qemu, run_ssh, start_journal_remote @@ -67,7 +67,7 @@ from mkosi.run import ( fork_and_wait, run, ) -from mkosi.sandbox import Mount, chroot_cmd, finalize_crypto_mounts, finalize_passwd_mounts +from mkosi.sandbox import Mount, chroot_cmd, finalize_passwd_mounts from mkosi.tree import copy_tree, move_tree, rmtree from mkosi.types import PathString from mkosi.user import CLONE_NEWNS, INVOKING_USER, become_root, unshare @@ -494,7 +494,7 @@ def run_sync_scripts(context: Context) -> None: for script in context.config.sync_scripts: mounts = [ *sources, - *finalize_crypto_mounts(context.config.tools()), + *finalize_crypto_mounts(context.config), Mount(script, "/work/sync", ro=True), Mount(json, "/work/config.json", ro=True), ] diff --git a/mkosi/config.py b/mkosi/config.py index e91bdd32d..9491dc750 100644 --- a/mkosi/config.py +++ b/mkosi/config.py @@ -1477,6 +1477,7 @@ class Config: tools_tree_repositories: list[str] tools_tree_package_manager_trees: list[ConfigTree] tools_tree_packages: list[str] + tools_tree_certificates: bool runtime_trees: list[ConfigTree] runtime_size: Optional[int] runtime_scratch: ConfigFeature @@ -2775,6 +2776,14 @@ SETTINGS = ( parse=config_make_list_parser(delimiter=","), help="Add additional packages to the default tools tree", ), + ConfigSetting( + dest="tools_tree_certificates", + metavar="BOOL", + section="Host", + parse=config_parse_boolean, + help="Use certificates from the tools tree", + default=True, + ), ConfigSetting( dest="runtime_trees", long="--runtime-tree", @@ -3982,6 +3991,7 @@ def summary(config: Config) -> str: Tools Tree Repositories: {line_join_list(config.tools_tree_repositories)} Tools Tree Package Manager Trees: {line_join_list(config.tools_tree_package_manager_trees)} Tools Tree Packages: {line_join_list(config.tools_tree_packages)} + Tools Tree Certificates: {yes_no(config.tools_tree_certificates)} Runtime Trees: {line_join_list(config.runtime_trees)} Runtime Size: {format_bytes_or_none(config.runtime_size)} Runtime Scratch: {config.runtime_scratch} diff --git a/mkosi/distributions/opensuse.py b/mkosi/distributions/opensuse.py index 6d0a6b66b..f652271b1 100644 --- a/mkosi/distributions/opensuse.py +++ b/mkosi/distributions/opensuse.py @@ -13,8 +13,9 @@ from mkosi.installer.dnf import Dnf from mkosi.installer.rpm import RpmRepository, find_rpm_gpgkey, setup_rpm from mkosi.installer.zypper import Zypper from mkosi.log import die +from mkosi.mounts import finalize_crypto_mounts from mkosi.run import find_binary, run -from mkosi.sandbox import Mount, finalize_crypto_mounts +from mkosi.sandbox import Mount from mkosi.util import listify, sort_packages @@ -172,7 +173,7 @@ def fetch_gpgurls(context: Context, repourl: str) -> tuple[str, ...]: ], sandbox=context.sandbox( network=True, - mounts=[Mount(d, d), *finalize_crypto_mounts(context.config.tools())], + mounts=[Mount(d, d), *finalize_crypto_mounts(context.config)], ), ) xml = (Path(d) / "repomd.xml").read_text() diff --git a/mkosi/installer/__init__.py b/mkosi/installer/__init__.py index 77ab30eb2..ca4043098 100644 --- a/mkosi/installer/__init__.py +++ b/mkosi/installer/__init__.py @@ -4,8 +4,9 @@ from pathlib import Path from mkosi.config import Config, ConfigFeature, OutputFormat from mkosi.context import Context +from mkosi.mounts import finalize_crypto_mounts from mkosi.run import find_binary -from mkosi.sandbox import Mount, finalize_crypto_mounts +from mkosi.sandbox import Mount from mkosi.tree import copy_tree, rmtree from mkosi.types import PathString from mkosi.util import startswith @@ -52,7 +53,7 @@ class PackageManager: @classmethod def mounts(cls, context: Context) -> list[Mount]: mounts = [ - *finalize_crypto_mounts(tools=context.config.tools()), + *finalize_crypto_mounts(context.config), Mount(context.packages, "/work/packages"), ] diff --git a/mkosi/installer/rpm.py b/mkosi/installer/rpm.py index c0e0fe78e..b7741c285 100644 --- a/mkosi/installer/rpm.py +++ b/mkosi/installer/rpm.py @@ -22,11 +22,13 @@ class RpmRepository(NamedTuple): def find_rpm_gpgkey(context: Context, key: str) -> Optional[str]: - if gpgpath := next((context.config.tools() / "usr/share/distribution-gpg-keys").rglob(key), None): - return ('/' / gpgpath.relative_to(context.config.tools())).as_uri() + root = context.config.tools() if context.config.tools_tree_certificates else Path("/") + + if gpgpath := next((root / "usr/share/distribution-gpg-keys").rglob(key), None): + return (Path("/") / gpgpath.relative_to(root)).as_uri() if gpgpath := next(Path(context.pkgmngr / "etc/pki/rpm-gpg").rglob(key), None): - return ('/' / gpgpath.relative_to(context.pkgmngr)).as_uri() + return (Path("/") / gpgpath.relative_to(context.pkgmngr)).as_uri() return None diff --git a/mkosi/mounts.py b/mkosi/mounts.py index 788120b94..8f75f1a5e 100644 --- a/mkosi/mounts.py +++ b/mkosi/mounts.py @@ -133,3 +133,27 @@ def finalize_source_mounts(config: Config, *, ephemeral: bool) -> Iterator[list[ ) yield [Mount(src, target) for src, target in sorted(sources, key=lambda s: s[1])] + + +def finalize_crypto_mounts(config: Config) -> list[Mount]: + root = config.tools() if config.tools_tree_certificates else Path("/") + + mounts = [ + (root / subdir, Path("/") / subdir) + for subdir in ( + Path("usr/share/keyrings"), + Path("usr/share/distribution-gpg-keys"), + Path("etc/pki"), + Path("etc/ssl"), + Path("etc/ca-certificates"), + Path("etc/pacman.d/gnupg"), + Path("var/lib/ca-certificates"), + ) + if (root / subdir).exists() + ] + + return [ + Mount(src, target, ro=True) + for src, target + in sorted(set(mounts), key=lambda s: s[1]) + ] diff --git a/mkosi/resources/mkosi.md b/mkosi/resources/mkosi.md index 21e72ec80..fad19033a 100644 --- a/mkosi/resources/mkosi.md +++ b/mkosi/resources/mkosi.md @@ -1783,6 +1783,14 @@ boolean argument: either `1`, `yes`, or `true` to enable, or `0`, `no`, separated list of package specifications. This option may be used multiple times in which case the specified package lists are combined. +`ToolsTreeCertificates=`, `--tools-tree-certificates=` + +: Specify whether to use certificates and keys from the tools tree. If + enabled, `/usr/share/keyrings`, `/usr/share/distribution-gpg-keys`, + `/etc/pki`, `/etc/ssl`, `/etc/ca-certificates`, `/etc/pacman.d/gnupg` + and `/var/lib/ca-certificates` from the tools tree are used. + Otherwise, these directories are picked up from the host. + `RuntimeTrees=`, `--runtime-tree=` : Takes a colon separated pair of paths. The first path refers to a diff --git a/mkosi/sandbox.py b/mkosi/sandbox.py index 68fdc8f00..6f06d436e 100644 --- a/mkosi/sandbox.py +++ b/mkosi/sandbox.py @@ -79,26 +79,6 @@ def finalize_passwd_mounts(root: PathString) -> list[Mount]: ] -def finalize_crypto_mounts(tools: Path = Path("/")) -> list[Mount]: - mounts = [ - (tools / subdir, Path("/") / subdir) - for subdir in ( - Path("etc/pki"), - Path("etc/ssl"), - Path("etc/ca-certificates"), - Path("etc/pacman.d/gnupg"), - Path("var/lib/ca-certificates"), - ) - if (tools / subdir).exists() - ] - - return [ - Mount(src, target, ro=True) - for src, target - in sorted(set(mounts), key=lambda s: s[1]) - ] - - def finalize_mounts(mounts: Sequence[Mount]) -> list[PathString]: mounts = list(set(mounts)) diff --git a/tests/test_json.py b/tests/test_json.py index 7cb5534dc..72adf3f7c 100644 --- a/tests/test_json.py +++ b/tests/test_json.py @@ -310,6 +310,7 @@ def test_config() -> None: ], "Timezone": null, "ToolsTree": null, + "ToolsTreeCertificates": true, "ToolsTreeDistribution": null, "ToolsTreeMirror": null, "ToolsTreePackageManagerTrees": [ @@ -468,6 +469,7 @@ def test_config() -> None: sync_scripts = [Path("/sync")], timezone = None, tools_tree = None, + tools_tree_certificates = True, tools_tree_distribution = None, tools_tree_mirror = None, tools_tree_package_manager_trees = [ConfigTree(Path("/a/b/c"), Path("/"))],