#!/usr/bin/env python3 """GUARDiA ITSM Gitea Push + CI/CD Webhook 설정""" import paramiko, time, sys, os, io, zipfile HOST='101.79.17.164'; USER='root'; PASS='1q2w3e!Q' LOCAL_ITSM='C:/GUARDiA/itsm' SEP=chr(92) client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(HOST, username=USER, password=PASS, timeout=15) sftp = client.open_sftp() def run(label, cmd, timeout=60): print(f'\n[{label}]') chan = client.get_transport().open_session() chan.set_combine_stderr(True) chan.exec_command(cmd) start = time.time() while not chan.exit_status_ready(): if chan.recv_ready(): sys.stdout.buffer.write(chan.recv(4096)); sys.stdout.flush() if time.time()-start > timeout: print('[TIMEOUT]'); break time.sleep(0.3) while chan.recv_ready(): sys.stdout.buffer.write(chan.recv(4096)) sys.stdout.flush() rc = chan.recv_exit_status() print(f'exit={rc}'); return rc # ITSM 소스 패키징 SKIP_DIRS = {'__pycache__', '.git', 'backups', '_workspace', '.claude', 'node_modules', 'uploads'} SKIP_EXTS = ('.pyc', '.db', '.db.bak', '.log') zip_buf = io.BytesIO(); count = 0 with zipfile.ZipFile(zip_buf, 'w', zipfile.ZIP_DEFLATED) as zf: for root, dirs, files in os.walk(LOCAL_ITSM): dirs[:] = [d for d in dirs if d not in SKIP_DIRS] rel = os.path.relpath(root, LOCAL_ITSM).replace(SEP, '/') for f in files: if f.endswith(SKIP_EXTS) or f.startswith('test_'): continue arc = f if rel == '.' else f'{rel}/{f}' zf.write(os.path.join(root, f), arc); count += 1 zip_buf.seek(0) with sftp.open('/tmp/guardia-src.zip', 'wb') as f: f.write(zip_buf.read()) print(f'{count}개 파일 업로드') # push 스크립트 생성 push_script = """#!/bin/bash rm -rf /tmp/grd-push mkdir /tmp/grd-push cd /tmp/grd-push unzip -q /tmp/guardia-src.zip git init -q git config user.email ci@zioinfo.co.kr git config user.name ZioCI git add -A git commit -q -m "feat: GUARDiA ITSM v2.0 initial commit" git remote add origin http://zio:Zio%40Admin2026%21@localhost:3000/zio/guardia-itsm.git git push -f origin HEAD:main 2>&1 echo "PUSH_DONE" """ with sftp.open('/tmp/push_guardia.sh', 'w') as f: f.write(push_script) # Webhook 설정 스크립트 webhook_script = """#!/usr/bin/env python3 import urllib.request, json, base64 GITEA = 'http://localhost:3000' cred = base64.b64encode(b'zio:Zio@Admin2026!').decode() headers = {'Content-Type':'application/json','Authorization':f'Basic {cred}'} # 기존 웹훅 삭제 for hook_id in [1,2,3,4]: req = urllib.request.Request(f'{GITEA}/api/v1/repos/zio/guardia-itsm/hooks/{hook_id}', method='DELETE', headers=headers) try: urllib.request.urlopen(req) except: pass # 새 웹훅 등록 data = json.dumps({ 'type': 'gitea', 'active': True, 'config': {'url': 'http://localhost:9999/', 'content_type': 'json', 'secret': 'zioinfo-deploy-2026'}, 'events': ['push'] }).encode() req = urllib.request.Request(f'{GITEA}/api/v1/repos/zio/guardia-itsm/hooks', data=data, method='POST', headers=headers) resp = urllib.request.urlopen(req) d = json.loads(resp.read()) print('Webhook ID:', d.get('id')) """ with sftp.open('/tmp/setup_webhook.py', 'w') as f: f.write(webhook_script) sftp.close() run('Gitea push', 'bash /tmp/push_guardia.sh', 60) run('Webhook 설정', 'python3 /tmp/setup_webhook.py') # Deploy 서버에 guardia 배포 핸들러 추가 deploy_handler_script = """ import os, sys os.chdir('/opt/guardia/app') # guardia deploy server 업데이트 deploy_server_path = '/opt/zioinfo/deploy_server.py' with open(deploy_server_path, 'r') as f: content = f.read() # guardia 배포 스텝 확인 if 'guardia' not in content: print('Deploy server에 guardia 스텝 추가 필요') else: print('Deploy server: guardia 이미 포함됨') """ sftp2 = client.open_sftp() with sftp2.open('/tmp/check_deploy.py', 'w') as f: f.write(deploy_handler_script) sftp2.close() run('Deploy 서버 확인', 'python3 /tmp/check_deploy.py') # 브랜치 확인 run('저장소 브랜치 확인', 'curl -s http://localhost:3000/api/v1/repos/zio/guardia-itsm ' '-u zio:Zio@Admin2026! | python3 -c "import json,sys; d=json.load(sys.stdin); ' 'print(chr(78)+chr(97)+chr(109)+chr(101)+chr(58), d.get(chr(102)+chr(117)+chr(108)+chr(108)+chr(95)+chr(110)+chr(97)+chr(109)+chr(101)), ' 'chr(66)+chr(114)+chr(97)+chr(110)+chr(99)+chr(104)+chr(58), d.get(chr(100)+chr(101)+chr(102)+chr(97)+chr(117)+chr(108)+chr(116)+chr(95)+chr(98)+chr(114)+chr(97)+chr(110)+chr(99)+chr(104)))"') client.close() print('\nGUARDiA CI/CD 구축 완료')