部署脚本

This commit is contained in:
2026-06-17 11:42:27 +08:00
parent ae6da23f6c
commit 13fffa1460
+250
View File
@@ -0,0 +1,250 @@
#!/usr/bin/env bash
# walletman 远程管理:deploy / start / stop / restart / status
# 用法: ./wm.sh deploy|start|stop|restart|status
set -euo pipefail
JUMP_HOST="${JUMP_HOST:-ipay-jump}"
TARGET_HOST="${TARGET_HOST:-ipay-test}"
REMOTE_BASE="${REMOTE_BASE:-/home/ec2-user/walletman}"
REMOTE_BIN_DIR="${REMOTE_BASE}/cmd/server"
REMOTE_BIN="${REMOTE_BIN_DIR}/ipay.bin"
REMOTE_WALLETS="${REMOTE_BASE}/cmd/wallets.json"
REMOTE_FCM_CONFIG="${REMOTE_BIN_DIR}/config/fcm-service-account.json"
REMOTE_LOG="${REMOTE_BASE}/walletman.log"
REMOTE_PID="${REMOTE_BASE}/walletman.pid"
GO_TLS_FLAG="${GO_TLS_FLAG:--tls android}"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WALLETMAN_DIR="$(cd "${SCRIPT_DIR}/../walletman" && pwd)"
log() { printf '\033[1;32m[wm]\033[0m %s\n' "$*"; }
warn() { printf '\033[1;33m[wm]\033[0m %s\n' "$*"; }
die() { printf '\033[1;31m[wm]\033[0m %s\n' "$*" >&2; exit 1; }
ssh_jump() {
ssh -o ClearAllForwardings=yes -o BatchMode=yes "${JUMP_HOST}" "$@"
}
ssh_target() {
ssh_jump ssh -o BatchMode=yes "${TARGET_HOST}" "$@"
}
remote_script() {
ssh_target bash -s
}
# 远端 start/stop/statusdeploy 也会 source 这段逻辑)
run_remote_ctl() {
local action="$1"
local check_health="${2:-0}"
remote_script <<EOF
set -euo pipefail
REMOTE_BIN_DIR="${REMOTE_BIN_DIR}"
REMOTE_BIN="${REMOTE_BIN}"
REMOTE_LOG="${REMOTE_LOG}"
REMOTE_PID="${REMOTE_PID}"
GO_TLS_FLAG="${GO_TLS_FLAG}"
ACTION="${action}"
CHECK_HEALTH="${check_health}"
stop_walletman() {
if [[ -f "\${REMOTE_PID}" ]]; then
old_pid=\$(cat "\${REMOTE_PID}" 2>/dev/null || true)
if [[ -n "\${old_pid}" ]] && kill -0 "\${old_pid}" 2>/dev/null; then
echo "stop pid=\${old_pid}"
kill "\${old_pid}" || true
sleep 1
kill -9 "\${old_pid}" 2>/dev/null || true
fi
rm -f "\${REMOTE_PID}"
fi
if pkill -f "\${REMOTE_BIN}" 2>/dev/null; then
echo "stop pkill \${REMOTE_BIN}"
sleep 1
fi
}
start_walletman() {
if [[ ! -x "\${REMOTE_BIN}" ]]; then
echo "binary not found: \${REMOTE_BIN}" >&2
exit 1
fi
cd "\${REMOTE_BIN_DIR}"
nohup "\${REMOTE_BIN}" \${GO_TLS_FLAG} >> "\${REMOTE_LOG}" 2>&1 &
echo \$! > "\${REMOTE_PID}"
echo "started pid=\$(cat "\${REMOTE_PID}")"
}
status_walletman() {
if [[ -f "\${REMOTE_PID}" ]]; then
pid=\$(cat "\${REMOTE_PID}" 2>/dev/null || true)
if [[ -n "\${pid}" ]] && kill -0 "\${pid}" 2>/dev/null; then
echo "running pid=\${pid}"
else
echo "not running (stale pid file)"
fi
else
echo "not running"
fi
if curl -sf --max-time 5 http://127.0.0.1:16000/wallets >/dev/null; then
echo "health ok"
else
echo "health fail"
exit 1
fi
}
case "\${ACTION}" in
stop) stop_walletman ;;
start)
stop_walletman
start_walletman
sleep 2
;;
restart)
stop_walletman
start_walletman
sleep 2
;;
status) status_walletman; exit 0 ;;
*) echo "unknown action \${ACTION}" >&2; exit 1 ;;
esac
if [[ "\${CHECK_HEALTH}" == "1" ]]; then
if curl -sf --max-time 5 http://127.0.0.1:16000/wallets >/dev/null; then
echo "health ok: http://127.0.0.1:16000/wallets"
else
echo "health check failed, tail log:" >&2
tail -n 30 "\${REMOTE_LOG}" >&2 || true
exit 1
fi
fi
EOF
}
cmd_start() {
log "start ${TARGET_HOST}"
run_remote_ctl start 1
}
cmd_stop() {
log "stop ${TARGET_HOST}"
run_remote_ctl stop 0
log "已停止"
}
cmd_restart() {
log "restart ${TARGET_HOST}"
run_remote_ctl restart 1
}
cmd_status() {
log "status ${TARGET_HOST}"
run_remote_ctl status
}
cmd_deploy() {
local build_dir staging tarball
build_dir="$(mktemp -d)"
staging="${build_dir}/staging"
tarball="${build_dir}/walletman-deploy.tgz"
trap 'rm -rf "${build_dir}"' EXIT
local wallets_json="${WALLETMAN_DIR}/cmd/wallets.json"
local fcm_config="${WALLETMAN_DIR}/cmd/server/config/fcm-service-account.json"
[[ -f "${wallets_json}" ]] || die "缺少 ${wallets_json}"
[[ -f "${fcm_config}" ]] || die "缺少 ${fcm_config}"
log "构建 linux/amd64 二进制..."
mkdir -p "${staging}/bin" "${staging}/test" "${staging}/cmd" "${staging}/config"
(
cd "${WALLETMAN_DIR}"
GOOS=linux GOARCH=amd64 go build -buildvcs=false -ldflags="-s -w" -o "${staging}/bin/ipay.bin" ./cmd/server
)
cp -R "${WALLETMAN_DIR}/test/." "${staging}/test/"
cp "${wallets_json}" "${staging}/cmd/wallets.json"
cp "${fcm_config}" "${staging}/config/fcm-service-account.json"
if [[ "$(uname -s)" == Darwin ]]; then
xattr -cr "${staging}" 2>/dev/null || true
fi
log "打包..."
if [[ "$(uname -s)" == Darwin ]]; then
COPYFILE_DISABLE=1 tar --no-xattrs -czf "${tarball}" -C "${staging}" bin test cmd config 2>/dev/null \
|| COPYFILE_DISABLE=1 tar -czf "${tarball}" -C "${staging}" bin test cmd config
else
tar czf "${tarball}" -C "${staging}" bin test cmd config
fi
log "上传到 ${JUMP_HOST}..."
scp -o ClearAllForwardings=yes "${tarball}" "${JUMP_HOST}:/tmp/walletman-deploy.tgz"
ssh_jump scp "/tmp/walletman-deploy.tgz" "${TARGET_HOST}:/tmp/walletman-deploy.tgz"
log "分发到 ${TARGET_HOST}:${REMOTE_BASE} ..."
remote_script <<EOF
set -euo pipefail
REMOTE_BASE="${REMOTE_BASE}"
REMOTE_BIN_DIR="${REMOTE_BIN_DIR}"
REMOTE_BIN="${REMOTE_BIN}"
REMOTE_WALLETS="${REMOTE_WALLETS}"
REMOTE_FCM_CONFIG="${REMOTE_FCM_CONFIG}"
mkdir -p "\${REMOTE_BIN_DIR}" "\${REMOTE_BASE}/cmd" "\${REMOTE_BASE}/test" "\${REMOTE_BIN_DIR}/config"
cd /tmp
tar --warning=no-unknown-keyword -xzf walletman-deploy.tgz 2>/dev/null \
|| tar xzf walletman-deploy.tgz 2>/dev/null \
|| tar xzf walletman-deploy.tgz
rm -f walletman-deploy.tgz
if [[ -f "\${REMOTE_BIN}" ]]; then
cp "\${REMOTE_BIN}" "\${REMOTE_BIN}.bak.\$(date +%Y%m%d%H%M%S)"
fi
install -m 755 bin/ipay.bin "\${REMOTE_BIN}"
rsync -a test/ "\${REMOTE_BASE}/test/"
ln -sfn ../../test "\${REMOTE_BIN_DIR}/test"
if [[ -f "\${REMOTE_WALLETS}" ]]; then
cp "\${REMOTE_WALLETS}" "\${REMOTE_WALLETS}.bak.\$(date +%Y%m%d%H%M%S)"
fi
install -m 644 cmd/wallets.json "\${REMOTE_WALLETS}"
install -m 600 config/fcm-service-account.json "\${REMOTE_FCM_CONFIG}"
rm -f "\${REMOTE_BIN_DIR}/wallets.json"
EOF
ssh_jump rm -f /tmp/walletman-deploy.tgz
log "文件已更新,重启服务..."
run_remote_ctl restart 1
log "部署完成: ${TARGET_HOST}:${REMOTE_BIN}"
log "wallets.json → ${REMOTE_WALLETS}"
log "fcm config → ${REMOTE_FCM_CONFIG}"
}
usage() {
cat <<EOF
用法: $(basename "$0") <command>
deploy 构建并部署到 ${TARGET_HOST},然后 restart
start 启动远端 walletman
stop 停止远端 walletman
restart 重启远端 walletman
status 查看进程与健康检查
环境变量: JUMP_HOST TARGET_HOST REMOTE_BASE GO_TLS_FLAG
EOF
}
main() {
local cmd="${1:-}"
case "${cmd}" in
deploy|--deploy) cmd_deploy ;;
start|--start) cmd_start ;;
stop|--stop) cmd_stop ;;
restart|--restart) cmd_restart ;;
status|--status) cmd_status ;;
-h|--help|help|"") usage ;;
*) die "未知命令: ${cmd}(见 --help" ;;
esac
}
main "$@"