#!/usr/bin/env python3 import subprocess, os, sys NEW_SERVER = os.environ.get("NEW_SERVER", "172.30.18.199") KEY_PATH = os.environ.get("SSH_KEY_PATH", "/root/.ssh/new_server_ed25519") def ssh(cmd, timeout=600): """SSH执行命令,流式输出""" print(f"[SSH] {cmd[:100]}...") proc = subprocess.Popen( f'ssh -i {KEY_PATH} -o StrictHostKeyChecking=no -o ConnectTimeout=10 root@{NEW_SERVER} "{cmd}"', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True ) output = [] for line in proc.stdout: print(line.rstrip()) output.append(line) proc.wait(timeout=timeout) if proc.returncode != 0: print(f"[ERROR] SSH command failed with code {proc.returncode}") sys.exit(proc.returncode) return "".join(output) def scp_upload(local_path, remote_path): print(f"[SCP] {local_path} -> {remote_path}") r = subprocess.run( f'scp -i {KEY_PATH} -o StrictHostKeyChecking=no {local_path} root@{NEW_SERVER}:{remote_path}', shell=True, capture_output=True, text=True ) if r.returncode != 0: print(f"[ERROR] SCP upload failed: {r.stderr}") sys.exit(1) print("[SCP] upload ok") print("=" * 60) print("STEP 1: 检查系统版本") print("=" * 60) ssh("cat /etc/os-release && echo '---' && uname -r") print("\n" + "=" * 60) print("STEP 2: 安装编译依赖") print("=" * 60) ssh("yum install -y gcc openssl-devel bzip2-devel libffi-devel zlib-devel wget make readline-devel sqlite-devel 2>&1 | tail -20") print("\n" + "=" * 60) print("STEP 3: 下载 Python 3.10.14 源码") print("=" * 60) ssh(""" cd /tmp && \ if [ ! -f Python-3.10.14.tgz ]; then wget -q https://www.python.org/ftp/python/3.10.14/Python-3.10.14.tgz fi && \ ls -lh Python-3.10.14.tgz """) print("\n" + "=" * 60) print("STEP 4: 编译安装 Python 3.10(约5-10分钟)") print("=" * 60) ssh(""" cd /tmp && \ tar xzf Python-3.10.14.tgz && \ cd Python-3.10.14 && \ ./configure --prefix=/usr/local/python310 --enable-optimizations --with-ensurepip=install 2>&1 | tail -5 && \ make -j$(nproc) 2>&1 | tail -10 && \ make install 2>&1 | tail -10 """, timeout=900) print("\n" + "=" * 60) print("STEP 5: 替换默认 python3 和 pip3") print("=" * 60) ssh(""" # 备份旧的python3 mv /usr/bin/python3 /usr/bin/python3.bak 2>/dev/null || true mv /usr/bin/pip3 /usr/bin/pip3.bak 2>/dev/null || true # 软链接到新的 ln -sf /usr/local/python310/bin/python3.10 /usr/bin/python3 ln -sf /usr/local/python310/bin/pip3.10 /usr/bin/pip3 ln -sf /usr/local/python310/bin/python3.10 /usr/local/bin/python3 ln -sf /usr/local/python310/bin/pip3.10 /usr/local/bin/pip3 # 验证 python3 --version && pip3 --version && which python3 """) print("\n" + "=" * 60) print("STEP 6: 修复CMD Agent端口(5000→5927)") print("=" * 60) ssh(""" # 修改server.py中的端口 sed -i 's/port=5000/port=5927/g; s/port = 5000/port = 5927/g; s/5000/5927/g' /opt/cmd-agent/server.py 2>/dev/null || true grep -n '5927\\|5000\\|port' /opt/cmd-agent/server.py | head -10 # 重启服务 systemctl restart cmd-agent sleep 2 systemctl status cmd-agent --no-pager | head -5 ss -tlnp | grep 5927 """) print("\n" + "=" * 60) print("STEP 7: 重启所有6个Runner服务,让它们用新Python") print("=" * 60) ssh(""" for i in 1 2 3 4 5 6; do systemctl restart act-runner-$i echo "act-runner-$i restarted" done sleep 3 systemctl list-units 'act-runner-*' --no-legend """) print("\n" + "=" * 60) print("STEP 8: 最终验证") print("=" * 60) ssh(""" echo "Python版本:" && python3 --version echo "Pip版本:" && pip3 --version echo "测试 --break-system-packages:" && pip3 install --help 2>&1 | grep break-system || echo "NOT FOUND" echo "Runner服务数:" && systemctl list-units 'act-runner-*' --no-legend | wc -l echo "CMD Agent:" && ss -tlnp | grep 5927 """) print("\n✅ 全部完成!")