From e3fb52343d09049a7c7ae6dbd00af49d4f33f14a Mon Sep 17 00:00:00 2001 From: Rinjae Date: Thu, 9 Jul 2026 16:20:54 +0900 Subject: [PATCH] =?UTF-8?q?"Jenkinsfile=20=EA=B0=9C=EC=84=A0:=20-=20Tomcat?= =?UTF-8?q?=20=EB=B0=B0=ED=8F=AC=20=EA=B5=AC=EC=A1=B0=20=E2=86=92=20WebLog?= =?UTF-8?q?ic=20=EA=B8=B0=EB=B0=98=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= =?UTF-8?q?=20-=20stage=EB=B3=84=20agent=20=EB=AA=85=EC=8B=9C=20=EB=B0=8F?= =?UTF-8?q?=20=EB=B6=88=ED=95=84=EC=9A=94=ED=95=9C=20=ED=99=98=EA=B2=BD?= =?UTF-8?q?=EB=B3=80=EC=88=98=20=EC=A0=9C=EA=B1=B0=20-=20Webhook=20?= =?UTF-8?q?=EC=95=8C=EB=A6=BC=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Jenkinsfile | 260 +++++++++++++++++++++++++--------------------------- 1 file changed, 127 insertions(+), 133 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 4ce8da5..3ae52ea 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,163 +1,157 @@ pipeline { - agent { label 'djb-vm' } + agent none options { timestamps() disableConcurrentBuilds() + skipDefaultCheckout() // stage별 agent의 자동 SCM checkout 방지 (Deploy 노드는 git 접근 불필요, unstash로만 WAR 수신) buildDiscarder(logRotator(numToKeepStr: '20', artifactNumToKeepStr: '20')) } environment { - JAVA_HOME = '/apps/opts/jdk8' - JAVA_HOME_TOMCAT = '/apps/opts/jdk17' - GRADLE_HOME = '/apps/opts/gradle-8.7' - GRADLE_USER_HOME = '/apps/opts/gradle-home' - NODE_HOME = '/apps/opts/node-v24' - PATH = "/apps/opts/jdk8/bin:/apps/opts/gradle-8.7/bin:/apps/opts/node-v24/bin:/apps/opts/bin:${env.PATH}" GIT_SSH_COMMAND = 'ssh -o StrictHostKeyChecking=accept-new' - CATALINA_BASE = '/prod/eapim/apigw' - CATALINA_HOME = '/prod/eapim/apache-tomcat-9.0.116' - CATALINA_PID = '/prod/eapim/apigw/logs/catalina.pid' - DEPLOY_HTTP_PORT = '39110' + WEBHOOK_URL = 'http://172.30.1.50:18000/api/hooks/01ba51b01d3c4c98ae8f3183a23a84ed713197857d024b5da4f303458195eb32' } stages { - stage('Checkout') { - steps { - checkout scm + stage('Build (djb-vm)') { + agent { label 'djb-vm' } + environment { + JAVA_HOME = '/apps/opts/jdk8' + GRADLE_HOME = '/apps/opts/gradle-8.7' + GRADLE_USER_HOME = '/apps/opts/gradle-home' + NODE_HOME = '/apps/opts/node-v24' + PATH = "/apps/opts/jdk8/bin:/apps/opts/gradle-8.7/bin:/apps/opts/node-v24/bin:/apps/opts/bin:${env.PATH}" } - } + stages { + stage('Checkout') { + steps { checkout scm } + } - stage('Checkout modules') { - steps { - sh ''' - set -eu + stage('Checkout modules') { + steps { + sh ''' + set -eu - for REPO in elink-online-core elink-online-transformer elink-online-common elink-online-emsclient elink-online-core-jpa; do - if [ ! -e "$REPO/.git" ]; then - rm -rf "$REPO" - git clone --depth=1 --branch master \ - "ssh://git@172.30.1.50:2222/djb-eapim/$REPO.git" \ - "$REPO" - else - git -C "$REPO" fetch --depth=1 origin master - git -C "$REPO" reset --hard origin/master - git -C "$REPO" clean -fdx - fi - done - ''' - } - } + for REPO in elink-online-core elink-online-transformer elink-online-common elink-online-emsclient elink-online-core-jpa; do + if [ ! -e "$REPO/.git" ]; then + rm -rf "$REPO" + git clone --depth=1 --branch master \ + "ssh://git@172.30.1.50:2222/djb-eapim/$REPO.git" \ + "$REPO" + else + git -C "$REPO" fetch --depth=1 origin master + git -C "$REPO" reset --hard origin/master + git -C "$REPO" clean -fdx + fi + done + ''' + } + } - stage('Verify toolchain') { - steps { - sh ''' - set -eu - java -version - gradle --version - ''' - } - } + stage('Verify toolchain') { + steps { + sh ''' + set -eu + java -version + gradle --version + ''' + } + } - stage('Build WAR') { - steps { - sh 'gradle clean build -x test --no-daemon' - } - post { - success { - sh ''' - set -eu - cd build/libs - sha1sum eapim-online.war > eapim-online.war.sha1 - sha256sum eapim-online.war > eapim-online.war.sha256 - md5sum eapim-online.war > eapim-online.war.md5 - ''' - archiveArtifacts artifacts: 'build/libs/eapim-online.war,build/libs/eapim-online.war.sha1,build/libs/eapim-online.war.sha256,build/libs/eapim-online.war.md5', fingerprint: true + stage('Build WAR') { + steps { sh 'gradle clean build -x test --no-daemon -Pprofile=weblogic' } + post { + success { + sh ''' + set -eu + cd build/libs + sha256sum eapim-online.war > eapim-online.war.sha256 + ''' + archiveArtifacts artifacts: 'build/libs/eapim-online.war,build/libs/eapim-online.war.sha256', fingerprint: true + stash name: 'war', includes: 'build/libs/eapim-online.war' + } + } } } } - stage('Stop Tomcat') { - steps { - sh ''' - set +e - systemctl --user stop eapim-apigw 2>/dev/null - - if [ -f "$CATALINA_PID" ] && kill -0 "$(cat "$CATALINA_PID")" 2>/dev/null; then - JAVA_HOME="$JAVA_HOME_TOMCAT" "$CATALINA_HOME/bin/shutdown.sh" 30 -force || true - for i in $(seq 1 30); do - [ -f "$CATALINA_PID" ] && kill -0 "$(cat "$CATALINA_PID")" 2>/dev/null || break - sleep 1 - done - fi - rm -f "$CATALINA_PID" - ''' + stage('Deploy (weblogic)') { + agent { label 'weblogic' } + environment { + JENKINS_NODE_COOKIE = 'dontKillMe' // background weblogic를 빌드 종료 시 죽이지 않게 + WL_HOME = '/app/eapim/apigw' + WL_DEPLOY_DIR = '/app/eapim/apigw' + WL_WAR_NAME = 'eapim-online.war' + WL_HTTP_PORT = '39110' + WL_NOHUP = '/logs/weblogic/domains/eapimDomain/nohup.agwSvr11.out' } - } + stages { + stage('Stop WebLogic') { + steps { + sh '"$WL_HOME/stopAgw11.sh"' // 동기: 완전 종료까지 블록, 미기동 시에도 안전 + } + } + stage('Deploy WAR') { + steps { + unstash 'war' + sh ''' + set -eu + cp build/libs/eapim-online.war "$WL_DEPLOY_DIR/$WL_WAR_NAME" + ls -la "$WL_DEPLOY_DIR" + ''' + } + } + stage('Start WebLogic and readiness') { + steps { + sh ''' + set -eu + "$WL_HOME/startAgw11.sh" # nohup & 로 백그라운드 기동, 즉시 리턴 - stage('Deploy ROOT.war') { - steps { - sh ''' - set -eu - DEPLOY_DIR="$CATALINA_BASE/webapps" - rm -rf "$DEPLOY_DIR/ROOT" "$DEPLOY_DIR/ROOT.war" - cp build/libs/eapim-online.war "$DEPLOY_DIR/ROOT.war" - ls -la "$DEPLOY_DIR" - ''' - } - } + DEADLINE=$(($(date +%s) + 300)) + STATUS=000 + while [ "$(date +%s)" -lt "$DEADLINE" ]; do + STATUS=$(curl -sS -o /dev/null -w '%{http_code}' --max-time 3 \ + "http://localhost:$WL_HTTP_PORT/" 2>/dev/null || echo "000") + case "$STATUS" in + 200|302|401|403|404) echo "Readiness OK (/ HTTP $STATUS)"; break ;; + esac + sleep 3 + done - stage('Start Tomcat and readiness') { - steps { - sh ''' - set -eu - LOG="$CATALINA_BASE/logs/catalina.$(date +%Y-%m-%d).log" - BEFORE=0 - [ -f "$LOG" ] && BEFORE=$(stat -c %s "$LOG") - - systemctl --user start eapim-apigw - - PROBE_URL="http://localhost:$DEPLOY_HTTP_PORT/" - DEADLINE=$(($(date +%s) + 300)) - STATUS=000 - - while [ "$(date +%s)" -lt "$DEADLINE" ]; do - STATUS=$(curl -sS -o /dev/null -w '%{http_code}' --max-time 3 \ - "$PROBE_URL" 2>/dev/null || echo "000") - case "$STATUS" in - 200|302|401|403|404) - echo "Readiness OK ($PROBE_URL HTTP $STATUS)" - break - ;; - esac - - if [ -f "$LOG" ] && tail -c +$((BEFORE+1)) "$LOG" | grep -qE "Application listener .* Exception|SEVERE.*startup.Catalina"; then - echo "Startup error detected in log" - tail -c +$((BEFORE+1)) "$LOG" | tail -80 - exit 1 - fi - sleep 2 - done - - case "$STATUS" in - 200|302|401|403|404) ;; - *) - echo "Readiness probe failed within 300s, last HTTP status: $STATUS" - echo "--- last 300 lines of catalina log ---" - [ -f "$LOG" ] && tail -c +$((BEFORE+1)) "$LOG" | tail -300 - echo "--- systemd unit status ---" - systemctl --user status eapim-apigw --no-pager || true - echo "--- listening ports ---" - ss -tlnp 2>/dev/null | grep -E ":$DEPLOY_HTTP_PORT\\b" || echo "(port $DEPLOY_HTTP_PORT not listening)" - exit 1 - ;; - esac - - echo "--- key boot log lines ---" - tail -c +$((BEFORE+1)) "$LOG" | grep -E "Server startup|Deployment of web" | head -10 || true - ''' + case "$STATUS" in + 200|302|401|403|404) ;; + *) + echo "Readiness failed within 300s, last HTTP=$STATUS" + [ -f "$WL_NOHUP" ] && tail -120 "$WL_NOHUP" + exit 1 + ;; + esac + ''' + } + } } } } + post { + success { + node('weblogic') { + sh ''' + set +e + payload=$(printf '{"text":"[%s #%s](%s) SUCCESS"}' "$JOB_NAME" "$BUILD_NUMBER" "$BUILD_URL") + curl -sS --fail --max-time 5 -H 'Content-Type: application/json' -X POST --data "$payload" "$WEBHOOK_URL" >/dev/null || echo "Webhook failed" + ''' + } + } + failure { + node('weblogic') { + sh ''' + set +e + payload=$(printf '{"text":"[%s #%s](%s) FAILURE"}' "$JOB_NAME" "$BUILD_NUMBER" "$BUILD_URL") + curl -sS --fail --max-time 5 -H 'Content-Type: application/json' -X POST --data "$payload" "$WEBHOOK_URL" >/dev/null || echo "Webhook failed" + ''' + } + } + } }