ssh.run: script via fichier temporaire + stdin=/dev/null (brew/sudo avalaient le script)
1 changed file +4 −1
modified
mld/ssh.py
+4 −1
@@ -20,8 +20,11 @@ def target(ip): | |||||
| 20 | def run(ip, cmd, timeout=120, stdin=None, path=True): | 20 | def run(ip, cmd, timeout=120, stdin=None, path=True): | ||
| 21 | """Exécute `cmd` (bash) sur le nœud. Retourne (rc, stdout, stderr).""" | 21 | """Exécute `cmd` (bash) sur le nœud. Retourne (rc, stdout, stderr).""" | ||
| 22 | full = (REMOTE_PATH if path else "") + cmd | 22 | full = (REMOTE_PATH if path else "") + cmd | ||
| 23 | + # le script est d'abord écrit dans un fichier temporaire puis exécuté avec stdin=/dev/null : | ||||
| 24 | + # avec `bash -s`, toute commande lisant stdin (brew, sudo, npm…) avalerait la suite du script. | ||||
| 25 | + wrapper = "f=$(mktemp /tmp/mld.XXXXXX) && cat > \"$f\" && bash \"$f\" </dev/null; rc=$?; rm -f \"$f\"; exit $rc" | ||||
| 23 | try: | 26 | try: | ||
| 24 | − p = subprocess.run(["ssh"] + SSH_OPTS + [target(ip), "bash -s"], input=full if stdin is None else stdin, | 27 | + p = subprocess.run(["ssh"] + SSH_OPTS + [target(ip), wrapper], input=full if stdin is None else stdin, | ||
| 25 | capture_output=True, text=True, timeout=timeout) | 28 | capture_output=True, text=True, timeout=timeout) | ||
| 26 | return p.returncode, p.stdout, p.stderr | 29 | return p.returncode, p.stdout, p.stderr | ||
| 27 | except subprocess.TimeoutExpired: | 30 | except subprocess.TimeoutExpired: | ||
| 28 | 31 | ||||