From: Daan De Meyer Date: Mon, 11 Dec 2023 09:17:19 +0000 (+0100) Subject: Add RepartOffline= option X-Git-Tag: v20~81 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cda6b579cfab7854664d225334d4e7ea07fe889f;p=thirdparty%2Fmkosi.git Add RepartOffline= option Instead of auto-detecting all cases where --offline=no has to be used with systemd-repart, let's allow configuring it via an option so that if we discover any new cases, users can easily disable offline mode themselves. --- diff --git a/NEWS.md b/NEWS.md index 80a290d1a..d9f487eee 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,10 @@ ## v20 +- We don't automatically set `--offline=no` anymore when we detect the + `Subvolumes=` setting is used in a `systemd-repart` partition + definition file. Instead, use the new `RepartOffline` option to + explicitly disable running `systemd-repart` in offline mode. - During the image build we now install UKIs/kernels/initrds to `/boot` instead of `/efi`. While this will generally not be noticeable, users with custom systemd-repart ESP partition definitions will need to add diff --git a/mkosi/__init__.py b/mkosi/__init__.py index 9200f2196..a5c02695e 100644 --- a/mkosi/__init__.py +++ b/mkosi/__init__.py @@ -43,6 +43,7 @@ from mkosi.config import ( format_tree, parse_config, summary, + yes_no, ) from mkosi.distributions import Distribution from mkosi.installer import clean_package_manager_metadata, package_manager_scripts @@ -2203,7 +2204,7 @@ def make_image( "--dry-run=no", "--json=pretty", "--no-pager", - "--offline=yes", + f"--offline={yes_no(state.config.repart_offline)}", "--seed", str(state.config.seed) if state.config.seed else "random", state.staging / state.config.output_with_format, ] @@ -2227,15 +2228,8 @@ def make_image( if state.config.sector_size: cmdline += ["--sector-size", str(state.config.sector_size)] - if definitions: - for d in definitions: - cmdline += ["--definitions", d] - - # Subvolumes= only works with --offline=no. - grep = run(["grep", "--recursive", "--include=*.conf", "Subvolumes=", *definitions], - stdout=subprocess.DEVNULL, check=False) - if grep.returncode == 0: - cmdline += ["--offline=no"] + for d in definitions: + cmdline += ["--definitions", d] env = { option: value @@ -3038,6 +3032,10 @@ def run_verb(args: MkosiArgs, images: Sequence[MkosiConfig]) -> None: die(f"mkosi {config.minimum_version} or newer is required to build this configuration (found {__version__})") + for config in images: + if not config.repart_offline and os.getuid() != 0: + die(f"Must be root to build {config.name()} image configured with RepartOffline=no") + for config in images: check_workspace_directory(config) diff --git a/mkosi/config.py b/mkosi/config.py index 015c3203a..77127d90f 100644 --- a/mkosi/config.py +++ b/mkosi/config.py @@ -910,6 +910,7 @@ class MkosiConfig: split_artifacts: bool repart_dirs: list[Path] sector_size: Optional[int] + repart_offline: bool overlay: bool use_subvolumes: ConfigFeature seed: Optional[uuid.UUID] @@ -1459,6 +1460,13 @@ SETTINGS = ( parse=config_parse_sector_size, help="Set the disk image sector size", ), + MkosiConfigSetting( + dest="repart_offline", + section="Output", + parse=config_parse_boolean, + help="Build disk images without using loopback devices", + default=True, + ), MkosiConfigSetting( dest="overlay", metavar="BOOL", @@ -3006,6 +3014,7 @@ def summary(config: MkosiConfig) -> str: Split Artifacts: {yes_no(config.split_artifacts)} Repart Directories: {line_join_list(config.repart_dirs)} Sector Size: {none_to_default(config.sector_size)} + Repart Offline: {yes_no(config.repart_offline)} Overlay: {yes_no(config.overlay)} Use Subvolumes: {yes_no_auto(config.use_subvolumes)} Seed: {none_to_random(config.seed)} diff --git a/mkosi/resources/mkosi.md b/mkosi/resources/mkosi.md index 19c489bf3..1b79b17f1 100644 --- a/mkosi/resources/mkosi.md +++ b/mkosi/resources/mkosi.md @@ -722,6 +722,26 @@ boolean argument: either `1`, `yes`, or `true` to enable, or `0`, `no`, : Override the default sector size that systemd-repart uses when building a disk image. +`Offline=`, `--offline=` + +: Specifies whether to build disk images using loopback devices. Enabled + by default. When enabled, `systemd-repart` will not use loopback + devices to build disk images. When disabled, `systemd-repart` will + always use loopback devices to build disk images. + +: Note that when using `Offline=no` mkosi cannot run unprivileged and + the image build has to be done as the root user outside of any + containers and with loopback devices available on the host system. + +: There are currently two known scenarios where `Offline=no` has to be + used. The first is when using `Subvolumes=` in a repart partition + definition file, as subvolumes cannot be created without using + loopback devices. The second is when creating a system with SELinux + and an XFS root partition. Because `mkfs.xfs` does not support + populating an XFS filesystem with extended attributes, loopback + devices have to be used to ensure the SELinux extended attributes end + up in the generated XFS filesystem. + `Overlay=`, `--overlay` : When used together with `BaseTrees=`, the output will consist only out of diff --git a/tests/test_json.py b/tests/test_json.py index 64736e188..730695e5a 100644 --- a/tests/test_json.py +++ b/tests/test_json.py @@ -223,6 +223,7 @@ def test_config() -> None: "all" ], "RepartDirectories": [], + "RepartOffline": true, "Repositories": [], "RepositoryKeyCheck": false, "RootPassword": [ @@ -362,6 +363,7 @@ def test_config() -> None: remove_files = [], remove_packages = ["all"], repart_dirs = [], + repart_offline = True, repositories = [], repository_key_check = False, root_password = ("test1234", False),