"""5개 시스템 전체 배포 상태 검증""" import paramiko, sys, base64, json 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) G = base64.b64encode(b'zio:Zio@Admin2026!').decode() def run(cmd, timeout=15): _, o, _ = c.exec_command(cmd, timeout=timeout) return o.read().decode('utf-8','replace').strip() def gitea_commit(repo): out = run(f"curl -sf 'http://127.0.0.1:9003/api/v1/repos/zio/{repo}/commits?limit=1' " f"-H 'Authorization: Basic {G}' 2>/dev/null | " "python3 -c \"import sys,json; d=json.load(sys.stdin); " "print(d[0]['sha'][:8], d[0]['commit']['message'][:50])\" 2>/dev/null") return out or '(조회 실패)' print('=' * 60) print('GUARDiA 5개 시스템 배포 상태 검증') print('=' * 60) # ── 1. guardia-itsm ────────────────────────────────────────── print('\n━━ 1. GUARDiA ITSM (guardia-itsm) ━━') svc = run('systemctl is-active guardia 2>/dev/null') port = run('ss -tlnp | grep 9001 2>/dev/null | head -1') src_commit = run('git -C /opt/guardia/src log -1 --oneline 2>/dev/null') app_routers = run('ls /opt/guardia/app/routers/*.py 2>/dev/null | wc -l') app_vs_src = run('diff -rq /opt/guardia/src /opt/guardia/app ' '--exclude="*.pyc" --exclude="__pycache__" --exclude=".git" ' '--exclude="*.db" --exclude="uploads" 2>/dev/null | head -5 || echo "동일"') stash = run('git -C /opt/guardia/src stash list 2>/dev/null') uncommit = run('git -C /opt/guardia/src status --short 2>/dev/null | grep -v "static/assets" | head -5') gitea = gitea_commit('guardia-itsm') print(f' 서비스: {svc}') print(f' 포트 9001: {"✅ LISTEN" if "9001" in port else "❌ 없음"}') print(f' src 커밋: {src_commit}') print(f' app routers: {app_routers}개') print(f' Gitea: {gitea}') print(f' app vs src: {app_vs_src[:100]}') print(f' stash: {stash or "없음"}') print(f' uncommit: {uncommit or "없음"}') # ── 2. zioinfo-web ─────────────────────────────────────────── print('\n━━ 2. 지오정보기술 홈페이지 (zioinfo-web) ━━') svc = run('systemctl is-active zioinfo 2>/dev/null') port = run('ss -tlnp | grep 8082 2>/dev/null | head -1') src_commit = run('git -C /opt/zioinfo/src log -1 --oneline 2>/dev/null') jar_date = run('ls -la /opt/zioinfo/app/app.jar 2>/dev/null | awk \'{print $6,$7,$8}\'') www_date = run('ls -la /var/www/zioinfo/index.html 2>/dev/null | awk \'{print $6,$7,$8}\'') stash = run('git -C /opt/zioinfo/src stash list 2>/dev/null') uncommit = run('git -C /opt/zioinfo/src status --short 2>/dev/null | grep -v "static/assets" | head -5') gitea = gitea_commit('zioinfo-web') guardia_detail = run('ls /opt/zioinfo/src/frontend/src/pages/GuardiaDetail.jsx 2>/dev/null && ' 'wc -l < /opt/zioinfo/src/frontend/src/pages/GuardiaDetail.jsx 2>/dev/null') print(f' 서비스: {svc}') print(f' 포트 8082: {"✅ LISTEN" if "8082" in port else "❌ 없음"}') print(f' src 커밋: {src_commit}') print(f' jar 날짜: {jar_date}') print(f' /var/www 날짜: {www_date}') print(f' GuardiaDetail: {guardia_detail}줄') print(f' Gitea: {gitea}') print(f' stash: {stash or "없음"}') print(f' uncommit: {uncommit or "없음"}') # ── 3. guardia-manager ─────────────────────────────────────── print('\n━━ 3. GUARDiA Manager (guardia-manager) ━━') svc = run('systemctl is-active guardia-manager 2>/dev/null') port = run('ss -tlnp | grep 8090 2>/dev/null | head -1') www_date = run('ls -la /var/www/manager/index.html 2>/dev/null | awk \'{print $6,$7,$8}\' || echo "없음"') be_routers = run('ls /opt/manager/backend/routers/*.py 2>/dev/null | wc -l || echo 0') gitea = gitea_commit('guardia-manager') print(f' 서비스: {svc}') print(f' 포트 8090: {"✅ LISTEN" if "8090" in port else "❌ 없음"}') print(f' /var/www/manager: {www_date}') print(f' backend routers: {be_routers}개') print(f' Gitea: {gitea}') # ── 4. guardia-messenger ───────────────────────────────────── print('\n━━ 4. GUARDiA Messenger (guardia-messenger) ━━') gitea = gitea_commit('guardia-messenger') app_json = run("curl -sf 'http://127.0.0.1:9003/api/v1/repos/zio/guardia-messenger/contents/app.json' " f"-H 'Authorization: Basic {G}' 2>/dev/null | " "python3 -c \"import sys,json,base64; d=json.load(sys.stdin); " "c=base64.b64decode(d['content']).decode(); " "import json as j2; a=j2.loads(c); " "print('v'+a.get('expo',{}).get('version','?'))\" 2>/dev/null") eas_json = run("curl -sf 'http://127.0.0.1:9003/api/v1/repos/zio/guardia-messenger/contents/eas.json' " f"-H 'Authorization: Basic {G}' 2>/dev/null | " "python3 -c \"import sys,json,base64; d=json.load(sys.stdin); " "c=base64.b64decode(d['content']).decode(); print(c[:100])\" 2>/dev/null") print(f' Gitea: {gitea}') print(f' 앱 버전: {app_json or "(조회 실패)"}') print(f' eas.json: {eas_json[:80] if eas_json else "(없음)"}') print(f' 배포 방식: EAS Build (expo.dev) — 서버 배포 없음') # ── 5. guardia-docs ────────────────────────────────────────── print('\n━━ 5. GUARDiA Docs (guardia-docs) ━━') gitea = gitea_commit('guardia-docs') doc_count = run("curl -sf 'http://127.0.0.1:9003/api/v1/repos/zio/guardia-docs/git/trees/main?recursive=true' " f"-H 'Authorization: Basic {G}' 2>/dev/null | " "python3 -c \"import sys,json; d=json.load(sys.stdin); " "mds=[t for t in d.get('tree',[]) if t['path'].endswith('.md')]; " "print(len(mds), '개 md 문서')\" 2>/dev/null") print(f' Gitea: {gitea}') print(f' 문서: {doc_count or "(조회 실패)"}') # ── 종합 ───────────────────────────────────────────────────── print('\n' + '=' * 60) print('종합 요약') print('=' * 60) services = { 'guardia (ITSM)': run('systemctl is-active guardia 2>/dev/null'), 'zioinfo (홈페이지)': run('systemctl is-active zioinfo 2>/dev/null'), 'guardia-manager': run('systemctl is-active guardia-manager 2>/dev/null'), 'zioinfo-deploy': run('systemctl is-active zioinfo-deploy 2>/dev/null'), 'jenkins': run('systemctl is-active jenkins 2>/dev/null'), } for name, status in services.items(): icon = '✅' if status == 'active' else '❌' print(f' {icon} {name}: {status}') c.close()