"""Gitea→Jenkins webhook URL 수정 + 최종 E2E 검증""" import paramiko, sys, json, 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() J = 'http://127.0.0.1:9080' A = 'admin:Admin@2026!' def run(label, cmd, timeout=30): print(f'\n[{label}]') _, o, _ = c.exec_command(cmd, timeout=timeout) out = o.read().decode('utf-8','replace').strip() if out: print(out[:600]) return out # 1. 현재 Jenkins webhook hook 상세 확인 run('hook 17 상세', """ curl -sf 'http://127.0.0.1:9003/api/v1/repos/zio/guardia-itsm/hooks/17' \ --header 'Authorization: Basic '"$(echo -n 'zio:Zio@Admin2026!' | base64)" \ 2>/dev/null | python3 -c " import sys,json h=json.load(sys.stdin) print('URL:', h['config'].get('url')) print('type:', h['type']) print('active:', h['active']) print('last_status:', h.get('last_status','?')) " 2>/dev/null """) # 2. Jenkins에서 Gitea 플러그인이 사용하는 실제 트리거 URL 확인 run('Jenkins job trigger 설정', f'curl -sf -u "{A}" {J}/job/guardia-itsm/config.xml 2>/dev/null | ' "python3 -c \"import sys; c=sys.stdin.read(); " "[print(l.strip()) for l in c.splitlines() if 'trigger' in l.lower() or 'gitea' in l.lower() or 'hook' in l.lower()]\" 2>/dev/null | head -10") # 3. Jenkins 빌드 history 확인 run('Jenkins 빌드 히스토리', f'curl -sf -u "{A}" {J}/job/guardia-itsm/api/json 2>/dev/null | ' "python3 -c \"import sys,json; d=json.load(sys.stdin); " "print('lastBuild:', d.get('lastBuild',{}).get('number')); " "print('nextBuild:', d.get('nextBuildNumber'))\" 2>/dev/null") # 4. Gitea webhook URL을 Gitea plugin URL로 수정 # Jenkins Gitea plugin이 처리하는 URL: /gitea-webhook/post # 일반 job 트리거 URL: /job/{name}/build (with token) # Jenkins job에 build trigger token 설정 def jenkins_groovy(script, timeout=30): _, o, _ = c.exec_command(f'curl -sf -u "{A}" {J}/crumbIssuer/api/json 2>/dev/null', timeout=10) try: cd = json.loads(o.read().decode('utf-8','replace').strip()) cf = f'{cd["crumbRequestField"]}: {cd["crumb"]}' except: cf = 'Jenkins-Crumb: x' payload = json.dumps({'script': script}) with sftp.open('/tmp/groovy.json', 'w') as f: f.write(json.dumps({'script': script})) _, o, _ = c.exec_command( f'curl -sf -X POST "{J}/scriptText" -u "{A}" ' f'-H "{cf}" --data-urlencode "script={script.replace(chr(39), chr(39)+chr(92)+chr(39)+chr(39))}" 2>/dev/null', timeout=timeout) return o.read().decode('utf-8','replace').strip() # Build Token 설정 (원격 빌드 트리거용) token_script = """ import jenkins.model.* def job = Jenkins.instance.getItem('guardia-itsm') def prop = job.getProperty(org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty.class) println "Job found: ${job.name}" println "Triggers: ${job.triggers}" """ print('\n[Jenkins trigger 설정 확인]') out = jenkins_groovy(token_script) if out: print(f' {out[:300]}') # 5. Gitea webhook URL을 /job/guardia-itsm/build?token=gitea-trigger 로 업데이트 REPOS_HOOK_IDS = { 'guardia-itsm': 17, 'zioinfo-web': 16, 'guardia-manager': 18, 'guardia-messenger': 19, 'guardia-docs': 20, } # Jenkins에 각 job의 trigger token 설정 for repo in REPOS_HOOK_IDS: token_payload = json.dumps({"script": f""" import jenkins.model.* import org.jenkinsci.plugins.workflow.job.* def job = Jenkins.instance.getItem('{repo}') if (!job) {{ println 'NOT FOUND: {repo}'; return }} // Remote trigger 설정 def triggers = job.getProperty(com.github.kosimovsky.gitea.webhook.trigger.GiteaWebHookTrigger) println "gitea trigger: ${{triggers}}" println "job: ${{job.name}} ok" """}) print(f'\n[{repo} trigger 확인]') with sftp.open('/tmp/t.groovy', 'w') as f: f.write(json.loads(token_payload)['script']) # 6. 올바른 접근: Gitea webhook을 deploy_server.py 전용으로 유지하고 # Jenkins는 별도 폴링 또는 deploy_server.py에서 Jenkins API 호출 # 이것이 현재 아키텍처에서 가장 안정적 print('\n[현재 아키텍처 정리]') print(' Gitea push → webhook(9999) → deploy_server.py → 즉시 배포 ✅') print(' Gitea push → webhook(Jenkins) → Jenkins build+test+notify ✅ (설정 중)') # 7. Jenkins에서 직접 Gitea polling 설정 (webhook 대신) run('Jenkins SCM polling 활성화 확인', f'curl -sf -u "{A}" {J}/job/guardia-itsm/config.xml 2>/dev/null | ' "python3 -c \"import sys; c=sys.stdin.read(); print('polling:', 'scmPoll' in c or 'SCMTrigger' in c)\" 2>/dev/null") # 8. deploy_server.py에서 Jenkins build 트리거 추가 run('deploy_server.py Jenkins 트리거 여부', "grep -n 'jenkins\\|9080\\|build' /opt/zioinfo/deploy_server.py | head -10") sftp.close() c.close() print('\n=== 완료 ===')