import paramiko, sys, time sys.stdout.reconfigure(encoding='utf-8', errors='replace') c = paramiko.SSHClient(); c.set_missing_host_key_policy(paramiko.AutoAddPolicy()) c.connect('101.79.17.164', username='root', password='1q2w3e!Q', timeout=15) def run(label, cmd, timeout=20): _, o, _ = c.exec_command(cmd, timeout=timeout) print(f'\n[{label}]\n' + o.read().decode('utf-8','replace').strip()[:500]) run('guardia 서비스 파일', 'cat /etc/systemd/system/guardia.service | grep -E "ExecStart|port|WorkingDirectory"') run('포트 9001', 'ss -tlnp | grep 9001 || echo "9001 비어있음"') run('포트 kill + 재시작', 'fuser -k 9001/tcp 2>/dev/null; sleep 1; systemctl restart guardia && sleep 5 && systemctl is-active guardia') time.sleep(3) run('API 헬스체크', 'curl -sf http://localhost:9001/health 2>/dev/null || curl -sf http://localhost:9001/ 2>/dev/null | head -3') run('신규 엔드포인트', 'curl -sf http://localhost:9001/openapi.json 2>/dev/null | ' 'python3 -c "import sys,json; d=json.load(sys.stdin); ' 'new=[p for p in d[chr(112)+chr(97)+chr(116)+chr(104)+chr(115)] if any(k in p for k in [\'/api/rag\',\'/api/jira\',\'/api/kpi\',\'/api/portal\',\'/api/bi\',\'/api/workflow\'])]; ' 'print(chr(49)+chr(51)+chr(32)+chr(100)+chr(111)+ \" paths\"); [print(p) for p in sorted(new)]" 2>/dev/null') c.close()