feat(prd): add prd-hm script to replace 110 jar without Rainbond

This commit is contained in:
tsiji 2026-09-10 10:29:21 +08:00
parent 25b3c216b0
commit 6da7c08e91

119
deploy/deploy-prd-hm.sh Executable file
View File

@ -0,0 +1,119 @@
#!/bin/bash
# Build prd MES jar on Jenkins and replace it on 110.
# Does not touch Harbor, k8s-manifests, or Rainbond.
set -euo pipefail
HM_SSH="${HM_SSH:-mes@10.10.11.110}"
HM_NS="${HM_NS:-prd}"
HM_LABEL="${HM_LABEL:-name=gr61c96c}"
HM_CONTAINER="${HM_CONTAINER:-nalinv-mes}"
JAR_NAME="${JAR_NAME:-iep-app.jar}"
INT_REPO="${INT_REPO:-http://10.10.11.66:3000/mes/nalinv-int.git}"
INT_BRANCH="${INT_BRANCH:-prd}"
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
cd "$ROOT"
ssh_hm() {
ssh -o BatchMode=yes -o ServerAliveInterval=30 "$HM_SSH" "$@"
}
MAVEN_SETTINGS="${MAVEN_SETTINGS:-}"
if [ -z "$MAVEN_SETTINGS" ] && [ -f /var/jenkins_home/.m2/settings.xml ]; then
MAVEN_SETTINGS="/var/jenkins_home/.m2/settings.xml"
fi
MAVEN_REPO_LOCAL="${MAVEN_REPO_LOCAL:-}"
if [ -z "$MAVEN_REPO_LOCAL" ] && [ -d /var/jenkins_home/.m2/repository ]; then
MAVEN_REPO_LOCAL="/var/jenkins_home/.m2/repository"
fi
MAVEN_CMD=(mvn)
if [ -n "$MAVEN_SETTINGS" ]; then
MAVEN_CMD+=(--settings "$MAVEN_SETTINGS")
fi
if [ -n "$MAVEN_REPO_LOCAL" ]; then
MAVEN_CMD+=("-Dmaven.repo.local=$MAVEN_REPO_LOCAL")
fi
INT_TMPDIR=$(mktemp -d)
trap 'rm -rf "$INT_TMPDIR"' EXIT
echo "==> [0/4] 同步并安装 int-api(${INT_BRANCH})..."
git clone --branch "$INT_BRANCH" --single-branch "$INT_REPO" "$INT_TMPDIR" -q
INT_COMMIT=$(git -C "$INT_TMPDIR" rev-parse HEAD)
echo " int-api 源码版本: $INT_COMMIT"
(
cd "$INT_TMPDIR"
"${MAVEN_CMD[@]}" clean install -DskipTests -pl int-api -am -q
)
echo "==> [1/4] 构建 JAR..."
"${MAVEN_CMD[@]}" clean package -DskipTests -pl mes-app -am -q
LOCAL_JAR="${ROOT}/mes-app/target/${JAR_NAME}"
COMMIT=$(git rev-parse HEAD)
SHA=$(sha256sum "$LOCAL_JAR" | awk '{print $1}')
echo " 完成: ${LOCAL_JAR} ($(du -sh "$LOCAL_JAR" | cut -f1)) sha256=${SHA} commit=${COMMIT}"
echo "==> [2/4] 上传 JAR 到 110..."
POD=$(ssh_hm "kubectl -n ${HM_NS} get po -l ${HM_LABEL} -o jsonpath='{.items[0].metadata.name}'")
if [ -z "$POD" ]; then
echo "ERROR: 110 上找不到 ${HM_LABEL} 的 Pod" >&2
exit 1
fi
scp -o BatchMode=yes "$LOCAL_JAR" "${HM_SSH}:/tmp/${JAR_NAME}"
echo " Pod=${POD}"
echo "==> [3/4] 写入运行中的容器并 commit 节点本地镜像..."
ssh_hm "POD='${POD}' NS='${HM_NS}' CONTAINER='${HM_CONTAINER}' JAR_NAME='${JAR_NAME}' COMMIT='${COMMIT}' SHA='${SHA}' bash -s" <<'REMOTE'
set -euo pipefail
NODE=$(kubectl -n "$NS" get po "$POD" -o jsonpath='{.spec.nodeName}')
IMAGE=$(kubectl -n "$NS" get po "$POD" -o jsonpath="{.status.containerStatuses[?(@.name==\"${CONTAINER}\")].image}")
CID=$(kubectl -n "$NS" get po "$POD" -o jsonpath="{.status.containerStatuses[?(@.name==\"${CONTAINER}\")].containerID}")
CID=${CID#docker://}
if [ -z "$NODE" ] || [ -z "$IMAGE" ] || [ -z "$CID" ]; then
echo "ERROR: 无法解析 Pod 节点/镜像/容器" >&2
exit 1
fi
echo " node=${NODE}"
echo " image=${IMAGE}"
echo " cid=${CID}"
kubectl -n "$NS" cp "/tmp/${JAR_NAME}" "${POD}:/app/${JAR_NAME}" -c "$CONTAINER"
kubectl -n "$NS" exec "$POD" -c "$CONTAINER" -- sh -c "printf '%s\n' '$COMMIT' > /app/.release-version"
DEBUG_OUT=$(kubectl debug "node/${NODE}" --image="$IMAGE" --profile=general -- sleep 180)
echo "$DEBUG_OUT"
DEBUG_POD=$(printf '%s\n' "$DEBUG_OUT" | sed -n 's/.*debugging pod \([^ ]*\).*/\1/p' | tail -1)
DEBUG_POD=${DEBUG_POD##*/}
if [ -z "$DEBUG_POD" ]; then
echo "ERROR: 未找到 node debug Pod" >&2
exit 1
fi
kubectl -n default wait --for=condition=Ready "po/${DEBUG_POD}" --timeout=60s
cleanup() { kubectl -n default delete po "$DEBUG_POD" --wait=false >/dev/null 2>&1 || true; }
trap cleanup EXIT
echo " debug=${DEBUG_POD}"
kubectl -n default exec "$DEBUG_POD" -- sh -c "chroot /host docker commit ${CID} ${IMAGE}"
echo " docker commit 完成"
echo "==> [4/4] 重启容器(同 Pod,不删 Pod)..."
kubectl -n "$NS" exec "$POD" -c "$CONTAINER" -- kill 1 || true
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18; do
if kubectl -n "$NS" exec "$POD" -c "$CONTAINER" -- sh -c "test -f /app/${JAR_NAME} && cat /app/.release-version" >/tmp/hm-rel 2>/dev/null; then
break
fi
sleep 5
done
kubectl -n "$NS" wait --for=condition=Ready "po/${POD}" --timeout=180s
REMOTE_COMMIT=$(kubectl -n "$NS" exec "$POD" -c "$CONTAINER" -- cat /app/.release-version)
REMOTE_SHA=$(kubectl -n "$NS" exec "$POD" -c "$CONTAINER" -- sha256sum "/app/${JAR_NAME}" | awk '{print $1}')
if [ "$REMOTE_COMMIT" != "$COMMIT" ] || [ "$REMOTE_SHA" != "$SHA" ]; then
echo "ERROR: 校验失败 commit=${REMOTE_COMMIT} sha=${REMOTE_SHA}" >&2
exit 1
fi
echo " 校验通过 commit=${REMOTE_COMMIT} sha=${REMOTE_SHA}"
REMOTE
echo ""
echo "110 MES 已更新: ${COMMIT}"
echo " Pod: ${POD}"
echo " JAR: ${JAR_NAME} sha256=${SHA}"