107 lines
3.6 KiB
Python
107 lines
3.6 KiB
Python
"""push_to_oneapi.py — собирает WORKING ключи со всех 5 хантеров → iishko + grokgw.
|
||
Работает через SFTP + push_helper.py (уже развёрнут на обоих сторах).
|
||
Запуск: python push_to_oneapi.py
|
||
"""
|
||
import io, json, os, sys, paramiko, re, time, subprocess
|
||
|
||
SSH_KEY = os.path.expanduser("~/.ssh/id_ed25519")
|
||
|
||
HUNTERS = {
|
||
"nl": ("144.31.34.147", 22, "/opt/hunter/data/hunter.db"),
|
||
"nl2": ("144.31.34.149", 22, "/opt/hunter/data/hunter.db"),
|
||
"nl3": ("144.31.34.148", 22, "/opt/hunter/data/hunter.db"),
|
||
"huntnl":("144.31.34.150", 22, "/opt/hunter/data/hunter.db"),
|
||
"ru": ("5.231.118.37", 18022, "/root/keyhunter/data/keys.db"),
|
||
}
|
||
|
||
STORES = {
|
||
"iishko": ("13.143.162.135", 22),
|
||
"grokgw": ("2.27.98.196", 22),
|
||
}
|
||
|
||
RU_PASSWORD = "8hDcYaQgl6Li7XtY"
|
||
DS_RE = re.compile(r"^sk-[0-9a-f]{32}$")
|
||
FETCH_SCRIPT = '''import sqlite3, json;db=sqlite3.connect(DB_PATH);rows=db.execute("SELECT val FROM keys WHERE status='WORKING'").fetchall();print(json.dumps([r[0] for r in rows]))'''
|
||
|
||
|
||
def log(msg):
|
||
print(f"[{time.strftime('%H:%M:%S')}] {msg}", flush=True)
|
||
|
||
|
||
def fetch_from(host, port, db_path, label, password=None):
|
||
"""Upload fetch script, run it, download result, return keys."""
|
||
log(f" fetching {label} ({host})...")
|
||
try:
|
||
c = paramiko.SSHClient()
|
||
c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||
if password:
|
||
c.connect(host, port=port, username="root", password=password, timeout=10)
|
||
else:
|
||
c.connect(host, port=port, username="root", key_filename=SSH_KEY, timeout=10)
|
||
|
||
sftp = c.open_sftp()
|
||
script = FETCH_SCRIPT.replace("DB_PATH", f'"{db_path}"')
|
||
with sftp.open("/tmp/fetch_keys.py", "w") as f:
|
||
f.write(script)
|
||
|
||
_, out, err = c.exec_command("python3 /tmp/fetch_keys.py", timeout=15)
|
||
raw = out.read().decode().strip()
|
||
if not raw:
|
||
log(f" {label}: no output")
|
||
return []
|
||
|
||
all_keys = json.loads(raw)
|
||
ds_keys = [k for k in all_keys if DS_RE.match(k)]
|
||
log(f" {label}: {len(all_keys)} raw, {len(ds_keys)} dashscope")
|
||
c.close()
|
||
return ds_keys
|
||
except Exception as e:
|
||
log(f" {label}: ERROR — {e}")
|
||
return []
|
||
|
||
|
||
def push_to(host, port, label, keys):
|
||
"""Pipe keys JSON through push_helper on remote store."""
|
||
if not keys:
|
||
return 0
|
||
log(f" pushing to {label} — {len(keys)} keys...")
|
||
|
||
payload = json.dumps(keys)
|
||
|
||
try:
|
||
r = subprocess.run(
|
||
["ssh", "-i", SSH_KEY, "-o", "StrictHostKeyChecking=no",
|
||
"-o", "ConnectTimeout=8", "-p", str(port), f"root@{host}",
|
||
"python3 /opt/push_helper.py"],
|
||
input=payload, capture_output=True, text=True, timeout=30,
|
||
)
|
||
if r.returncode != 0:
|
||
log(f" {label}: FAIL — {r.stderr.strip()[:120]}")
|
||
return 0
|
||
added = int(r.stdout.strip())
|
||
log(f" {label}: +{added}")
|
||
return added
|
||
except Exception as e:
|
||
log(f" {label}: ERROR — {e}")
|
||
return 0
|
||
|
||
|
||
def main():
|
||
log("=== push_to_oneapi START ===")
|
||
|
||
all_keys = []
|
||
for label, (host, port, db_path) in HUNTERS.items():
|
||
pwd = RU_PASSWORD if label == "ru" else None
|
||
all_keys.extend(fetch_from(host, port, db_path, label, password=pwd))
|
||
|
||
unique = list(set(all_keys))
|
||
log(f" total: {len(all_keys)} raw, {len(unique)} unique dashscope")
|
||
|
||
for label, (host, port) in STORES.items():
|
||
push_to(host, port, label, unique)
|
||
|
||
log("=== DONE ===")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main() |