2024-11-04 01:05:25 +01:00
|
|
|
import os
|
|
|
|
import signal
|
|
|
|
import subprocess
|
|
|
|
import sys
|
|
|
|
import time
|
|
|
|
from collections import deque
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
|
|
import click
|
|
|
|
import sysrsync
|
|
|
|
|
|
|
|
|
|
|
|
def run_shell(cmd, window_height=0):
|
|
|
|
out = subprocess.Popen(
|
|
|
|
cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True
|
|
|
|
)
|
|
|
|
stdout = []
|
|
|
|
if window_height:
|
|
|
|
h = window_height
|
|
|
|
try:
|
|
|
|
buf = deque()
|
|
|
|
for line in out.stdout:
|
|
|
|
term_size = os.get_terminal_size()
|
2024-11-04 22:12:42 +01:00
|
|
|
prefixed = (" => " + line).replace("\t", " ").rstrip()[: term_size[0] - 1] + "\n"
|
2024-11-04 01:05:25 +01:00
|
|
|
stdout.append(line)
|
|
|
|
buf.append(prefixed)
|
|
|
|
|
|
|
|
if h != 0:
|
|
|
|
sys.stdout.write(prefixed)
|
|
|
|
sys.stdout.flush()
|
|
|
|
h -= 1
|
|
|
|
continue
|
|
|
|
|
|
|
|
buf.popleft()
|
|
|
|
sys.stdout.write(f"\x1b[{window_height}F\x1b[0J")
|
|
|
|
sys.stdout.write("".join(buf))
|
|
|
|
sys.stdout.flush()
|
|
|
|
finally:
|
|
|
|
if h < window_height:
|
|
|
|
sys.stdout.write(f"\x1b[{window_height-h}F\x1b[0J")
|
|
|
|
sys.stdout.flush()
|
|
|
|
|
|
|
|
out.wait()
|
|
|
|
|
|
|
|
return out.returncode, "".join(stdout) if stdout else out.stdout.read()
|
|
|
|
|
|
|
|
|
|
|
|
def is_keepalived_master():
|
|
|
|
keepalived_data = Path("/tmp/keepalived.data")
|
|
|
|
keepalived_data.unlink(missing_ok=True) # do not read old data
|
|
|
|
|
|
|
|
sig = int(os.getenv("KEEPALIVED_DATA_SIGNAL", signal.SIGUSR1))
|
|
|
|
os.kill(int(Path("/run/keepalived.pid").read_text()), sig)
|
|
|
|
|
|
|
|
# wait for keepalived
|
|
|
|
for _ in range(10):
|
|
|
|
time.sleep(0.05)
|
|
|
|
if keepalived_data.exists():
|
|
|
|
break
|
|
|
|
else:
|
|
|
|
raise Exception(f"keepalived did not produce data on signal {sig}")
|
|
|
|
|
|
|
|
# TODO: could we do better?
|
|
|
|
return "State = MASTER" in Path("/tmp/keepalived.data").read_text()
|