|
@@ -393,7 +393,7 @@ pipeline {
|
|
|
echo ">>> PROD_DEPLOY_ROOT=${env.PROD_DEPLOY_ROOT}"
|
|
echo ">>> PROD_DEPLOY_ROOT=${env.PROD_DEPLOY_ROOT}"
|
|
|
def _ssh = (params.PROD_SSH_TARGET ?: '').trim()
|
|
def _ssh = (params.PROD_SSH_TARGET ?: '').trim()
|
|
|
if (_ssh) {
|
|
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"
|
|
echo ">>> 本地暂存目录(写入后同步): ${env.WORKSPACE}/.jenkins_remote_prod_staging"
|
|
|
def _paramCred = (params.PROD_SSH_CREDENTIALS_ID != null) ? params.PROD_SSH_CREDENTIALS_ID.toString().trim() : ''
|
|
def _paramCred = (params.PROD_SSH_CREDENTIALS_ID != null) ? params.PROD_SSH_CREDENTIALS_ID.toString().trim() : ''
|
|
|
def _sc = effectiveProdSshCredentialsId(_ssh)
|
|
def _sc = effectiveProdSshCredentialsId(_ssh)
|
|
@@ -563,6 +563,7 @@ printf '%s' "\$OUT"
|
|
|
}
|
|
}
|
|
|
steps {
|
|
steps {
|
|
|
script {
|
|
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 prodSsh = (params.PROD_SSH_TARGET ?: '').trim()
|
|
|
def prodRemoteRoot = (params.PROD_DEPLOY_ROOT ?: env.PROD_DEPLOY_ROOT ?: '/alien_produ/java').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')
|
|
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 dstDirSh = dstDir.replace("'", "'\\''")
|
|
|
def rsyncBootstrapBlock = ''
|
|
def rsyncBootstrapBlock = ''
|
|
|
if (prodSsh) {
|
|
if (prodSsh) {
|
|
|
|
|
+ // Jenkins 官方镜像常无 rsync;用 tar|ssh(两端需有 tar)
|
|
|
rsyncBootstrapBlock = """
|
|
rsyncBootstrapBlock = """
|
|
|
ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new '${sshQE}' "mkdir -p '${remQE}/${s.prodDir}/config'"
|
|
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
|
|
if [ "\$JENKINS_DRY_RUN" = 'true' ]; then
|
|
|
echo "[DRY_RUN] 尝试 BOOT-INF/classes/ 或瘦 jar 根目录 bootstrap-prod.yml -> ${dstFile}"
|
|
echo "[DRY_RUN] 尝试 BOOT-INF/classes/ 或瘦 jar 根目录 bootstrap-prod.yml -> ${dstFile}"
|
|
|
if [ -n '${sshQE}' ]; then
|
|
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
|
|
fi
|
|
|
else
|
|
else
|
|
|
mkdir -p "${dstDir}"
|
|
mkdir -p "${dstDir}"
|
|
@@ -637,7 +639,7 @@ printf '%s' "\$OUT"
|
|
|
echo "[DRY_RUN] mkdir -p ${dstDir}"
|
|
echo "[DRY_RUN] mkdir -p ${dstDir}"
|
|
|
echo "[DRY_RUN] cp -f ${srcGit} ${dstFile}"
|
|
echo "[DRY_RUN] cp -f ${srcGit} ${dstFile}"
|
|
|
if [ -n '${sshQE}' ]; then
|
|
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
|
|
fi
|
|
|
else
|
|
else
|
|
|
mkdir -p "${dstDir}"
|
|
mkdir -p "${dstDir}"
|
|
@@ -936,7 +938,7 @@ printf '%s' "\$OUT"
|
|
|
" JENKINS_PROD_ENV_FILE='" + effEnvPathForSh + "'\n"
|
|
" 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 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 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)'
|
|
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"
|
|
echo "[DRY_RUN] 同步 lib: \$PROMOTE_SRC_LIB -> \$PROMOTE_DST_LIB"
|
|
|
fi
|
|
fi
|
|
|
if [ -n "\$JENKINS_PROD_SSH" ]; then
|
|
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
|
|
fi
|
|
|
echo "[DRY_RUN] 将执行: docker compose -f \$COMPOSE_FILE --project-directory \$COMPOSE_DIR(restart 或 up -d --no-deps)\$COMPOSE_SVC;非 DRY 时脚本会设 COMPOSE_DIR"
|
|
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
|
|
if [ "\$JENKINS_PAY_CERT_SVC" = '1' ]; then
|