Kaynağa Gözat

Jenkins 从UAT生成生产环境镜像脚本

dujian 1 gün önce
ebeveyn
işleme
4cd8a0c96f

+ 8 - 6
docs/jenkins/Jenkinsfile-prod-promote-from-uat.groovy

@@ -393,7 +393,7 @@ pipeline {
                     echo ">>> PROD_DEPLOY_ROOT=${env.PROD_DEPLOY_ROOT}"
                     def _ssh = (params.PROD_SSH_TARGET ?: '').trim()
                     if (_ssh) {
-                        echo ">>> PROD_SSH_TARGET=${_ssh}(远程生产:制品 rsync 到对方 PROD_DEPLOY_ROOT,docker compose 在目标机执行)"
+                        echo ">>> PROD_SSH_TARGET=${_ssh}(远程生产:制品 tar|ssh 到对方 PROD_DEPLOY_ROOT,docker compose 在目标机执行)"
                         echo ">>> 本地暂存目录(写入后同步): ${env.WORKSPACE}/.jenkins_remote_prod_staging"
                         def _paramCred = (params.PROD_SSH_CREDENTIALS_ID != null) ? params.PROD_SSH_CREDENTIALS_ID.toString().trim() : ''
                         def _sc = effectiveProdSshCredentialsId(_ssh)
@@ -563,6 +563,7 @@ printf '%s' "\$OUT"
             }
             steps {
                 script {
+                    echo '>>> [bootstrap-sync] 远端目录已改为 tar|ssh(Jenkins 镜像无 rsync)。若下方 xtrace 仍出现 rsync:Job 的 Pipeline 仍是旧脚本,请从仓库复制最新 docs/jenkins/Jenkinsfile-prod-promote-from-uat.groovy 全文保存后再构建。'
                     def prodSsh = (params.PROD_SSH_TARGET ?: '').trim()
                     def prodRemoteRoot = (params.PROD_DEPLOY_ROOT ?: env.PROD_DEPLOY_ROOT ?: '/alien_produ/java').trim()
                     def prodLocalRoot = prodSsh ? "${env.WORKSPACE}/.jenkins_remote_prod_staging".replace('\\', '/') : (env.PROD_DEPLOY_ROOT ?: '/alien_produ/java')
@@ -585,9 +586,10 @@ printf '%s' "\$OUT"
                             def dstDirSh = dstDir.replace("'", "'\\''")
                             def rsyncBootstrapBlock = ''
                             if (prodSsh) {
+                                // Jenkins 官方镜像常无 rsync;用 tar|ssh(两端需有 tar)
                                 rsyncBootstrapBlock = """
                                     ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new '${sshQE}' "mkdir -p '${remQE}/${s.prodDir}/config'"
-                                    rsync -az '${dstDirSh}/' '${sshQE}:${remQE}/${s.prodDir}/config/'
+                                    ( cd '${dstDirSh}' && tar cf - . ) | ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new '${sshQE}' "tar xf - -C '${remQE}/${s.prodDir}/config'"
 """
                             }
 
@@ -607,7 +609,7 @@ printf '%s' "\$OUT"
                                 if [ "\$JENKINS_DRY_RUN" = 'true' ]; then
                                     echo "[DRY_RUN] 尝试 BOOT-INF/classes/ 或瘦 jar 根目录 bootstrap-prod.yml -> ${dstFile}"
                                     if [ -n '${sshQE}' ]; then
-                                        echo "[DRY_RUN] rsync config/ -> ${sshQE}:${remQE}/${s.prodDir}/config/"
+                                        echo "[DRY_RUN] tar|ssh config/ -> ${sshQE}:${remQE}/${s.prodDir}/config/"
                                     fi
                                 else
                                     mkdir -p "${dstDir}"
@@ -637,7 +639,7 @@ printf '%s' "\$OUT"
                                     echo "[DRY_RUN] mkdir -p ${dstDir}"
                                     echo "[DRY_RUN] cp -f ${srcGit} ${dstFile}"
                                     if [ -n '${sshQE}' ]; then
-                                        echo "[DRY_RUN] rsync config/ -> ${sshQE}:${remQE}/${s.prodDir}/config/"
+                                        echo "[DRY_RUN] tar|ssh config/ -> ${sshQE}:${remQE}/${s.prodDir}/config/"
                                     fi
                                 else
                                     mkdir -p "${dstDir}"
@@ -936,7 +938,7 @@ printf '%s' "\$OUT"
                                         "                            JENKINS_PROD_ENV_FILE='" + effEnvPathForSh + "'\n"
 
                                 def remoteDockerShimBlock = useRemoteProd ? '\n                            if [ -n "$JENKINS_PROD_SSH" ]; then\n                              docker() { ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new "$JENKINS_PROD_SSH" sudo docker "$@"; }\n                            fi\n' : '\n'
-                                def rsyncRemoteBlock = useRemoteProd ? '\n                                if [ -n "$JENKINS_PROD_SSH" ]; then\n                                    echo ">>> rsync 制品到 $JENKINS_PROD_SSH:$JENKINS_REMOTE_PROD_ROOT/$PROMOTE_PROD_DIR/"\n                                    ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new "$JENKINS_PROD_SSH" "sudo mkdir -p $JENKINS_REMOTE_PROD_ROOT/$PROMOTE_PROD_DIR $JENKINS_REMOTE_PROD_ROOT/logs/$PROMOTE_PROD_DIR"\n                                    rsync -az "$PROMOTE_DST_DIR/" "$JENKINS_PROD_SSH:$JENKINS_REMOTE_PROD_ROOT/$PROMOTE_PROD_DIR/"\n                                    rsync -az "$(dirname "$PROMOTE_DST_DIR")/logs/$PROMOTE_PROD_DIR/" "$JENKINS_PROD_SSH:$JENKINS_REMOTE_PROD_ROOT/logs/$PROMOTE_PROD_DIR/" 2>/dev/null || true\n                                fi\n' : '\n'
+                                def rsyncRemoteBlock = useRemoteProd ? '\n                                if [ -n "$JENKINS_PROD_SSH" ]; then\n                                    echo ">>> tar|ssh 同步制品到 $JENKINS_PROD_SSH:$JENKINS_REMOTE_PROD_ROOT/$PROMOTE_PROD_DIR/(与 bootstrap 一致:远端 mkdir/tar 不加 sudo;若报 Permission denied 请将 PROD_DEPLOY_ROOT 下目录属主改为 SSH 用户或配置 sudo NOPASSWD)"\n                                    ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new "$JENKINS_PROD_SSH" "mkdir -p $JENKINS_REMOTE_PROD_ROOT/$PROMOTE_PROD_DIR $JENKINS_REMOTE_PROD_ROOT/logs/$PROMOTE_PROD_DIR"\n                                    tar cf - -C "$PROMOTE_DST_DIR" . | ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new "$JENKINS_PROD_SSH" "tar xf - -C $JENKINS_REMOTE_PROD_ROOT/$PROMOTE_PROD_DIR"\n                                    _JLOG="$(dirname "$PROMOTE_DST_DIR")/logs/$PROMOTE_PROD_DIR"\n                                    if [ -d "$_JLOG" ]; then\n                                      tar cf - -C "$_JLOG" . 2>/dev/null | ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new "$JENKINS_PROD_SSH" "tar xf - -C $JENKINS_REMOTE_PROD_ROOT/logs/$PROMOTE_PROD_DIR" 2>/dev/null || true\n                                    fi\n                                fi\n' : '\n'
                                 def composeExistsBlockSh = useRemoteProd ? '\n                                if ! ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new "$JENKINS_PROD_SSH" "test -f $COMPOSE_FILE"; then\n                                    echo "ERROR: 远程未找到 docker compose 文件: $COMPOSE_FILE"\n                                    exit 1\n                                fi\n' : '\n                                if [ ! -f "$COMPOSE_FILE" ]; then\n                                    echo "ERROR: 未找到 docker compose 文件: $COMPOSE_FILE。请将 PROD_COMPOSE_FILE/PROD_DEPLOY_ROOT 与现网 yml 对齐,例如 /alien_produ/java/docker-compose.yml"\n                                    exit 1\n                                fi\n'
                                 def composeDirBlockSh = useRemoteProd ? '                                COMPOSE_DIR=$(dirname "$COMPOSE_FILE")' : '                                COMPOSE_DIR=$(cd "$(dirname "$COMPOSE_FILE")" && pwd)'
 
@@ -973,7 +975,7 @@ printf '%s' "\$OUT"
                                     echo "[DRY_RUN] 同步 lib: \$PROMOTE_SRC_LIB -> \$PROMOTE_DST_LIB"
                                 fi
                                 if [ -n "\$JENKINS_PROD_SSH" ]; then
-                                    echo "[DRY_RUN] rsync \$PROMOTE_DST_DIR/ -> \$JENKINS_PROD_SSH:\$JENKINS_REMOTE_PROD_ROOT/\$PROMOTE_PROD_DIR/"
+                                    echo "[DRY_RUN] tar|ssh \$PROMOTE_DST_DIR/ -> \$JENKINS_PROD_SSH:\$JENKINS_REMOTE_PROD_ROOT/\$PROMOTE_PROD_DIR/"
                                 fi
                                 echo "[DRY_RUN] 将执行: docker compose -f \$COMPOSE_FILE --project-directory \$COMPOSE_DIR(restart 或 up -d --no-deps)\$COMPOSE_SVC;非 DRY 时脚本会设 COMPOSE_DIR"
                                 if [ "\$JENKINS_PAY_CERT_SVC" = '1' ]; then