From 428bd7f6c15525942358f5ff6b54d07b3828025f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= <berykubik@gmail.com>
Date: Fri, 26 Aug 2022 11:12:21 +0200
Subject: [PATCH] Use `os.killpg` to kill processes instead of the kill command

Unless the shell builtin is used, the default kill command can't kill groups.
---
 cluster/cluster.py | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/cluster/cluster.py b/cluster/cluster.py
index 22205b8..484e259 100644
--- a/cluster/cluster.py
+++ b/cluster/cluster.py
@@ -252,17 +252,26 @@ def kill_process(hostname: str, pid: int, signal="TERM"):
     """
     Kill a process with the given `pid` on the specified `hostname`
     :param hostname: Hostname where the process is located.
-    :param pid: PID of the process to kill.
+    :param pid: PGID of the process to kill.
     :param signal: Signal used to kill the process. One of "TERM", "KILL" or "INT".
     """
+    import signal as pysignal
+
     assert signal in ("TERM", "KILL", "INT")
     logging.debug(f"Killing PGID {pid} on {hostname}")
-    args = ["kill", f"-{signal}", "--", f"-{pid}"]
     if not is_local(hostname):
-        args = ["ssh", hostname, "--"] + args
-    res = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-    if res.returncode != 0:
-        logging.error(
-            f"error: {res.returncode} {res.stdout.decode().strip()} {res.stderr.decode().strip()}")
-        return False
+        args = ["ssh", hostname, "--", "kill", f"-{signal}", f"-{pid}"]
+        res = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
+        if res.returncode != 0:
+            logging.error(
+                f"error: {res.returncode} {res.stdout.decode().strip()} {res.stderr.decode().strip()}")
+            return False
+    else:
+        if signal == "TERM":
+            signal = pysignal.SIGTERM
+        elif signal == "KILL":
+            signal = pysignal.SIGKILL
+        elif signal == "INT":
+            signal = pysignal.SIGINT
+        os.killpg(pid, signal)
     return True
-- 
GitLab