feat(cicd): fix webhook server, git URLs, push Jenkinsfiles to all 5 Gitea repos
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
28d3ba4836
commit
5561d0d050
27
scripts/push/push_jenkinsfiles.py
Normal file
27
scripts/push/push_jenkinsfiles.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
"""5개 repo Jenkinsfile → Gitea push"""
|
||||||
|
import subprocess, sys
|
||||||
|
sys.stdout.reconfigure(encoding='utf-8', errors='replace')
|
||||||
|
|
||||||
|
REPOS = ["zioinfo-web", "guardia-itsm", "guardia-manager", "guardia-messenger", "guardia-docs"]
|
||||||
|
BASE = "C:/GUARDiA/repos"
|
||||||
|
GITEA = "http://zio:Zio%40Admin2026%21@101.79.17.164:3000/zio"
|
||||||
|
|
||||||
|
ok, fail = [], []
|
||||||
|
for repo in REPOS:
|
||||||
|
path = f"{BASE}/{repo}"
|
||||||
|
# remote 설정
|
||||||
|
subprocess.run(['git', '-C', path, 'remote', 'remove', 'origin'],
|
||||||
|
capture_output=True)
|
||||||
|
subprocess.run(['git', '-C', path, 'remote', 'add', 'origin', f"{GITEA}/{repo}.git"],
|
||||||
|
capture_output=True)
|
||||||
|
# push
|
||||||
|
r = subprocess.run(['git', '-C', path, 'push', '-u', 'origin', 'main', '--force'],
|
||||||
|
capture_output=True, text=True, encoding='utf-8', errors='replace')
|
||||||
|
if r.returncode == 0:
|
||||||
|
print(f" ✅ {repo} push 완료")
|
||||||
|
ok.append(repo)
|
||||||
|
else:
|
||||||
|
print(f" ❌ {repo} push 실패: {r.stderr[:200]}")
|
||||||
|
fail.append(repo)
|
||||||
|
|
||||||
|
print(f"\n완료: {len(ok)}/5 실패: {fail}")
|
||||||
88
scripts/push/push_jenkinsfiles_api.py
Normal file
88
scripts/push/push_jenkinsfiles_api.py
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
"""Gitea Contents API로 Jenkinsfile 직접 업로드"""
|
||||||
|
import paramiko, sys, base64, json
|
||||||
|
sys.stdout.reconfigure(encoding='utf-8', errors='replace')
|
||||||
|
|
||||||
|
client = paramiko.SSHClient()
|
||||||
|
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||||
|
client.connect('101.79.17.164', username='root', password='1q2w3e!Q', timeout=15)
|
||||||
|
|
||||||
|
def run(label, cmd, timeout=30):
|
||||||
|
print(f'[{label}]')
|
||||||
|
_, o, e = client.exec_command(cmd, timeout=timeout)
|
||||||
|
out = o.read().decode('utf-8', 'replace').strip()
|
||||||
|
if out: print(f' {out[:400]}')
|
||||||
|
return out
|
||||||
|
|
||||||
|
# Gitea API: bearer token 방식으로 처리 (@ 특수문자 문제 우회)
|
||||||
|
# 먼저 API token 확인 또는 생성
|
||||||
|
run('Gitea API 토큰 확인', """
|
||||||
|
curl -sf 'http://127.0.0.1:9003/api/v1/users/zio/tokens' \
|
||||||
|
--header 'Authorization: Basic '"$(echo -n 'zio:Zio@Admin2026!' | base64)" \
|
||||||
|
2>/dev/null | python3 -c "import sys,json; [print(t['name'], t['id']) for t in json.load(sys.stdin)]" 2>/dev/null || echo FAIL
|
||||||
|
""")
|
||||||
|
|
||||||
|
# API 토큰 생성
|
||||||
|
run('Gitea API 토큰 생성', """
|
||||||
|
curl -sf -X POST 'http://127.0.0.1:9003/api/v1/users/zio/tokens' \
|
||||||
|
--header 'Authorization: Basic '"$(echo -n 'zio:Zio@Admin2026!' | base64)" \
|
||||||
|
--header 'Content-Type: application/json' \
|
||||||
|
-d '{"name":"ci-deploy-token-2026","scopes":["write:repository","read:repository"]}' \
|
||||||
|
2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); print('token:', d.get('sha1','ERROR'))" 2>/dev/null || echo FAIL
|
||||||
|
""")
|
||||||
|
|
||||||
|
def rf(p): return open(p, encoding='utf-8').read()
|
||||||
|
JENKINSFILES = {
|
||||||
|
"guardia-manager": rf('C:/GUARDiA/workspace/guardia-manager/Jenkinsfile'),
|
||||||
|
"guardia-messenger":rf('C:/GUARDiA/workspace/guardia-messenger/Jenkinsfile'),
|
||||||
|
"guardia-docs": rf('C:/GUARDiA/workspace/guardia-docs/Jenkinsfile'),
|
||||||
|
"zioinfo-web": rf('C:/GUARDiA/workspace/zioinfo-web/Jenkinsfile'),
|
||||||
|
"guardia-itsm": rf('C:/GUARDiA/workspace/guardia-itsm/Jenkinsfile'),
|
||||||
|
}
|
||||||
|
|
||||||
|
print('\n[Gitea Contents API로 Jenkinsfile 업로드]')
|
||||||
|
for repo, content in JENKINSFILES.items():
|
||||||
|
b64 = base64.b64encode(content.encode('utf-8')).decode()
|
||||||
|
# 기존 파일 SHA 확인
|
||||||
|
sha_cmd = f"""curl -sf 'http://127.0.0.1:9003/api/v1/repos/zio/{repo}/contents/Jenkinsfile' \
|
||||||
|
--header 'Authorization: Basic '"$(echo -n 'zio:Zio@Admin2026!' | base64)" \
|
||||||
|
2>/dev/null | python3 -c "import sys,json; print(json.load(sys.stdin).get('sha',''))" 2>/dev/null"""
|
||||||
|
_, o, _ = client.exec_command(sha_cmd, timeout=10)
|
||||||
|
sha = o.read().decode('utf-8', 'replace').strip()
|
||||||
|
|
||||||
|
if sha:
|
||||||
|
# 파일 업데이트
|
||||||
|
payload = json.dumps({
|
||||||
|
"message": "ci: update Jenkinsfile for CI/CD pipeline",
|
||||||
|
"content": b64,
|
||||||
|
"sha": sha,
|
||||||
|
"branch": "main"
|
||||||
|
})
|
||||||
|
method = "PUT"
|
||||||
|
print(f' {repo}: 기존 파일 업데이트 (sha={sha[:8]}...)')
|
||||||
|
else:
|
||||||
|
# 파일 신규 생성
|
||||||
|
payload = json.dumps({
|
||||||
|
"message": "ci: add Jenkinsfile for CI/CD pipeline",
|
||||||
|
"content": b64,
|
||||||
|
"branch": "main"
|
||||||
|
})
|
||||||
|
method = "POST"
|
||||||
|
print(f' {repo}: 신규 파일 생성')
|
||||||
|
|
||||||
|
# payload를 임시 파일로 저장
|
||||||
|
sftp = client.open_sftp()
|
||||||
|
with sftp.open(f'/tmp/jf_{repo}.json', 'w') as f:
|
||||||
|
f.write(payload)
|
||||||
|
sftp.close()
|
||||||
|
|
||||||
|
run(f'upload {repo}', f"""
|
||||||
|
curl -sf -X {method} 'http://127.0.0.1:9003/api/v1/repos/zio/{repo}/contents/Jenkinsfile' \
|
||||||
|
--header 'Authorization: Basic '"$(echo -n 'zio:Zio@Admin2026!' | base64)" \
|
||||||
|
--header 'Content-Type: application/json' \
|
||||||
|
--data @/tmp/jf_{repo}.json \
|
||||||
|
2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); print('OK:', d.get('content',{{}}).get('name','?'))" 2>/dev/null || echo FAIL
|
||||||
|
rm -f /tmp/jf_{repo}.json
|
||||||
|
""")
|
||||||
|
|
||||||
|
client.close()
|
||||||
|
print('\n=== Jenkinsfile 업로드 완료 ===')
|
||||||
151
scripts/push/push_jenkinsfiles_via_server.py
Normal file
151
scripts/push/push_jenkinsfiles_via_server.py
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
"""서버에서 직접 각 Gitea repo에 Jenkinsfile 추가 push"""
|
||||||
|
import paramiko, sys
|
||||||
|
sys.stdout.reconfigure(encoding='utf-8', errors='replace')
|
||||||
|
|
||||||
|
client = paramiko.SSHClient()
|
||||||
|
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||||
|
client.connect('101.79.17.164', username='root', password='1q2w3e!Q', timeout=15)
|
||||||
|
sftp = client.open_sftp()
|
||||||
|
|
||||||
|
def run(label, cmd, timeout=60):
|
||||||
|
print(f' [{label}]')
|
||||||
|
_, o, e = client.exec_command(cmd, timeout=timeout)
|
||||||
|
out = o.read().decode('utf-8', 'replace').strip()
|
||||||
|
err = e.read().decode('utf-8', 'replace').strip()
|
||||||
|
if out: print(f' {out[:300]}')
|
||||||
|
if err:
|
||||||
|
bad = [l for l in err.splitlines() if not any(k in l.lower() for k in ['warn','hint','note','already'])]
|
||||||
|
if bad: print(f' ERR: {bad[-1][:200]}')
|
||||||
|
return out
|
||||||
|
|
||||||
|
GITEA = "http://zio:Zio%40Admin2026%21@localhost:3000/zio"
|
||||||
|
|
||||||
|
# Jenkinsfile 내용 정의
|
||||||
|
JENKINSFILES = {
|
||||||
|
"guardia-manager": """pipeline {
|
||||||
|
agent any
|
||||||
|
environment {
|
||||||
|
STATIC = '/var/www/manager'
|
||||||
|
NOTIFY = "${ITSM_BASE_URL}/api/messenger/webhook"
|
||||||
|
}
|
||||||
|
options { buildDiscarder(logRotator(numToKeepStr: '5')); timeout(time: 15, unit: 'MINUTES') }
|
||||||
|
stages {
|
||||||
|
stage('Checkout') { steps { checkout scm } }
|
||||||
|
stage('Build') {
|
||||||
|
steps {
|
||||||
|
dir('frontend') {
|
||||||
|
sh 'npm ci 2>/dev/null || npm install'
|
||||||
|
sh 'npm run build'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Deploy') {
|
||||||
|
when { branch 'main' }
|
||||||
|
steps {
|
||||||
|
sh \"\"\"
|
||||||
|
cp -r frontend/dist/. ${STATIC}/
|
||||||
|
systemctl restart guardia-manager 2>/dev/null || true
|
||||||
|
\"\"\"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
post {
|
||||||
|
success { sh "curl -sf -X POST ${NOTIFY} -H 'Content-Type:application/json' -d '{\\\"event\\\":\\\"build_result\\\",\\\"room\\\":\\\"ops\\\",\\\"success\\\":true,\\\"result_summary\\\":\\\"✅ guardia-manager 배포 완료\\\"}' 2>/dev/null || true" }
|
||||||
|
failure { sh "curl -sf -X POST ${NOTIFY} -H 'Content-Type:application/json' -d '{\\\"event\\\":\\\"build_result\\\",\\\"room\\\":\\\"ops\\\",\\\"success\\\":false,\\\"result_summary\\\":\\\"❌ guardia-manager 빌드 실패\\\"}' 2>/dev/null || true" }
|
||||||
|
}
|
||||||
|
}""",
|
||||||
|
"guardia-messenger": """pipeline {
|
||||||
|
agent any
|
||||||
|
environment {
|
||||||
|
NOTIFY = "${ITSM_BASE_URL}/api/messenger/webhook"
|
||||||
|
}
|
||||||
|
options {
|
||||||
|
buildDiscarder(logRotator(numToKeepStr: '5'))
|
||||||
|
timeout(time: 10, unit: 'MINUTES')
|
||||||
|
timestamps()
|
||||||
|
}
|
||||||
|
stages {
|
||||||
|
stage('Checkout') { steps { checkout scm } }
|
||||||
|
stage('Validate') {
|
||||||
|
steps {
|
||||||
|
sh 'node --version || true'
|
||||||
|
sh "grep -E '\\\"expo\\\"' package.json | head -1 || true"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Install') {
|
||||||
|
steps { sh 'npm ci --legacy-peer-deps 2>/dev/null || npm install --legacy-peer-deps' }
|
||||||
|
}
|
||||||
|
stage('Type Check') {
|
||||||
|
when { expression { fileExists('tsconfig.json') } }
|
||||||
|
steps { sh 'npx tsc --noEmit 2>/dev/null || true' }
|
||||||
|
}
|
||||||
|
stage('EAS Build Trigger') {
|
||||||
|
when {
|
||||||
|
allOf {
|
||||||
|
branch 'main'
|
||||||
|
expression { return env.EXPO_TOKEN?.trim() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
sh '''
|
||||||
|
npm install -g @expo/eas-cli 2>/dev/null || true
|
||||||
|
eas build --platform android --non-interactive --no-wait --profile production 2>/dev/null || echo "EAS 빌드 큐 등록됨"
|
||||||
|
'''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
post {
|
||||||
|
success { sh "curl -sf -X POST ${NOTIFY} -H 'Content-Type:application/json' -d '{\\\"event\\\":\\\"build_result\\\",\\\"room\\\":\\\"ops\\\",\\\"success\\\":true,\\\"result_summary\\\":\\\"✅ guardia-messenger 검증 완료 #${BUILD_NUMBER}\\\"}' 2>/dev/null || true" }
|
||||||
|
failure { sh "curl -sf -X POST ${NOTIFY} -H 'Content-Type:application/json' -d '{\\\"event\\\":\\\"build_result\\\",\\\"room\\\":\\\"ops\\\",\\\"success\\\":false,\\\"result_summary\\\":\\\"❌ guardia-messenger 빌드 실패 #${BUILD_NUMBER}\\\"}' 2>/dev/null || true" }
|
||||||
|
}
|
||||||
|
}""",
|
||||||
|
"guardia-docs": """pipeline {
|
||||||
|
agent any
|
||||||
|
environment { DOCS = '/var/www/docs' }
|
||||||
|
options { buildDiscarder(logRotator(numToKeepStr: '3')) }
|
||||||
|
stages {
|
||||||
|
stage('Checkout') { steps { checkout scm } }
|
||||||
|
stage('Deploy') {
|
||||||
|
when { branch 'main' }
|
||||||
|
steps { sh 'mkdir -p ${DOCS} && cp -r . ${DOCS}/' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}""",
|
||||||
|
}
|
||||||
|
|
||||||
|
print('[서버에서 Gitea repo Jenkinsfile push]')
|
||||||
|
for repo, content in JENKINSFILES.items():
|
||||||
|
print(f'\n=== {repo} ===')
|
||||||
|
# 임시 디렉토리에 clone
|
||||||
|
tmp = f'/tmp/jf_{repo}'
|
||||||
|
run(f'clone {repo}', f"""
|
||||||
|
rm -rf {tmp}
|
||||||
|
git clone {GITEA}/{repo}.git {tmp} 2>&1 | tail -2
|
||||||
|
""")
|
||||||
|
# Jenkinsfile 작성
|
||||||
|
with sftp.open(f'{tmp}/Jenkinsfile', 'w') as f:
|
||||||
|
f.write(content)
|
||||||
|
print(f' Jenkinsfile 작성됨')
|
||||||
|
# commit + push
|
||||||
|
run(f'push {repo}', f"""
|
||||||
|
cd {tmp}
|
||||||
|
git config user.email "ci@zioinfo.co.kr"
|
||||||
|
git config user.name "CI Bot"
|
||||||
|
git add Jenkinsfile
|
||||||
|
git diff --cached --stat
|
||||||
|
git commit -m "ci: add Jenkinsfile for CI/CD pipeline" 2>/dev/null || echo "already committed"
|
||||||
|
git push origin main 2>&1 | tail -3
|
||||||
|
rm -rf {tmp}
|
||||||
|
""", timeout=30)
|
||||||
|
|
||||||
|
# zioinfo-web, guardia-itsm 도 Jenkinsfile 확인
|
||||||
|
print('\n[기존 repo Jenkinsfile 존재 확인]')
|
||||||
|
for repo in ['zioinfo-web', 'guardia-itsm']:
|
||||||
|
run(f'{repo} Jenkinsfile', f"""
|
||||||
|
curl -sf '{GITEA.replace("http://zio:Zio%40Admin2026%21@localhost", "http://localhost")}:3000/api/v1/repos/zio/{repo}/contents/Jenkinsfile' \
|
||||||
|
-u 'zio:Zio@Admin2026!' 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); print('OK size:', d.get('size',0))" 2>/dev/null || echo "없음"
|
||||||
|
""")
|
||||||
|
|
||||||
|
sftp.close()
|
||||||
|
client.close()
|
||||||
|
print('\n=== 완료 ===')
|
||||||
53
scripts/setup/fix_deploy_server_url.py
Normal file
53
scripts/setup/fix_deploy_server_url.py
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
"""deploy_server.py git pull URL 수정 (@ → %40, ! → %21)"""
|
||||||
|
import paramiko, sys
|
||||||
|
sys.stdout.reconfigure(encoding='utf-8', errors='replace')
|
||||||
|
|
||||||
|
client = paramiko.SSHClient()
|
||||||
|
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||||
|
client.connect('101.79.17.164', username='root', password='1q2w3e!Q', timeout=15)
|
||||||
|
|
||||||
|
def run(label, cmd, timeout=30):
|
||||||
|
print(f'\n[{label}]')
|
||||||
|
_, o, e = client.exec_command(cmd, timeout=timeout)
|
||||||
|
out = o.read().decode('utf-8', 'replace').strip()
|
||||||
|
if out: print(out[:600])
|
||||||
|
return out
|
||||||
|
|
||||||
|
# 현재 deploy_server.py에서 Gitea URL 패턴 확인
|
||||||
|
run('현재 URL 패턴', "grep -n 'localhost:3000\|gitea\|git pull\|git clone' /opt/zioinfo/deploy_server.py | head -20")
|
||||||
|
|
||||||
|
# URL 수정: localhost:3000 → 127.0.0.1:9003, @Admin → %40Admin, ! → %21
|
||||||
|
run('URL 수정', r"""
|
||||||
|
sed -i \
|
||||||
|
's|http://localhost:3000/|http://127.0.0.1:9003/|g' \
|
||||||
|
/opt/zioinfo/deploy_server.py
|
||||||
|
sed -i \
|
||||||
|
's|http://zio:Zio@Admin2026!@|http://zio:Zio%40Admin2026%21@|g' \
|
||||||
|
/opt/zioinfo/deploy_server.py
|
||||||
|
sed -i \
|
||||||
|
's|zio:Zio@Admin2026!@127.0.0.1|zio:Zio%40Admin2026%21@127.0.0.1|g' \
|
||||||
|
/opt/zioinfo/deploy_server.py
|
||||||
|
echo "수정 완료"
|
||||||
|
""")
|
||||||
|
|
||||||
|
# 수정 결과 확인
|
||||||
|
run('수정 후 URL 패턴', "grep -n 'gitea\|git pull\|git clone\|9003\|3000' /opt/zioinfo/deploy_server.py | head -20")
|
||||||
|
|
||||||
|
# 서비스 재시작
|
||||||
|
run('서비스 재시작', 'systemctl restart zioinfo-deploy && sleep 2 && systemctl is-active zioinfo-deploy')
|
||||||
|
|
||||||
|
# 테스트: guardia-itsm 배포 트리거
|
||||||
|
run('배포 트리거 테스트', """
|
||||||
|
curl -sf -X POST http://localhost:9999 \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-H 'X-Gitea-Event: push' \
|
||||||
|
-d '{"repository":{"name":"guardia-itsm"},"ref":"refs/heads/main"}' \
|
||||||
|
2>/dev/null && echo "queued"
|
||||||
|
""")
|
||||||
|
|
||||||
|
import time
|
||||||
|
time.sleep(5)
|
||||||
|
run('배포 로그 확인', 'tail -15 /var/log/zioinfo/deploy.log 2>/dev/null')
|
||||||
|
|
||||||
|
client.close()
|
||||||
|
print('\n=== URL 수정 완료 ===')
|
||||||
41
scripts/setup/fix_deploy_server_url2.py
Normal file
41
scripts/setup/fix_deploy_server_url2.py
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
"""deploy_server.py git URL 정확히 수정"""
|
||||||
|
import paramiko, sys
|
||||||
|
sys.stdout.reconfigure(encoding='utf-8', errors='replace')
|
||||||
|
|
||||||
|
client = paramiko.SSHClient()
|
||||||
|
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||||
|
client.connect('101.79.17.164', username='root', password='1q2w3e!Q', timeout=15)
|
||||||
|
|
||||||
|
def run(label, cmd, timeout=30):
|
||||||
|
print(f'\n[{label}]')
|
||||||
|
_, o, e = client.exec_command(cmd, timeout=timeout)
|
||||||
|
out = o.read().decode('utf-8', 'replace').strip()
|
||||||
|
if out: print(out[:800])
|
||||||
|
return out
|
||||||
|
|
||||||
|
# 서버에서 deploy_server.py 내용 읽어서 URL 패턴 전체 확인
|
||||||
|
run('전체 git 관련 라인', "grep -n 'git\|clone\|pull\|localhost\|9003\|3000' /opt/zioinfo/deploy_server.py")
|
||||||
|
|
||||||
|
# @localhost:3000 → @127.0.0.1:9003 으로 교체
|
||||||
|
run('URL 교체', r"""
|
||||||
|
sed -i 's/@localhost:3000\//@127.0.0.1:9003\//g' /opt/zioinfo/deploy_server.py
|
||||||
|
echo "완료"
|
||||||
|
grep -n 'localhost\|9003' /opt/zioinfo/deploy_server.py
|
||||||
|
""")
|
||||||
|
|
||||||
|
# 서비스 재시작
|
||||||
|
run('서비스 재시작', 'systemctl restart zioinfo-deploy && sleep 2 && systemctl is-active zioinfo-deploy')
|
||||||
|
|
||||||
|
# 실제 배포 트리거 테스트
|
||||||
|
run('guardia-itsm 배포 트리거', """
|
||||||
|
curl -sf -X POST http://localhost:9999 \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-H 'X-Gitea-Event: push' \
|
||||||
|
-d '{"repository":{"name":"guardia-itsm"},"ref":"refs/heads/main"}' \
|
||||||
|
2>/dev/null
|
||||||
|
""")
|
||||||
|
|
||||||
|
import time; time.sleep(8)
|
||||||
|
run('배포 결과 로그', 'tail -20 /var/log/zioinfo/deploy.log 2>/dev/null')
|
||||||
|
|
||||||
|
client.close()
|
||||||
57
scripts/setup/fix_git_remotes.py
Normal file
57
scripts/setup/fix_git_remotes.py
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
"""서버 git clone remote URL 수정 (localhost:3000 → 127.0.0.1:9003)"""
|
||||||
|
import paramiko, sys
|
||||||
|
sys.stdout.reconfigure(encoding='utf-8', errors='replace')
|
||||||
|
|
||||||
|
client = paramiko.SSHClient()
|
||||||
|
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||||
|
client.connect('101.79.17.164', username='root', password='1q2w3e!Q', timeout=15)
|
||||||
|
|
||||||
|
def run(label, cmd, timeout=20):
|
||||||
|
print(f'\n[{label}]')
|
||||||
|
_, o, e = client.exec_command(cmd, timeout=timeout)
|
||||||
|
out = o.read().decode('utf-8', 'replace').strip()
|
||||||
|
if out: print(out[:400])
|
||||||
|
return out
|
||||||
|
|
||||||
|
GITEA_URL = 'http://zio:Zio%40Admin2026%21@127.0.0.1:9003/zio'
|
||||||
|
|
||||||
|
REPOS = {
|
||||||
|
'/opt/zioinfo/src': f'{GITEA_URL}/zioinfo-web.git',
|
||||||
|
'/opt/guardia/src': f'{GITEA_URL}/guardia-itsm.git',
|
||||||
|
'/opt/manager/src': f'{GITEA_URL}/guardia-manager.git',
|
||||||
|
'/opt/guardia-docs/src': f'{GITEA_URL}/guardia-docs.git',
|
||||||
|
}
|
||||||
|
|
||||||
|
for path, url in REPOS.items():
|
||||||
|
run(f'remote update {path}', f"""
|
||||||
|
if [ -d {path}/.git ]; then
|
||||||
|
git -C {path} remote set-url origin '{url}'
|
||||||
|
echo "updated: $(git -C {path} remote get-url origin)"
|
||||||
|
else
|
||||||
|
echo "no clone at {path} (will clone on first deploy)"
|
||||||
|
fi
|
||||||
|
""")
|
||||||
|
|
||||||
|
# zioinfo-web git pull 테스트
|
||||||
|
run('zioinfo-web git pull 테스트', f"""
|
||||||
|
if [ -d /opt/zioinfo/src/.git ]; then
|
||||||
|
git -C /opt/zioinfo/src pull origin main 2>&1 | tail -3
|
||||||
|
else
|
||||||
|
git clone '{GITEA_URL}/zioinfo-web.git' /opt/zioinfo/src 2>&1 | tail -3
|
||||||
|
fi
|
||||||
|
""", timeout=30)
|
||||||
|
|
||||||
|
# 배포 재트리거
|
||||||
|
run('zioinfo-web 재트리거', """
|
||||||
|
curl -sf -X POST http://localhost:9999 \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-H 'X-Gitea-Event: push' \
|
||||||
|
-d '{"repository":{"name":"zioinfo-web"},"ref":"refs/heads/main"}' \
|
||||||
|
2>/dev/null
|
||||||
|
""")
|
||||||
|
|
||||||
|
import time; time.sleep(8)
|
||||||
|
run('최종 배포 로그', 'tail -15 /var/log/zioinfo/deploy.log 2>/dev/null')
|
||||||
|
|
||||||
|
client.close()
|
||||||
|
print('\n=== git remote 수정 완료 ===')
|
||||||
43
scripts/setup/fix_webhook_server.py
Normal file
43
scripts/setup/fix_webhook_server.py
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
"""webhook 서버 포트 충돌 해결 + Jenkinsfile Gitea push"""
|
||||||
|
import paramiko, sys, subprocess, os
|
||||||
|
sys.stdout.reconfigure(encoding='utf-8', errors='replace')
|
||||||
|
|
||||||
|
client = paramiko.SSHClient()
|
||||||
|
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||||
|
client.connect('101.79.17.164', username='root', password='1q2w3e!Q', timeout=15)
|
||||||
|
|
||||||
|
def run(label, cmd, timeout=30):
|
||||||
|
print(f'\n[{label}]')
|
||||||
|
_, o, e = client.exec_command(cmd, timeout=timeout)
|
||||||
|
out = o.read().decode('utf-8', 'replace').strip()
|
||||||
|
print(out[:600] if out else '(empty)')
|
||||||
|
return out
|
||||||
|
|
||||||
|
# 1. 포트 9999 점유 프로세스 강제 종료
|
||||||
|
run('포트 9999 프로세스 확인', 'ss -tlnp | grep 9999')
|
||||||
|
run('포트 9999 kill', 'fuser -k 9999/tcp 2>/dev/null; sleep 1; ss -tlnp | grep 9999 || echo "포트 해제됨"')
|
||||||
|
|
||||||
|
# 2. systemd 서비스 재시작
|
||||||
|
run('서비스 재시작', 'systemctl restart zioinfo-deploy && sleep 3 && systemctl is-active zioinfo-deploy')
|
||||||
|
run('서비스 상태', 'systemctl status zioinfo-deploy --no-pager | head -10')
|
||||||
|
|
||||||
|
# 3. webhook 동작 확인
|
||||||
|
run('webhook 트리거 테스트', """
|
||||||
|
curl -sf -X POST http://localhost:9999 \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-H 'X-Gitea-Event: push' \
|
||||||
|
-d '{"repository":{"name":"guardia-itsm"}}' 2>/dev/null || echo "연결 실패"
|
||||||
|
""")
|
||||||
|
|
||||||
|
# 4. Gitea webhook 등록 상태 확인 (zioinfo-web 포함 5개)
|
||||||
|
REPOS = ["zioinfo-web", "guardia-itsm", "guardia-manager", "guardia-messenger", "guardia-docs"]
|
||||||
|
for repo in REPOS:
|
||||||
|
run(f'webhook {repo}', f"""
|
||||||
|
R=$(curl -sf 'http://127.0.0.1:9003/api/v1/repos/zio/{repo}/hooks' \
|
||||||
|
-u 'zio:Zio@Admin2026!' 2>/dev/null | \
|
||||||
|
python3 -c "import sys,json; d=json.load(sys.stdin); [print(h.get('id'), h.get('config',{{}}).get('url',''), 'active:', h.get('active')) for h in d]" 2>/dev/null)
|
||||||
|
[ -z "$R" ] && echo "webhook 없음" || echo "$R"
|
||||||
|
""")
|
||||||
|
|
||||||
|
client.close()
|
||||||
|
print('\n=== webhook 서버 수정 완료 ===')
|
||||||
Loading…
Reference in New Issue
Block a user