ci deploy (src cf7b53d)
This commit is contained in:
93
vps-sync.sh
Normal file
93
vps-sync.sh
Normal file
@ -0,0 +1,93 @@
|
||||
#!/bin/sh
|
||||
# VPS 侧发版拉取:从产物仓取最新构建,二进制有变化才重启服务。
|
||||
# 由 sgame-admin-sync.timer 每分钟触发(见 deploy/vps-README.md)。
|
||||
#
|
||||
# 关键约束:产物仓托管在 NAS 的 Gitea 上,而 NAS 每晚 23 点关机、偶尔断网。
|
||||
# 因此拉取失败一律视为「本次没有新版本」——静默保持现状继续跑,
|
||||
# 绝不因为拉不到而重启或停服。线上可用性不依赖 NAS 在线。
|
||||
set -u
|
||||
|
||||
APP_DIR=/opt/sgame-admin
|
||||
REPO_DIR="$APP_DIR/repo"
|
||||
REPO_URL=https://git.xindiegaming.top/bia/sgame-admin-deploy.git
|
||||
# git 操作的硬超时:NAS 不可达时 TCP 可能挂很久,绝不能让 timer 堆积
|
||||
GIT_TIMEOUT=60
|
||||
|
||||
log() { echo "sgame-admin-sync: $*"; }
|
||||
|
||||
# 1) 取最新产物。任何失败都直接退出 0(= 没有新版本可发)
|
||||
#
|
||||
# 注意:目标机是 CentOS 7,git 1.8.3.1 不支持 `git -C <dir>`,只能子 shell 里 cd。
|
||||
if [ -d "$REPO_DIR/.git" ]; then
|
||||
(cd "$REPO_DIR" && timeout "$GIT_TIMEOUT" git fetch --depth 1 origin main >/dev/null 2>&1) || {
|
||||
log "产物仓不可达(NAS 可能已关机),保持当前版本运行"
|
||||
exit 0
|
||||
}
|
||||
# 必须 reset 到 FETCH_HEAD 而不是 origin/main:git 1.8.3 在 `git fetch
|
||||
# origin <branch>` 这种简写下只写 FETCH_HEAD,不会顺带更新
|
||||
# refs/remotes/origin/main。reset 到 origin/main 等于原地不动,
|
||||
# 结果是"每次都检测到差异、每次都把旧产物装回去"。
|
||||
(cd "$REPO_DIR" && timeout "$GIT_TIMEOUT" git reset --hard FETCH_HEAD >/dev/null 2>&1) || {
|
||||
log "reset 失败,保持当前版本运行"
|
||||
exit 0
|
||||
}
|
||||
else
|
||||
timeout "$GIT_TIMEOUT" git clone --depth 1 "$REPO_URL" "$REPO_DIR" >/dev/null 2>&1 || {
|
||||
log "首次 clone 失败(NAS 可能已关机),稍后重试"
|
||||
exit 0
|
||||
}
|
||||
fi
|
||||
|
||||
NEW_BIN="$REPO_DIR/server"
|
||||
CUR_BIN="$APP_DIR/server"
|
||||
|
||||
if [ ! -f "$NEW_BIN" ]; then
|
||||
log "产物仓里没有 server 二进制,跳过"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 2) 内容比对:只有真的变了才重启(timer 每分钟跑,不能每次都重启)
|
||||
NEW_SUM=$(md5sum "$NEW_BIN" | awk '{print $1}')
|
||||
CUR_SUM=$(md5sum "$CUR_BIN" 2>/dev/null | awk '{print $1}')
|
||||
if [ "$NEW_SUM" = "$CUR_SUM" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
log "检测到新版本 ($CUR_SUM -> $NEW_SUM),开始更新"
|
||||
|
||||
# 3) 就地替换 + 重启。二进制和 config.yaml 都留一份上一版,
|
||||
# 否则回滚只换回二进制、却留着新版 config,配出个没验证过的组合。
|
||||
cp -f "$CUR_BIN" "$APP_DIR/server.prev" 2>/dev/null || true
|
||||
cp -f "$APP_DIR/config.yaml" "$APP_DIR/config.yaml.prev" 2>/dev/null || true
|
||||
install -m 0755 -o sgame -g sgame "$NEW_BIN" "$CUR_BIN" || {
|
||||
log "替换二进制失败,保持当前版本运行"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# config.yaml 跟着产物走;密钥不在其中(走 EnvironmentFile)
|
||||
if [ -f "$REPO_DIR/config.yaml" ]; then
|
||||
install -m 0644 -o sgame -g sgame "$REPO_DIR/config.yaml" "$APP_DIR/config.yaml"
|
||||
fi
|
||||
|
||||
systemctl restart sgame-admin
|
||||
|
||||
# 4) 起不来就自动回滚,避免一次坏发版把线上撂倒一整夜
|
||||
sleep 3
|
||||
for i in 1 2 3 4 5; do
|
||||
if curl -fsS --max-time 3 http://127.0.0.1:8090/health >/dev/null 2>&1; then
|
||||
log "更新完成,健康检查通过"
|
||||
exit 0
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
log "新版本健康检查失败,回滚到上一版"
|
||||
if [ -f "$APP_DIR/server.prev" ]; then
|
||||
install -m 0755 -o sgame -g sgame "$APP_DIR/server.prev" "$CUR_BIN"
|
||||
if [ -f "$APP_DIR/config.yaml.prev" ]; then
|
||||
install -m 0644 -o sgame -g sgame "$APP_DIR/config.yaml.prev" "$APP_DIR/config.yaml"
|
||||
fi
|
||||
systemctl restart sgame-admin
|
||||
log "已回滚(二进制 + config.yaml)"
|
||||
fi
|
||||
exit 1
|
||||
Reference in New Issue
Block a user