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) sftp = c.open_sftp() 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()[:600]) # 실제 포트 확인 run('guardia 서비스 포트', 'cat /etc/systemd/system/guardia.service | grep -E "port|Port"') run('프로세스 포트', 'ss -tlnp | grep -E "uvicorn|python3" | head -5') # fuser 정리 후 재시작 run('포트 정리 + 재시작', 'fuser -k 9001/tcp 2>/dev/null || true; sleep 1; ' 'systemctl restart guardia && sleep 6 && systemctl is-active guardia') time.sleep(4) # 신규 엔드포인트 Python 스크립트로 확인 test = """ import urllib.request, json, sys for port in [9001, 8001, 8443]: try: req = urllib.request.Request(f"http://localhost:{port}/openapi.json") d = json.loads(urllib.request.urlopen(req, timeout=5).read()) paths = sorted(d["paths"].keys()) keywords = ["/api/rag", "/api/jira", "/api/kpi", "/api/portal", "/api/bi/", "/api/workflow"] new_paths = [p for p in paths if any(k in p for k in keywords)] print(f"포트 {port}: 총 {len(paths)}개 엔드포인트, 신규 {len(new_paths)}개") for p in new_paths: print(" ", p) break except Exception as e: print(f"포트 {port}: {e}") """ with sftp.open('/tmp/verify.py', 'w') as f: f.write(test) run('신규 API 검증', 'python3 /tmp/verify.py 2>&1; rm /tmp/verify.py') # DB 테이블 검증 db_test = """ import asyncio, sys sys.path.insert(0, '/opt/guardia/app') from database import engine from sqlalchemy import text async def check(): tables = ['tb_rag_feedback','tb_jira_config','tb_jira_sync_mapping', 'tb_kpi_definition','tb_kpi_value', 'tb_auto_workflow_rule','tb_auto_workflow_run'] async with engine.connect() as conn: for t in tables: try: r = await conn.execute(text(f"SELECT COUNT(*) FROM {t}")) print(f" {t}: OK") except Exception as e: print(f" {t}: {str(e)[:50]}") asyncio.run(check()) """ with sftp.open('/tmp/dbtest.py', 'w') as f: f.write(db_test) run('DB 테이블 검증', 'cd /opt/guardia/app && /opt/guardia/venv/bin/python3 /tmp/dbtest.py 2>&1; rm /tmp/dbtest.py') sftp.close(); c.close()