127 lines
4.9 KiB
Python
127 lines
4.9 KiB
Python
"""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=== 완료 ===')
|