Files
2026-07-25 08:47:35 +08:00

89 lines
2.8 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""从本机 SSH 触发服务器一键更新(服务器内 git pull,不 scp 代码)。
环境变量(可选):
DEPLOY_HOST 默认 47.236.184.99
DEPLOY_USER 默认 root
DEPLOY_PASS 服务器密码
DEPLOY_ROOT 默认 /opt/eth_hedge_sim
REPO_URL 默认 https://git.bz121.com/dekun/eth_hedge_sim.git
DEPLOY_MODE update|bootstrap 默认 update(跑 pull_and_restart
bootstrap 时执行 manage 非交互更新路径
"""
from __future__ import annotations
import os
import sys
HOST = os.environ.get("DEPLOY_HOST", "47.236.184.99")
USER = os.environ.get("DEPLOY_USER", "root")
PASSWORD = os.environ.get("DEPLOY_PASS", "")
ROOT = os.environ.get("DEPLOY_ROOT", "/opt/eth_hedge_sim")
REPO = os.environ.get("REPO_URL", "https://git.bz121.com/dekun/eth_hedge_sim.git")
MODE = os.environ.get("DEPLOY_MODE", "update").strip().lower()
def main() -> int:
if not PASSWORD:
print("Set DEPLOY_PASS env var (do not commit password).", file=sys.stderr)
return 2
try:
import paramiko
except ImportError:
print("pip install paramiko", file=sys.stderr)
return 2
if MODE == "bootstrap":
remote = f"""
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive
if [[ ! -d '{ROOT}/.git' ]]; then
mkdir -p /opt
git clone '{REPO}' '{ROOT}'
fi
bash '{ROOT}/deploy/pull_and_restart.sh'
curl -fsS http://127.0.0.1:5155/health || true
"""
else:
remote = f"""
set -euo pipefail
if [[ ! -d '{ROOT}/.git' ]]; then
mkdir -p /opt
git clone '{REPO}' '{ROOT}'
fi
bash '{ROOT}/deploy/lib/update.sh'
curl -fsS http://127.0.0.1:5155/health || true
"""
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
print(f"connecting {USER}@{HOST} ...")
client.connect(HOST, username=USER, password=PASSWORD, timeout=30)
print("running remote pull/update ...")
stdin, stdout, stderr = client.exec_command(remote, get_pty=True)
while True:
chunk = stdout.read(1024)
if not chunk:
break
text = chunk.decode("utf-8", errors="replace") if isinstance(chunk, bytes) else chunk
try:
print(text, end="", flush=True)
except UnicodeEncodeError:
print(text.encode("ascii", errors="replace").decode("ascii"), end="", flush=True)
err_raw = stderr.read()
err = err_raw.decode("utf-8", errors="replace") if isinstance(err_raw, bytes) else err_raw
code = stdout.channel.recv_exit_status()
if err:
try:
print(err, file=sys.stderr)
except UnicodeEncodeError:
print(err.encode("ascii", errors="replace").decode("ascii"), file=sys.stderr)
client.close()
print(f"exit={code}")
return code
if __name__ == "__main__":
raise SystemExit(main())