From 95d71df20472e45a89aa8db5361ac2477cadcd08 Mon Sep 17 00:00:00 2001 From: Mathieu Benoit Date: Thu, 13 Aug 2026 18:14:45 -0400 Subject: [PATCH] [FIX] systemd : lancer run.sh par bash, contre les echecs 203/EXEC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit erplibre.service mourait en 3 ms sur openSUSE s390x, « status=203/EXEC », sans jamais entrer dans le script. Ce code ne dit pas que run.sh a echoue : il dit que systemd n'a pas pu l'EXECUTER. Quatre causes le produisent — bit x absent, shebang qui ne resout pas, /home monte noexec, SELinux refusant l'execve (Leap 16 est passe a SELinux). Les distinguer demande un acces a la machine ; les traiter ensemble ne le demande pas. Passe a « /bin/bash run.sh », le fichier n'est plus qu'une donnee lue : noexec et SELinux ne portent que sur l'execve, et le bit x devient sans objet. Mesure : un script en 644 refuse en direct, execute par bash. Les trois generateurs ecrivaient la meme ligne, les trois sont corriges. Le venv n'y est pour rien — odoo_bin.sh l'active deja, et c'est celui d'Odoo, pas celui des outils. --- EN --- erplibre.service died in 3 ms on openSUSE s390x, "status=203/EXEC", never entering the script. That code does not say run.sh failed: it says systemd could not EXECUTE it. Four causes produce it — missing x bit, unresolvable shebang, /home mounted noexec, SELinux denying execve (Leap 16 switched to SELinux). Telling them apart needs access to the machine; handling them together does not. Run as "/bin/bash run.sh", the file is merely data being read: noexec and SELinux only cover execve, and the x bit becomes moot. Measured: a 644 script refused directly, executed fine through bash. All three generators wrote the same line; all three are fixed. The venv is not involved — odoo_bin.sh already activates it, and it is Odoo's, not the tooling one. Assisted-by: Claude Opus 5 (cherry picked from commit 6f8cee84b72fd016fa188d204f280b011594627c) --- script/systemd/install_daemon.py | 17 ++++++++++++++++- script/systemd/install_daemon.sh | 2 +- script/todo/todo.py | 2 +- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/script/systemd/install_daemon.py b/script/systemd/install_daemon.py index 9f0ef6a..0369940 100755 --- a/script/systemd/install_daemon.py +++ b/script/systemd/install_daemon.py @@ -9,6 +9,20 @@ import subprocess import sys from pathlib import Path +# « ExecStart=/bin/bash …/run.sh » et non le script seul. +# +# Lancé seul, systemd doit EXÉCUTER le fichier, et l'échoue en « 203/EXEC » +# dans quatre cas au moins : bit x absent, shebang qui ne résout pas, /home +# monté noexec, SELinux refusant l'execve. Vécu sur openSUSE s390x — le +# processus mourait en 3 ms, sans jamais entrer dans le script, ce qui rend le +# diagnostic très pénible : aucune sortie, et un code qui ressemble à une +# erreur d'application. +# +# Passé à bash, run.sh n'est plus qu'une DONNÉE lue : les quatre causes +# disparaissent ensemble, y compris noexec et SELinux, qui ne portent que sur +# l'execve. Rien n'est perdu au passage — le shebang du script désigne déjà +# bash. C'est aussi ce que font install_daemon.sh et le générateur de todo.py, +# les trois écrivant la même unité. UNIT_TEMPLATE = """[Unit] Description=ERPLibre for {user} Requires=postgresql.service @@ -23,7 +37,8 @@ Group={user} Restart=always RestartSec=5 PIDFile={home_erplibre}/.venv.erplibre/service.pid -ExecStart={home_erplibre}/run.sh{EXEC_PARAM} +# bash explicite : voir install_daemon.py (evite 203/EXEC). +ExecStart=/bin/bash {home_erplibre}/run.sh{EXEC_PARAM} WorkingDirectory={home_erplibre} StandardOutput=journal+console diff --git a/script/systemd/install_daemon.sh b/script/systemd/install_daemon.sh index cfc2bd2..922872e 100755 --- a/script/systemd/install_daemon.sh +++ b/script/systemd/install_daemon.sh @@ -31,7 +31,7 @@ Group=${EL_USER} Restart=always RestartSec=5 PIDFile=${EL_HOME_ERPLIBRE}/.venv.erplibre/service.pid -ExecStart=${EL_HOME_ERPLIBRE}/run.sh +ExecStart=/bin/bash ${EL_HOME_ERPLIBRE}/run.sh WorkingDirectory=${EL_HOME_ERPLIBRE} StandardOutput=journal+console diff --git a/script/todo/todo.py b/script/todo/todo.py index d8ea5c6..641dd66 100755 --- a/script/todo/todo.py +++ b/script/todo/todo.py @@ -5421,7 +5421,7 @@ class TODO: "Group=$SVC_GROUP\n" "Restart=always\n" "RestartSec=5\n" - "ExecStart=$SVC_DIR/run.sh\n" + "ExecStart=/bin/bash $SVC_DIR/run.sh\n" "WorkingDirectory=$SVC_DIR\n" "StandardOutput=journal+console\n" "$SELINUX_LINE\n"