Files
xiaoxia-saas/scripts/install_cmd_agent.py
T
CI Bot 72bfd4236e
Check New Server Env / check (push) Successful in 1s
Downgrade New Runners to v0.2.6 / downgrade (push) Successful in 18s
Install CMD Agent + Node.js on New Server / install (push) Failing after 10m31s
fix: use shell download instead of checkout action + install nodejs
2026-07-13 18:30:59 +08:00

151 lines
5.0 KiB
Python
Executable File

#!/usr/bin/env python3
"""在新服务器安装CMD Agent + Node.js + 基础CI环境"""
import subprocess
import os
import base64
NEW_SERVER = "172.30.18.199"
KEY_CONTENT = """-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACD6GquAk5vBEfbtaJCTSfnQEhjzC8e5GF60hSbPP0BJbAAAAJiQxGNokMRj
aAAAAAtzc2gtZWQyNTUxOQAAACD6GquAk5vBEfbtaJCTSfnQEhjzC8e5GF60hSbPP0BJbA
AAAED2muzuU4BAiCqbg0ayGxgiDvfS/xI1SFvb32oLzTnn8/oaq4CTm8ER9u1okJNJ+dAS
GPMLx7kYXrSFJs8/QElsAAAAFHJ1bm5lci1hZG1pbkB4aWFveGlhAQ==
-----END OPENSSH PRIVATE KEY-----
"""
key_path = "/tmp/new_server_ed25519"
with open(key_path, "w") as f:
f.write(KEY_CONTENT)
os.chmod(key_path, 0o600)
def ssh(cmd):
r = subprocess.run(
f'ssh -i {key_path} -o StrictHostKeyChecking=no -o ConnectTimeout=10 root@{NEW_SERVER} "{cmd}"',
shell=True, capture_output=True, text=True
)
return r.returncode, r.stdout.strip(), r.stderr.strip()
print("=" * 50)
print("步骤1: 环境检查")
print("=" * 50)
rc, out, err = ssh("cat /etc/os-release | head -3 && echo '---' && python3 --version && echo '---' && which docker && docker --version && echo '---' && which node 2>/dev/null && node --version 2>/dev/null || echo 'node: not installed'")
print(out[:500])
print("\n" + "=" * 50)
print("步骤2: 安装Node.js 20.x (CI checkout action需要)")
print("=" * 50)
rc, out, err = ssh("curl -fsSL https://deb.nodesource.com/setup_20.x | bash - 2>&1 | tail -3 && apt-get install -y nodejs 2>&1 | tail -3 && node --version && npm --version")
print(f"结果: RC={rc}")
print(out[:300])
if err and rc != 0:
print(f"ERR: {err[:300]}")
print("\n" + "=" * 50)
print("步骤3: 安装flask (CMD Agent依赖)")
print("=" * 50)
# 先试pip install,如果失败试试--break-system-packages
rc, out, err = ssh("pip3 install flask 2>&1 | tail -5")
if rc != 0:
print("pip3 install 失败,尝试 --break-system-packages...")
rc, out, err = ssh("pip3 install --break-system-packages flask 2>&1 | tail -5")
print(f"结果: RC={rc}")
print(out[:300])
# 验证
rc2, out2, err2 = ssh("python3 -c 'import flask; print(flask.__version__)' 2>&1")
print(f"flask验证: {out2[:100]}")
print("\n" + "=" * 50)
print("步骤4: 写入CMD Agent")
print("=" * 50)
agent_code = """#!/usr/bin/env python3
import subprocess
from flask import Flask, request, jsonify
app = Flask(__name__)
API_KEY = "xiaoxia-cmd-agent-2026"
@app.before_request
def verify_key():
key = request.headers.get("X-API-Key", "")
if key != API_KEY:
return jsonify({"error": "unauthorized"}), 401
@app.route("/cmd", methods=["POST"])
def run_cmd():
data = request.get_json()
cmd = data.get("cmd", "")
timeout = data.get("timeout", 60)
if not cmd:
return jsonify({"error": "no cmd"}), 400
try:
r = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=timeout)
return jsonify({
"returncode": r.returncode,
"stdout": r.stdout[:50000],
"stderr": r.stderr[:50000]
})
except subprocess.TimeoutExpired:
return jsonify({"error": "timeout"}), 504
@app.route("/health", methods=["GET"])
def health():
return jsonify({"status": "ok", "service": "cmd-agent"})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5927, debug=False)
"""
code_b64 = base64.b64encode(agent_code.encode()).decode()
rc, out, err = ssh(f'mkdir -p /opt/cmd-agent && echo "{code_b64}" | base64 -d > /opt/cmd-agent/server.py && chmod +x /opt/cmd-agent/server.py && ls -la /opt/cmd-agent/')
print(f"写入: {'成功' if rc==0 else '失败'}")
print(out[:200])
print("\n" + "=" * 50)
print("步骤5: 创建systemd服务")
print("=" * 50)
svc = """[Unit]
Description=CMD Agent
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/cmd-agent
ExecStart=/usr/bin/python3 /opt/cmd-agent/server.py
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
"""
svc_b64 = base64.b64encode(svc.encode()).decode()
rc, out, err = ssh(f'echo "{svc_b64}" | base64 -d > /etc/systemd/system/cmd-agent.service && systemctl daemon-reload && systemctl enable cmd-agent.service && systemctl start cmd-agent.service && sleep 2 && systemctl is-active cmd-agent.service')
print(f"服务状态: {out[:100] if rc==0 else '失败'}")
if err and rc != 0:
print(f"ERR: {err[:300]}")
print("\n" + "=" * 50)
print("步骤6: CMD Agent健康检查")
print("=" * 50)
rc, out, err = ssh("curl -s -H 'X-API-Key: xiaoxia-cmd-agent-2026' http://127.0.0.1:5927/health")
print(f"健康检查: {out[:200]}")
print("\n" + "=" * 50)
print("步骤7: Docker镜像检查")
print("=" * 50)
rc, out, err = ssh("docker images 2>&1 | head -15")
print(f"镜像:\n{out[:400]}")
print("\n" + "=" * 50)
print("步骤8: 最终环境核验")
print("=" * 50)
rc, out, err = ssh("echo 'Python:' && python3 --version && echo 'Node:' && node --version && echo 'Docker:' && docker --version && echo 'Git:' && git --version && echo 'Runner进程:' && ps aux | grep act_runner_v0.2.6 | grep -v grep | wc -l")
print(out)
print("\n" + "=" * 50)
print("全部完成!")
print("=" * 50)