Skip to content

Commit 986ace8

Browse files
committed
Add MakeScriptsExecutable= setting to optionally try to make scripts executable before bailing out
If it fails, it was going to die() anyway. OBS sources defined inline (ie, not in a tarball) cannot have the mode preserved, so it's not possible to have mkosi.build or so as a bare script in an OBS project, one needs to tar it up and extract it again later, which means it cannot be edited by the inline editor, which is very convenient for small and trivial builds like an addon.
1 parent 814f200 commit 986ace8

File tree

5 files changed

+33
-8
lines changed

5 files changed

+33
-8
lines changed

mkosi/__init__.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -649,13 +649,21 @@ def finalize_config_json(config: Config) -> Iterator[Path]:
649649
yield Path(f.name)
650650

651651

652+
def check_script(config: Config, script: Path) -> None:
653+
if not os.access(script, os.X_OK):
654+
if config.make_scripts_executable:
655+
logging.warning(f"{script} is not executable, attempting to chmod it")
656+
os.chmod(script, os.stat(script).st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
657+
else:
658+
die(f"{script} is not executable")
659+
660+
652661
def run_configure_scripts(config: Config) -> Config:
653662
if not config.configure_scripts:
654663
return config
655664

656665
for script in config.configure_scripts:
657-
if not os.access(script, os.X_OK):
658-
die(f"{script} is not executable")
666+
check_script(config, script)
659667

660668
env = dict(
661669
DISTRIBUTION=str(config.distribution),
@@ -703,8 +711,7 @@ def run_sync_scripts(config: Config) -> None:
703711
return
704712

705713
for script in config.sync_scripts:
706-
if not os.access(script, os.X_OK):
707-
die(f"{script} is not executable")
714+
check_script(config, script)
708715

709716
env = dict(
710717
DISTRIBUTION=str(config.distribution),
@@ -2723,8 +2730,7 @@ def check_inputs(config: Config) -> None:
27232730
config.finalize_scripts,
27242731
config.postoutput_scripts,
27252732
):
2726-
if not os.access(script, os.X_OK):
2727-
die(f"{script} is not executable")
2733+
check_script(config, script)
27282734

27292735
if config.secure_boot and not config.secure_boot_key:
27302736
die(
@@ -4592,8 +4598,7 @@ def run_clean_scripts(config: Config) -> None:
45924598
return
45934599

45944600
for script in config.clean_scripts:
4595-
if not os.access(script, os.X_OK):
4596-
die(f"{script} is not executable")
4601+
check_script(config, script)
45974602

45984603
env = dict(
45994604
DISTRIBUTION=str(config.distribution),

mkosi/config.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2151,6 +2151,7 @@ class Config:
21512151
proxy_peer_certificate: Optional[Path]
21522152
proxy_client_certificate: Optional[Path]
21532153
proxy_client_key: Optional[Path]
2154+
make_scripts_executable: bool
21542155

21552156
nspawn_settings: Optional[Path]
21562157
ephemeral: bool
@@ -4015,6 +4016,14 @@ def parse_kernel_module_filter_regexp(p: str) -> str:
40154016
help="Set the proxy client key",
40164017
scope=SettingScope.multiversal,
40174018
),
4019+
ConfigSetting(
4020+
dest="make_scripts_executable",
4021+
metavar="BOOL",
4022+
section="Build",
4023+
parse=config_parse_boolean,
4024+
default=False,
4025+
help="Whether mkosi will try to make build/postinst/finalize scripts executable if they are not",
4026+
),
40184027
# Runtime section
40194028
ConfigSetting(
40204029
dest="nspawn_settings",
@@ -5788,6 +5797,8 @@ def summary(config: Config) -> str:
57885797
Proxy Client Certificate: {none_to_none(config.proxy_client_certificate)}
57895798
Proxy Client Key: {none_to_none(config.proxy_client_key)}
57905799
5800+
Automatically set +x on scripts: {yes_no(config.make_scripts_executable)}
5801+
57915802
{bold("HOST CONFIGURATION")}:
57925803
NSpawn Settings: {none_to_none(config.nspawn_settings)}
57935804
Ephemeral: {config.ephemeral}

mkosi/resources/man/mkosi.1.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1753,6 +1753,10 @@ boolean argument: either `1`, `yes`, or `true` to enable, or `0`, `no`,
17531753
Currently, setting a proxy client key is only supported when **dnf** or
17541754
**dnf5** is used to build the image.
17551755

1756+
`MakeScriptsExecutable=`, `--make-scripts-executable=`
1757+
: If one of the hook scripts (see `SCRIPTS` section) is not marked as executable, attempt to chmod it
1758+
instead of failing outright. Defaults to `no`.
1759+
17561760
### [Runtime] Section (previously known as the [Host] section)
17571761

17581762
`NSpawnSettings=`, `--settings=`

mkosi/resources/mkosi-obs/mkosi.conf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,6 @@ SecureBoot=no
88
SignExpectedPcr=no
99
Verity=defer
1010
Checksum=yes
11+
12+
[Build]
13+
MakeScriptsExecutable=yes

tests/test_json.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ def test_config() -> None:
254254
"Machine": "machine",
255255
"MachineId": "b58253b0-cc92-4a34-8782-bcd99b20d07f",
256256
"MakeInitrd": false,
257+
"MakeScriptsExecutable": false,
257258
"ManifestFormat": [
258259
"json",
259260
"changelog"
@@ -508,6 +509,7 @@ def test_config() -> None:
508509
locale="en_C.UTF-8",
509510
machine_id=uuid.UUID("b58253b0cc924a348782bcd99b20d07f"),
510511
machine="machine",
512+
make_scripts_executable=False,
511513
make_initrd=False,
512514
manifest_format=[ManifestFormat.json, ManifestFormat.changelog],
513515
maxmem=123,

0 commit comments

Comments
 (0)