From 2902e5efbb48fbad765bf1801383528b9e021b94 Mon Sep 17 00:00:00 2001 From: Antonio Alvarez Feijoo Date: Fri, 20 Sep 2024 16:12:06 +0200 Subject: [PATCH 1/2] Add OutputMode= option --- mkosi/__init__.py | 3 +++ mkosi/config.py | 36 ++++++++++++++++++++++++++++++++++++ mkosi/resources/man/mkosi.md | 5 +++++ tests/test_json.py | 2 ++ 4 files changed, 46 insertions(+) diff --git a/mkosi/__init__.py b/mkosi/__init__.py index 8072cc308..29f34fa64 100644 --- a/mkosi/__init__.py +++ b/mkosi/__init__.py @@ -3032,6 +3032,9 @@ def finalize_staging(context: Context) -> None: (context.config.output_dir_or_cwd() / f.name).symlink_to(f.readlink()) continue + if f.is_file() and context.config.output_mode is not None: + os.chmod(f, context.config.output_mode) + move_tree( f, context.config.output_dir_or_cwd(), use_subvolumes=context.config.use_subvolumes, diff --git a/mkosi/config.py b/mkosi/config.py index 2eb0cee72..c17889d07 100644 --- a/mkosi/config.py +++ b/mkosi/config.py @@ -682,6 +682,24 @@ def config_parse_compress_level(value: Optional[str], old: Optional[int]) -> Opt return level +def config_parse_mode(value: Optional[str], old: Optional[int]) -> Optional[int]: + if not value: + return None + + try: + mode = int(value, base=8) + except ValueError: + die(f"Access mode {value!r} is not a valid integer in base 8") + + if mode < 0: + die(f"Access mode cannot be negative (got {value})") + + if mode > 0o1777: + die(f"Access mode cannot be greater than 1777 (got {value})") + + return mode + + def config_default_compression(namespace: argparse.Namespace) -> Compression: if namespace.output_format in (OutputFormat.tar, OutputFormat.cpio, OutputFormat.uki, OutputFormat.esp): if namespace.distribution == Distribution.ubuntu and namespace.release == "focal": @@ -1447,6 +1465,7 @@ class Config: compress_output: Compression compress_level: int output_dir: Optional[Path] + output_mode: Optional[int] image_id: Optional[str] image_version: Optional[str] split_artifacts: bool @@ -2074,6 +2093,14 @@ def parse_ini(path: Path, only_sections: Collection[str] = ()) -> Iterator[tuple help="Output directory", scope=SettingScope.universal, ), + ConfigSetting( + dest="output_mode", + metavar="MODE", + section="Output", + parse=config_parse_mode, + help="Set file system access mode for image", + scope=SettingScope.universal, + ), ConfigSetting( dest="image_version", match=config_match_version, @@ -4190,6 +4217,14 @@ def format_bytes_or_none(num_bytes: Optional[int]) -> str: return format_bytes(num_bytes) if num_bytes is not None else "none" +def format_octal(oct_value: int) -> str: + return f"{oct_value:>04o}" + + +def format_octal_or_default(oct_value: Optional[int]) -> str: + return format_octal(oct_value) if oct_value is not None else "default" + + def bold(s: Any) -> str: return f"{Style.bold}{s}{Style.reset}" @@ -4243,6 +4278,7 @@ def summary(config: Config) -> str: Compression: {config.compress_output} Compression Level: {config.compress_level} Output Directory: {config.output_dir_or_cwd()} + Output Mode: {format_octal_or_default(config.output_mode)} Image ID: {config.image_id} Image Version: {config.image_version} Split Artifacts: {yes_no(config.split_artifacts)} diff --git a/mkosi/resources/man/mkosi.md b/mkosi/resources/man/mkosi.md index aa1422377..231d9b60f 100644 --- a/mkosi/resources/man/mkosi.md +++ b/mkosi/resources/man/mkosi.md @@ -562,6 +562,10 @@ boolean argument: either `1`, `yes`, or `true` to enable, or `0`, `no`, not specified and the directory `mkosi.output/` exists in the local directory, it is automatically used for this purpose. +`OutputMode=`, `--output-mode=` +: File system access mode used when creating the output image file. Takes an + access mode in octal notation. If not set, uses the current system defaults. + `ImageVersion=`, `--image-version=` : Configure the image version. This accepts any string, but it is recommended to specify a series of dot separated components. The @@ -2541,6 +2545,7 @@ and cannot be configured in subimages: - `LocalMirror=` - `Mirror=` - `OutputDirectory=` +- `OutputMode=` - `PackageCacheDirectory=` - `PackageDirectories=` - `Profile=` diff --git a/tests/test_json.py b/tests/test_json.py index 896cc0482..6217d73ba 100644 --- a/tests/test_json.py +++ b/tests/test_json.py @@ -197,6 +197,7 @@ def test_config() -> None: "NSpawnSettings": null, "Output": "outfile", "OutputDirectory": "/your/output/here", + "OutputMode": 83, "Overlay": true, "PackageCacheDirectory": "/a/b/c", "PackageDirectories": [], @@ -430,6 +431,7 @@ def test_config() -> None: output="outfile", output_dir=Path("/your/output/here"), output_format=OutputFormat.uki, + output_mode=0o123, overlay=True, package_cache_dir=Path("/a/b/c"), package_directories=[], From 3fe62ba52099e38920dc07cf3d3a90d048dfa954 Mon Sep 17 00:00:00 2001 From: Antonio Alvarez Feijoo Date: Fri, 20 Sep 2024 16:12:24 +0200 Subject: [PATCH 2/2] mkosi-initrd: set output mode 600 by default Traditionally, initrds stored in /boot must have their access mode set to 600. Nowadays, this is useless for initrds stored on the vfat-formatted ESP, but it doesn't hurt to support the old use case. --- mkosi/initrd.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mkosi/initrd.py b/mkosi/initrd.py index fd368139e..3b6a9d95f 100644 --- a/mkosi/initrd.py +++ b/mkosi/initrd.py @@ -88,7 +88,7 @@ def main() -> None: "mkosi", "--force", "--directory", "", - "--format", str(args.format), + "--format", args.format, "--output", args.output, "--output-dir", args.output_dir, "--extra-tree", f"/usr/lib/modules/{args.kernel_version}:/usr/lib/modules/{args.kernel_version}", @@ -111,6 +111,8 @@ def main() -> None: "--package-cache-dir=/var", "--cache-only=metadata", ] + if args.format != OutputFormat.directory.value: + cmdline += ["--output-mode=600"] for d in ("/usr/lib/mkosi-initrd", "/usr/local/lib/mkosi-initrd", "/run/mkosi-initrd", "/etc/mkosi-initrd"): if Path(d).exists():