Skip to content

Commit f2383b6

Browse files
authored
Merge pull request #3053 from aafeijoo-suse/output-permissions-feat
Add `OutputMode=` option
2 parents 85074ab + 3fe62ba commit f2383b6

File tree

5 files changed

+49
-1
lines changed

5 files changed

+49
-1
lines changed

mkosi/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3028,6 +3028,9 @@ def finalize_staging(context: Context) -> None:
30283028
(context.config.output_dir_or_cwd() / f.name).symlink_to(f.readlink())
30293029
continue
30303030

3031+
if f.is_file() and context.config.output_mode is not None:
3032+
os.chmod(f, context.config.output_mode)
3033+
30313034
move_tree(
30323035
f, context.config.output_dir_or_cwd(),
30333036
use_subvolumes=context.config.use_subvolumes,

mkosi/config.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,24 @@ def config_parse_compress_level(value: Optional[str], old: Optional[int]) -> Opt
682682
return level
683683

684684

685+
def config_parse_mode(value: Optional[str], old: Optional[int]) -> Optional[int]:
686+
if not value:
687+
return None
688+
689+
try:
690+
mode = int(value, base=8)
691+
except ValueError:
692+
die(f"Access mode {value!r} is not a valid integer in base 8")
693+
694+
if mode < 0:
695+
die(f"Access mode cannot be negative (got {value})")
696+
697+
if mode > 0o1777:
698+
die(f"Access mode cannot be greater than 1777 (got {value})")
699+
700+
return mode
701+
702+
685703
def config_default_compression(namespace: argparse.Namespace) -> Compression:
686704
if namespace.output_format in (OutputFormat.tar, OutputFormat.cpio, OutputFormat.uki, OutputFormat.esp):
687705
if namespace.distribution == Distribution.ubuntu and namespace.release == "focal":
@@ -1447,6 +1465,7 @@ class Config:
14471465
compress_output: Compression
14481466
compress_level: int
14491467
output_dir: Optional[Path]
1468+
output_mode: Optional[int]
14501469
image_id: Optional[str]
14511470
image_version: Optional[str]
14521471
split_artifacts: bool
@@ -2074,6 +2093,14 @@ def parse_ini(path: Path, only_sections: Collection[str] = ()) -> Iterator[tuple
20742093
help="Output directory",
20752094
scope=SettingScope.universal,
20762095
),
2096+
ConfigSetting(
2097+
dest="output_mode",
2098+
metavar="MODE",
2099+
section="Output",
2100+
parse=config_parse_mode,
2101+
help="Set file system access mode for image",
2102+
scope=SettingScope.universal,
2103+
),
20772104
ConfigSetting(
20782105
dest="image_version",
20792106
match=config_match_version,
@@ -4190,6 +4217,14 @@ def format_bytes_or_none(num_bytes: Optional[int]) -> str:
41904217
return format_bytes(num_bytes) if num_bytes is not None else "none"
41914218

41924219

4220+
def format_octal(oct_value: int) -> str:
4221+
return f"{oct_value:>04o}"
4222+
4223+
4224+
def format_octal_or_default(oct_value: Optional[int]) -> str:
4225+
return format_octal(oct_value) if oct_value is not None else "default"
4226+
4227+
41934228
def bold(s: Any) -> str:
41944229
return f"{Style.bold}{s}{Style.reset}"
41954230

@@ -4243,6 +4278,7 @@ def summary(config: Config) -> str:
42434278
Compression: {config.compress_output}
42444279
Compression Level: {config.compress_level}
42454280
Output Directory: {config.output_dir_or_cwd()}
4281+
Output Mode: {format_octal_or_default(config.output_mode)}
42464282
Image ID: {config.image_id}
42474283
Image Version: {config.image_version}
42484284
Split Artifacts: {yes_no(config.split_artifacts)}

mkosi/initrd.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ def main() -> None:
8888
"mkosi",
8989
"--force",
9090
"--directory", "",
91-
"--format", str(args.format),
91+
"--format", args.format,
9292
"--output", args.output,
9393
"--output-dir", args.output_dir,
9494
"--extra-tree", f"/usr/lib/modules/{args.kernel_version}:/usr/lib/modules/{args.kernel_version}",
@@ -111,6 +111,8 @@ def main() -> None:
111111
"--package-cache-dir=/var",
112112
"--cache-only=metadata",
113113
]
114+
if args.format != OutputFormat.directory.value:
115+
cmdline += ["--output-mode=600"]
114116

115117
for d in ("/usr/lib/mkosi-initrd", "/usr/local/lib/mkosi-initrd", "/run/mkosi-initrd", "/etc/mkosi-initrd"):
116118
if Path(d).exists():

mkosi/resources/man/mkosi.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,10 @@ boolean argument: either `1`, `yes`, or `true` to enable, or `0`, `no`,
562562
not specified and the directory `mkosi.output/` exists in the local
563563
directory, it is automatically used for this purpose.
564564

565+
`OutputMode=`, `--output-mode=`
566+
: File system access mode used when creating the output image file. Takes an
567+
access mode in octal notation. If not set, uses the current system defaults.
568+
565569
`ImageVersion=`, `--image-version=`
566570
: Configure the image version. This accepts any string, but it is
567571
recommended to specify a series of dot separated components. The
@@ -2541,6 +2545,7 @@ and cannot be configured in subimages:
25412545
- `LocalMirror=`
25422546
- `Mirror=`
25432547
- `OutputDirectory=`
2548+
- `OutputMode=`
25442549
- `PackageCacheDirectory=`
25452550
- `PackageDirectories=`
25462551
- `Profile=`

tests/test_json.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ def test_config() -> None:
197197
"NSpawnSettings": null,
198198
"Output": "outfile",
199199
"OutputDirectory": "/your/output/here",
200+
"OutputMode": 83,
200201
"Overlay": true,
201202
"PackageCacheDirectory": "/a/b/c",
202203
"PackageDirectories": [],
@@ -430,6 +431,7 @@ def test_config() -> None:
430431
output="outfile",
431432
output_dir=Path("/your/output/here"),
432433
output_format=OutputFormat.uki,
434+
output_mode=0o123,
433435
overlay=True,
434436
package_cache_dir=Path("/a/b/c"),
435437
package_directories=[],

0 commit comments

Comments
 (0)