157 lines
5.2 KiB
Bash
157 lines
5.2 KiB
Bash
|
|
#!/usr/bin/env bash
|
|||
|
|
# datahub 更新脚本:git pull + 智能重建 + 滚动重启
|
|||
|
|
#
|
|||
|
|
# 用法:bash update.sh [选项]
|
|||
|
|
# --force-rebuild 不看 git diff,强制重建所有镜像
|
|||
|
|
# --skip-migrate 检测到新迁移时不提示,直接跳过
|
|||
|
|
|
|||
|
|
set -euo pipefail
|
|||
|
|
|
|||
|
|
B='\033[34m'; G='\033[32m'; Y='\033[33m'; R='\033[31m'; N='\033[0m'
|
|||
|
|
step() { echo -e "\n${B}=> $*${N}"; }
|
|||
|
|
ok() { echo -e "${G}[OK]${N} $*"; }
|
|||
|
|
warn() { echo -e "${Y}[!]${N} $*"; }
|
|||
|
|
err() { echo -e "${R}[ERR]${N} $*" >&2; }
|
|||
|
|
|
|||
|
|
FORCE_REBUILD=false
|
|||
|
|
SKIP_MIGRATE=false
|
|||
|
|
for arg in "$@"; do
|
|||
|
|
case "$arg" in
|
|||
|
|
--force-rebuild) FORCE_REBUILD=true ;;
|
|||
|
|
--skip-migrate) SKIP_MIGRATE=true ;;
|
|||
|
|
-h|--help)
|
|||
|
|
sed -n '2,7p' "$0"
|
|||
|
|
exit 0
|
|||
|
|
;;
|
|||
|
|
*) echo "未知参数: $arg" >&2; exit 1 ;;
|
|||
|
|
esac
|
|||
|
|
done
|
|||
|
|
|
|||
|
|
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
|||
|
|
REPO_ROOT=$(cd "$SCRIPT_DIR/../../.." && pwd)
|
|||
|
|
QUADLET_DIR="$HOME/.config/containers/systemd"
|
|||
|
|
|
|||
|
|
cd "$REPO_ROOT"
|
|||
|
|
|
|||
|
|
# 1. 必须是 git 仓库且工作区干净
|
|||
|
|
if [ ! -d .git ]; then
|
|||
|
|
err "$REPO_ROOT 不是 git 仓库"
|
|||
|
|
exit 1
|
|||
|
|
fi
|
|||
|
|
if ! git diff --quiet || ! git diff --cached --quiet; then
|
|||
|
|
err "工作区有未提交的变更,先 stash 或 commit"
|
|||
|
|
git status --short
|
|||
|
|
exit 1
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 2. git pull
|
|||
|
|
step "git pull"
|
|||
|
|
OLD_HEAD=$(git rev-parse HEAD)
|
|||
|
|
git pull --ff-only
|
|||
|
|
NEW_HEAD=$(git rev-parse HEAD)
|
|||
|
|
|
|||
|
|
if [ "$OLD_HEAD" = "$NEW_HEAD" ] && [ "$FORCE_REBUILD" = false ]; then
|
|||
|
|
ok "代码已是最新,无需更新(如需强制重建请加 --force-rebuild)"
|
|||
|
|
exit 0
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 3. 检测变更范围
|
|||
|
|
if [ "$FORCE_REBUILD" = true ]; then
|
|||
|
|
CH_BACKEND=true; CH_FRONTEND=true; CH_QUADLET=true
|
|||
|
|
CH_PG_IMAGE=true; CH_MIGRATIONS=true
|
|||
|
|
warn "强制重建:忽略 git diff"
|
|||
|
|
else
|
|||
|
|
DIFF=$(git diff --name-only "$OLD_HEAD" "$NEW_HEAD")
|
|||
|
|
matches() { echo "$DIFF" | grep -qE "$1"; }
|
|||
|
|
|
|||
|
|
CH_BACKEND=$(matches '^backend/' && echo true || echo false)
|
|||
|
|
CH_FRONTEND=$(matches '^(frontend/|deploy/podman/images/frontend/)' && echo true || echo false)
|
|||
|
|
CH_QUADLET=$(matches '^deploy/podman/quadlet/' && echo true || echo false)
|
|||
|
|
CH_PG_IMAGE=$(matches '^deploy/podman/images/postgres/' && echo true || echo false)
|
|||
|
|
CH_MIGRATIONS=$(matches '^backend/migrations/' && echo true || echo false)
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
echo
|
|||
|
|
echo "变更检测:"
|
|||
|
|
printf " %-20s %s\n" "backend image:" "$CH_BACKEND"
|
|||
|
|
printf " %-20s %s\n" "frontend image:" "$CH_FRONTEND"
|
|||
|
|
printf " %-20s %s\n" "postgres image:" "$CH_PG_IMAGE"
|
|||
|
|
printf " %-20s %s\n" "quadlet files:" "$CH_QUADLET"
|
|||
|
|
printf " %-20s %s\n" "migrations:" "$CH_MIGRATIONS"
|
|||
|
|
|
|||
|
|
# 4. 重建镜像
|
|||
|
|
if [ "$CH_PG_IMAGE" = "true" ]; then
|
|||
|
|
step "重建 postgres 镜像"
|
|||
|
|
podman build -t localhost/datahub-postgres:latest \
|
|||
|
|
-f deploy/podman/images/postgres/Dockerfile .
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
if [ "$CH_BACKEND" = "true" ]; then
|
|||
|
|
step "重建 backend 镜像"
|
|||
|
|
podman build -t localhost/datahub-backend:latest \
|
|||
|
|
-f backend/Dockerfile backend/
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
if [ "$CH_FRONTEND" = "true" ]; then
|
|||
|
|
step "重建 frontend 镜像"
|
|||
|
|
podman build -t localhost/datahub-frontend:latest \
|
|||
|
|
-f deploy/podman/images/frontend/Dockerfile .
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 5. 同步 Quadlet(任何 quadlet 改动或强制时)
|
|||
|
|
if [ "$CH_QUADLET" = "true" ] || [ "$FORCE_REBUILD" = true ]; then
|
|||
|
|
step "同步 Quadlet 单元"
|
|||
|
|
cp deploy/podman/quadlet/* "$QUADLET_DIR/"
|
|||
|
|
systemctl --user daemon-reload
|
|||
|
|
ok "Quadlet 已更新"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 6. 滚动重启受影响的服务
|
|||
|
|
step "重启受影响的服务"
|
|||
|
|
restart_svc() {
|
|||
|
|
local svc=$1
|
|||
|
|
echo " 重启 $svc.service"
|
|||
|
|
systemctl --user restart "$svc.service"
|
|||
|
|
sleep 2
|
|||
|
|
if ! systemctl --user is-active --quiet "$svc.service"; then
|
|||
|
|
err "$svc 重启失败"
|
|||
|
|
journalctl --user -u "$svc.service" -n 40 --no-pager
|
|||
|
|
exit 1
|
|||
|
|
fi
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[ "$CH_PG_IMAGE" = "true" ] && restart_svc datahub-postgres
|
|||
|
|
[ "$CH_BACKEND" = "true" ] && restart_svc datahub-backend
|
|||
|
|
[ "$CH_FRONTEND" = "true" ] && restart_svc datahub-frontend
|
|||
|
|
|
|||
|
|
# Quadlet 改了但镜像没改时,仍需重启对应服务
|
|||
|
|
if [ "$CH_QUADLET" = "true" ]; then
|
|||
|
|
DIFF_Q=$(git diff --name-only "$OLD_HEAD" "$NEW_HEAD" -- deploy/podman/quadlet/ 2>/dev/null || true)
|
|||
|
|
[ "$CH_PG_IMAGE" = "false" ] && echo "$DIFF_Q" | grep -q "datahub-postgres" && restart_svc datahub-postgres
|
|||
|
|
[ "$CH_BACKEND" = "false" ] && echo "$DIFF_Q" | grep -q "datahub-backend" && restart_svc datahub-backend
|
|||
|
|
[ "$CH_FRONTEND" = "false" ] && echo "$DIFF_Q" | grep -q "datahub-frontend" && restart_svc datahub-frontend
|
|||
|
|
echo "$DIFF_Q" | grep -q "datahub-rabbitmq" && restart_svc datahub-rabbitmq
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 7. 迁移提示
|
|||
|
|
if [ "$CH_MIGRATIONS" = "true" ] && [ "$SKIP_MIGRATE" = false ]; then
|
|||
|
|
echo
|
|||
|
|
warn "检测到新迁移文件:"
|
|||
|
|
git diff --name-only "$OLD_HEAD" "$NEW_HEAD" -- backend/migrations/ | sed 's/^/ /'
|
|||
|
|
read -rp "立即执行迁移?(Y/n): " ans
|
|||
|
|
ans="${ans,,}"
|
|||
|
|
if [[ -z "$ans" || "$ans" == "y" ]]; then
|
|||
|
|
podman exec -it datahub-backend php bin/hyperf.php migrate
|
|||
|
|
ok "迁移完成"
|
|||
|
|
else
|
|||
|
|
warn "跳过。后续可手动执行:podman exec -it datahub-backend php bin/hyperf.php migrate"
|
|||
|
|
fi
|
|||
|
|
elif [ "$CH_MIGRATIONS" = "true" ]; then
|
|||
|
|
warn "检测到新迁移但已 --skip-migrate,请手动执行"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
echo
|
|||
|
|
ok "更新完成"
|
|||
|
|
echo " $OLD_HEAD"
|
|||
|
|
echo " → $NEW_HEAD"
|