propagate signals to running commands

otherwise, we have long running processes when GitLab terminates jobs in
a pipeline
This commit is contained in:
Martin Diehl 2022-03-06 21:09:46 +01:00
parent 425d148ea8
commit 445d5ec720
1 changed files with 22 additions and 7 deletions

View File

@ -6,9 +6,10 @@ import os
import subprocess
import shlex
import re
import signal
import fractions
from collections import abc
from functools import reduce
from functools import reduce, partial
from typing import Callable, Union, Iterable, Sequence, Dict, List, Tuple, Literal, Any, Collection
from pathlib import Path
@ -174,21 +175,35 @@ def run(cmd: str,
Output of the executed command.
"""
def pass_signal(sig,_,proc,default):
proc.send_signal(sig)
signal.signal(sig,default)
signal.raise_signal(sig)
signals = [signal.SIGINT,signal.SIGTERM]
print(f"running '{cmd}' in '{wd}'")
process = subprocess.run(shlex.split(cmd),
process = subprocess.Popen(shlex.split(cmd),
stdout = subprocess.PIPE,
stderr = subprocess.PIPE,
env = os.environ if env is None else env,
cwd = wd,
encoding = 'utf-8',
timeout = timeout)
encoding = 'utf-8')
# ensure that process is terminated (https://stackoverflow.com/questions/22916783)
sig_states = [signal.signal(sig,partial(pass_signal,proc=process,default=signal.getsignal(sig))) for sig in signals]
try:
stdout,stderr = process.communicate(timeout=timeout)
finally:
for sig,state in zip(signals,sig_states):
signal.signal(sig,state)
if process.returncode != 0:
print(process.stdout)
print(process.stderr)
print(stdout)
print(stderr)
raise RuntimeError(f"'{cmd}' failed with returncode {process.returncode}")
return process.stdout, process.stderr
return stdout, stderr
execute = run