mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 15:42:02 +00:00
96 lines
2.6 KiB
Python
96 lines
2.6 KiB
Python
import logging
|
|
import os
|
|
import signal
|
|
import subprocess
|
|
import time
|
|
from contextlib import contextmanager
|
|
from pathlib import Path
|
|
from typing import Any, Dict, Iterator, List, Tuple, Union
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class WithIter(type):
|
|
def __iter__(cls):
|
|
return (v for k, v in cls.__dict__.items() if not k.startswith("_"))
|
|
|
|
|
|
@contextmanager
|
|
def cd(path: Union[Path, str]) -> Iterator[None]:
|
|
oldpwd = os.getcwd()
|
|
os.chdir(path)
|
|
try:
|
|
yield
|
|
finally:
|
|
os.chdir(oldpwd)
|
|
|
|
|
|
def is_hex(s):
|
|
try:
|
|
int(s, 16)
|
|
return True
|
|
except ValueError:
|
|
return False
|
|
|
|
|
|
def normalize_string(string: str) -> str:
|
|
lowercase_string = string.lower()
|
|
normalized_string = (
|
|
lowercase_string.replace(" ", "_")
|
|
.replace("-", "_")
|
|
.replace("/", "_")
|
|
.replace("(", "")
|
|
.replace(")", "")
|
|
.replace(",", "")
|
|
)
|
|
return normalized_string
|
|
|
|
|
|
class GHActions:
|
|
@staticmethod
|
|
def print_in_group(group_name: str, lines: Union[Any, List[Any]]) -> None:
|
|
lines = list(lines)
|
|
print(f"::group::{group_name}")
|
|
for line in lines:
|
|
print(line)
|
|
print("::endgroup::")
|
|
|
|
|
|
def kill_ci_runner(message: str) -> None:
|
|
"""The function to kill the current process with all parents when it's possible.
|
|
Works only when run with the set `CI` environment"""
|
|
if not os.getenv("CI", ""): # cycle import env_helper
|
|
logger.info("Running outside the CI, won't kill the runner")
|
|
return
|
|
print(f"::error::{message}")
|
|
|
|
def get_ppid_name(pid: int) -> Tuple[int, str]:
|
|
# Avoid using psutil, it's not in stdlib
|
|
stats = Path(f"/proc/{pid}/stat").read_text(encoding="utf-8").split()
|
|
return int(stats[3]), stats[1]
|
|
|
|
pid = os.getpid()
|
|
pids = {} # type: Dict[str, str]
|
|
while pid:
|
|
ppid, name = get_ppid_name(pid)
|
|
pids[str(pid)] = name
|
|
pid = ppid
|
|
logger.error(
|
|
"Sleeping 5 seconds and killing all possible processes from following:\n %s",
|
|
"\n ".join(f"{p}: {n}" for p, n in pids.items()),
|
|
)
|
|
time.sleep(5)
|
|
# The current process will be killed too
|
|
subprocess.run(f"kill -9 {' '.join(pids.keys())}", check=False, shell=True)
|
|
|
|
|
|
def set_job_timeout():
|
|
def timeout_handler(_signum, _frame):
|
|
print("Timeout expired")
|
|
raise TimeoutError("Job's KILL_TIMEOUT expired")
|
|
|
|
kill_timeout = int(os.getenv("KILL_TIMEOUT", "0"))
|
|
assert kill_timeout > 0, "kill timeout must be provided in KILL_TIMEOUT env"
|
|
signal.signal(signal.SIGALRM, timeout_handler)
|
|
signal.alarm(kill_timeout)
|