65 lines
2.9 KiB
Python
65 lines
2.9 KiB
Python
"""在 worker 容器内写文件 + 跑"""
|
|
import os, paramiko, base64
|
|
c = paramiko.SSHClient()
|
|
c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
c.connect("207.57.129.228", port=19717, username="root",
|
|
password=os.environ["REMOTE_PASS"],
|
|
timeout=30, allow_agent=False, look_for_keys=False)
|
|
|
|
py = r"""import asyncio, sys
|
|
sys.path.insert(0, '/app')
|
|
from sqlalchemy import select
|
|
from app.database import AsyncSessionLocal
|
|
from app.models.article import Article
|
|
|
|
async def main():
|
|
async with AsyncSessionLocal() as session:
|
|
rows = (await session.execute(
|
|
select(Article)
|
|
.where(Article.translation_status == "ok", Article.title_zh.is_not(None))
|
|
.order_by(Article.id.asc())
|
|
.limit(160)
|
|
)).scalars()
|
|
candidates = list(rows)
|
|
print(f"candidates={len(candidates)}")
|
|
todo = []
|
|
for a in candidates:
|
|
statuses = [a.format_status or "pending",
|
|
a.classify_status or "pending",
|
|
a.image_ai_status or "pending",
|
|
a.commentary_status or "pending"]
|
|
if any(s in ("pending","failed","n/a") for s in statuses):
|
|
todo.append(a.id)
|
|
if len(todo) >= 8: break
|
|
print(f"todo={len(todo)} ids={todo[:5]}")
|
|
if candidates:
|
|
a = candidates[0]
|
|
print(f"first: id={a.id} tr={a.translation_status} fmt={a.format_status} cls={a.classify_status} img={a.image_ai_status} cmt={a.commentary_status}")
|
|
|
|
asyncio.run(main())
|
|
"""
|
|
|
|
b64 = base64.b64encode(py.encode("utf-8")).decode("ascii")
|
|
|
|
# 分两步:先在主机上写(避免 docker exec 不持久文件)
|
|
si, so, se = c.exec_command(f"bash -lc 'echo {b64} | base64 -d > /srv/news/diag.py && ls -la /srv/news/diag.py && cat /srv/news/diag.py | head -3'", timeout=15)
|
|
print("=== step 1: write file ===")
|
|
print(so.read().decode(errors="replace"))
|
|
|
|
# 再 docker exec(此时文件在 /srv/news 挂载进 worker 容器,会出现在 /app 或 / 目录)
|
|
si, so, se = c.exec_command("bash -lc 'cd /srv/news && docker compose exec -T worker sh -c \"ls /tmp/diag.py 2>/dev/null; ls /app/diag.py 2>/dev/null; ls /diag.py 2>/dev/null; find / -name diag.py 2>/dev/null | head -5\"'", timeout=30)
|
|
print("=== step 2: find diag.py in container ===")
|
|
print(so.read().decode(errors="replace"))
|
|
|
|
# 直接用 docker compose exec 把文件传进去
|
|
si, so, se = c.exec_command("bash -lc 'cd /srv/news && docker compose exec -T worker sh -c \"cat > /tmp/diag.py\" < diag.py && docker compose exec -T worker ls -la /tmp/diag.py'", timeout=30)
|
|
print("=== step 3: copy file into container ===")
|
|
print(so.read().decode(errors="replace"))
|
|
|
|
# 跑
|
|
si, so, se = c.exec_command("bash -lc 'cd /srv/news && docker compose exec -T worker python /tmp/diag.py 2>&1 | tail -20'", timeout=30)
|
|
print("=== step 4: run ===")
|
|
print(so.read().decode(errors="replace"))
|
|
|
|
c.close()
|