258 lines
7.2 KiB
Bash
Executable File
258 lines
7.2 KiB
Bash
Executable File
#!/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_PROXIES="${REMOTE_BASE}/cmd/proxies.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 golang}"
|
||
|
||
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/status(deploy 也会 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 proxies_json="${WALLETMAN_DIR}/cmd/proxies.json"
|
||
local fcm_config="${WALLETMAN_DIR}/cmd/server/config/fcm-service-account.json"
|
||
[[ -f "${wallets_json}" ]] || die "缺少 ${wallets_json}"
|
||
[[ -f "${proxies_json}" ]] || die "缺少 ${proxies_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 "${proxies_json}" "${staging}/cmd/proxies.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_PROXIES="${REMOTE_PROXIES}"
|
||
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 cmd/proxies.json "\${REMOTE_PROXIES}"
|
||
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}"
|
||
log "proxies.json → ${REMOTE_PROXIES}"
|
||
}
|
||
|
||
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 "$@"
|