propagate signals to running commands
otherwise, we have long running processes when GitLab terminates jobs in a pipeline
This commit is contained in:
parent
425d148ea8
commit
445d5ec720
|
@ -6,9 +6,10 @@ import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import shlex
|
import shlex
|
||||||
import re
|
import re
|
||||||
|
import signal
|
||||||
import fractions
|
import fractions
|
||||||
from collections import abc
|
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 typing import Callable, Union, Iterable, Sequence, Dict, List, Tuple, Literal, Any, Collection
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
@ -174,21 +175,35 @@ def run(cmd: str,
|
||||||
Output of the executed command.
|
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}'")
|
print(f"running '{cmd}' in '{wd}'")
|
||||||
process = subprocess.run(shlex.split(cmd),
|
process = subprocess.Popen(shlex.split(cmd),
|
||||||
stdout = subprocess.PIPE,
|
stdout = subprocess.PIPE,
|
||||||
stderr = subprocess.PIPE,
|
stderr = subprocess.PIPE,
|
||||||
env = os.environ if env is None else env,
|
env = os.environ if env is None else env,
|
||||||
cwd = wd,
|
cwd = wd,
|
||||||
encoding = 'utf-8',
|
encoding = 'utf-8')
|
||||||
timeout = timeout)
|
# 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:
|
if process.returncode != 0:
|
||||||
print(process.stdout)
|
print(stdout)
|
||||||
print(process.stderr)
|
print(stderr)
|
||||||
raise RuntimeError(f"'{cmd}' failed with returncode {process.returncode}")
|
raise RuntimeError(f"'{cmd}' failed with returncode {process.returncode}")
|
||||||
|
|
||||||
return process.stdout, process.stderr
|
return stdout, stderr
|
||||||
|
|
||||||
|
|
||||||
execute = run
|
execute = run
|
||||||
|
|
Loading…
Reference in New Issue