Add curl|bash manage.sh with deploy/uninstall/update menu.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -21,17 +21,23 @@
|
||||
服务器目录:`/opt/eth_hedge_sim`
|
||||
更新方式:**只允许 `git pull`**,然后构建并 `pm2 startOrReload` 本项目进程。
|
||||
|
||||
### 服务器上
|
||||
### 推荐:curl 一键管理器(菜单)
|
||||
|
||||
```bash
|
||||
# 首次
|
||||
export REPO_URL=https://git.bz121.com/dekun/eth_hedge_sim.git
|
||||
bash /opt/eth_hedge_sim/deploy/bootstrap.sh
|
||||
# 若尚未 clone:
|
||||
# git clone "$REPO_URL" /opt/eth_hedge_sim && bash /opt/eth_hedge_sim/deploy/bootstrap.sh
|
||||
curl -fsSL https://git.bz121.com/dekun/eth_hedge_sim/raw/branch/main/deploy/manage.sh | bash
|
||||
```
|
||||
|
||||
# 日常更新
|
||||
bash /opt/eth_hedge_sim/deploy/pull_and_restart.sh
|
||||
菜单:
|
||||
|
||||
1. 一键部署
|
||||
2. 一键卸载(仅停删 `eth-hedge-api`,移走目录并备份 `.env`)
|
||||
3. 更新(`git pull` + 构建 + reload)
|
||||
0. 退出
|
||||
|
||||
已安装后也可:
|
||||
|
||||
```bash
|
||||
bash /opt/eth_hedge_sim/deploy/manage.sh
|
||||
```
|
||||
|
||||
### 本机触发远程更新
|
||||
|
||||
Regular → Executable
+4
-11
@@ -1,13 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
# 首次安装到 /opt/eth_hedge_sim(仅 git clone,后续一律 git pull)
|
||||
# 兼容入口:转发到 manage.sh(推荐 curl | bash)
|
||||
# curl -fsSL https://git.bz121.com/dekun/eth_hedge_sim/raw/branch/main/deploy/manage.sh | bash
|
||||
set -euo pipefail
|
||||
|
||||
REPO_URL="${REPO_URL:-https://git.bz121.com/dekun/eth_hedge_sim.git}"
|
||||
ROOT="${INSTALL_ROOT:-/opt/eth_hedge_sim}"
|
||||
|
||||
if [[ ! -d "$ROOT/.git" ]]; then
|
||||
mkdir -p "$(dirname "$ROOT")"
|
||||
git clone "$REPO_URL" "$ROOT"
|
||||
fi
|
||||
|
||||
bash "$ROOT/deploy/pull_and_restart.sh"
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
exec bash "${ROOT}/deploy/manage.sh" "$@"
|
||||
|
||||
Executable
+155
@@ -0,0 +1,155 @@
|
||||
#!/usr/bin/env bash
|
||||
# deploy/lib/common.sh — eth_hedge_sim 部署公共函数
|
||||
set -e
|
||||
set -u
|
||||
if [ -n "${BASH_VERSION:-}" ]; then
|
||||
set -o pipefail
|
||||
fi
|
||||
|
||||
INSTALL_ROOT="${INSTALL_ROOT:-/opt/eth_hedge_sim}"
|
||||
GIT_URL="${GIT_URL:-https://git.bz121.com/dekun/eth_hedge_sim.git}"
|
||||
GIT_BRANCH="${GIT_BRANCH:-main}"
|
||||
BACKUP_ROOT="${BACKUP_ROOT:-/root/backups/eth_hedge_sim}"
|
||||
TZ_NAME="${EHS_TZ:-Asia/Shanghai}"
|
||||
NODE_MAJOR="${NODE_MAJOR:-20}"
|
||||
PM2_APP_NAME="${PM2_APP_NAME:-eth-hedge-api}"
|
||||
API_PORT="${API_PORT:-5155}"
|
||||
|
||||
LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
DEPLOY_DIR="$(cd "${LIB_DIR}/.." && pwd)"
|
||||
REPO_ROOT="$(cd "${DEPLOY_DIR}/.." && pwd)"
|
||||
|
||||
log() { printf '[%s] %s\n' "$(TZ="${TZ_NAME}" date '+%Y-%m-%d %H:%M:%S')" "$*"; }
|
||||
step() { echo ""; log "==> $*"; }
|
||||
|
||||
die() {
|
||||
echo "错误: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
require_root() {
|
||||
if [[ "$(id -u)" -ne 0 ]]; then
|
||||
die "请使用 root 执行(推荐: sudo -i 后运行)"
|
||||
fi
|
||||
}
|
||||
|
||||
detect_server_ip() {
|
||||
local ip=""
|
||||
if command -v hostname >/dev/null 2>&1; then
|
||||
ip="$(hostname -I 2>/dev/null | awk '{print $1}')"
|
||||
fi
|
||||
if [[ -z "${ip}" ]]; then
|
||||
ip="127.0.0.1"
|
||||
fi
|
||||
echo "${ip}"
|
||||
}
|
||||
|
||||
# curl|bash 时 stdin 可能是管道,交互从 /dev/tty 读
|
||||
cm_read() {
|
||||
local __var="$1"
|
||||
local __prompt="${2:-}"
|
||||
local __line=""
|
||||
if [[ -n "${__prompt}" ]]; then
|
||||
printf '%s' "${__prompt}" >/dev/tty 2>/dev/null || printf '%s' "${__prompt}"
|
||||
fi
|
||||
if [[ -r /dev/tty ]]; then
|
||||
IFS= read -r __line </dev/tty || true
|
||||
else
|
||||
IFS= read -r __line || true
|
||||
fi
|
||||
printf -v "${__var}" '%s' "${__line}"
|
||||
}
|
||||
|
||||
confirm_yes() {
|
||||
local msg="$1"
|
||||
local ans=""
|
||||
cm_read ans "${msg} [y/N] "
|
||||
[[ "${ans}" == [yY] || "${ans}" == [yY][eE][sS] ]]
|
||||
}
|
||||
|
||||
repo_ready() {
|
||||
[[ -f "${1}/deploy/manage.sh" && -f "${1}/deploy/pull_and_restart.sh" ]]
|
||||
}
|
||||
|
||||
resolve_repo_root() {
|
||||
if repo_ready "${INSTALL_ROOT}"; then
|
||||
echo "${INSTALL_ROOT}"
|
||||
return 0
|
||||
fi
|
||||
if [[ -n "${REPO_ROOT:-}" ]] && repo_ready "${REPO_ROOT}"; then
|
||||
echo "${REPO_ROOT}"
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
ensure_system_deps() {
|
||||
step "检查系统依赖"
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
if command -v apt-get >/dev/null 2>&1; then
|
||||
apt-get update -qq
|
||||
apt-get install -y git ca-certificates curl python3 python3-venv python3-pip
|
||||
fi
|
||||
if ! command -v node >/dev/null 2>&1; then
|
||||
step "安装 Node.js ${NODE_MAJOR}"
|
||||
curl -fsSL "https://deb.nodesource.com/setup_${NODE_MAJOR}.x" | bash -
|
||||
apt-get install -y nodejs
|
||||
fi
|
||||
if ! command -v pm2 >/dev/null 2>&1; then
|
||||
step "安装 PM2"
|
||||
npm install -g pm2
|
||||
fi
|
||||
}
|
||||
|
||||
pm2_stop_project() {
|
||||
if command -v pm2 >/dev/null 2>&1; then
|
||||
pm2 stop "${PM2_APP_NAME}" 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
pm2_delete_project() {
|
||||
if command -v pm2 >/dev/null 2>&1; then
|
||||
pm2 delete "${PM2_APP_NAME}" 2>/dev/null || true
|
||||
pm2 save 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
pm2_save_startup() {
|
||||
if command -v pm2 >/dev/null 2>&1; then
|
||||
pm2 save 2>/dev/null || true
|
||||
pm2 startup systemd -u root --hp /root 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
verify_health() {
|
||||
local port="${1:-${API_PORT}}"
|
||||
local url="http://127.0.0.1:${port}/health"
|
||||
step "健康检查 ${url}"
|
||||
local i
|
||||
for i in 1 2 3 4 5 6 7 8 9 10; do
|
||||
if curl -fsS "${url}" >/dev/null 2>&1; then
|
||||
log "health OK"
|
||||
curl -fsS "${url}" || true
|
||||
echo ""
|
||||
return 0
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
log "警告: health 暂未就绪,请稍后检查 pm2 logs ${PM2_APP_NAME}"
|
||||
return 1
|
||||
}
|
||||
|
||||
print_post_install_guide() {
|
||||
local ip
|
||||
ip="$(detect_server_ip)"
|
||||
echo ""
|
||||
echo "══════════════════════════════════════"
|
||||
echo " eth_hedge_sim 部署完成"
|
||||
echo " 目录: ${INSTALL_ROOT}"
|
||||
echo " 本机: http://${ip}:${API_PORT}/health"
|
||||
echo " 进程: pm2 status → ${PM2_APP_NAME}"
|
||||
echo " 管理: bash ${INSTALL_ROOT}/deploy/manage.sh"
|
||||
echo " 配置: ${INSTALL_ROOT}/.env"
|
||||
echo "══════════════════════════════════════"
|
||||
echo ""
|
||||
}
|
||||
Executable
+67
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env bash
|
||||
# deploy/lib/install.sh — 一键部署
|
||||
set -e
|
||||
set -u
|
||||
if [ -n "${BASH_VERSION:-}" ]; then
|
||||
set -o pipefail
|
||||
fi
|
||||
|
||||
LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=common.sh
|
||||
source "${LIB_DIR}/common.sh"
|
||||
|
||||
run_pipeline() {
|
||||
local root="$1"
|
||||
REPO_ROOT="${root}"
|
||||
step "构建并启动 (pull_and_restart.sh)"
|
||||
bash "${REPO_ROOT}/deploy/pull_and_restart.sh"
|
||||
pm2_save_startup
|
||||
verify_health || true
|
||||
print_post_install_guide
|
||||
}
|
||||
|
||||
install_fresh() {
|
||||
require_root
|
||||
ensure_system_deps
|
||||
step "克隆仓库 → ${INSTALL_ROOT}"
|
||||
if [[ -d "${INSTALL_ROOT}" ]]; then
|
||||
die "目录已存在: ${INSTALL_ROOT},请先卸载或选修复"
|
||||
fi
|
||||
mkdir -p "$(dirname "${INSTALL_ROOT}")"
|
||||
git clone -b "${GIT_BRANCH}" "${GIT_URL}" "${INSTALL_ROOT}"
|
||||
run_pipeline "${INSTALL_ROOT}"
|
||||
}
|
||||
|
||||
install_repair() {
|
||||
require_root
|
||||
ensure_system_deps
|
||||
if ! REPO_ROOT="$(resolve_repo_root)"; then
|
||||
die "未找到安装目录 ${INSTALL_ROOT}"
|
||||
fi
|
||||
step "修复环境(保留 .env 与数据库)"
|
||||
run_pipeline "${REPO_ROOT}"
|
||||
}
|
||||
|
||||
handle_existing() {
|
||||
echo ""
|
||||
echo "检测到已部署: ${INSTALL_ROOT}"
|
||||
echo " a) 取消"
|
||||
echo " b) 修复/重装环境(保留 .env 与 SQLite)"
|
||||
local choice=""
|
||||
cm_read choice "请选择 [a/b]: "
|
||||
case "${choice}" in
|
||||
b|B) install_repair ;;
|
||||
*) log "已取消" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
main_install() {
|
||||
require_root
|
||||
if repo_ready "${INSTALL_ROOT}"; then
|
||||
handle_existing
|
||||
else
|
||||
install_fresh
|
||||
fi
|
||||
}
|
||||
|
||||
main_install "$@"
|
||||
Executable
+80
@@ -0,0 +1,80 @@
|
||||
#!/usr/bin/env bash
|
||||
# deploy/lib/uninstall.sh — 一键卸载(仅本项目 PM2,不动其它进程)
|
||||
set -e
|
||||
set -u
|
||||
if [ -n "${BASH_VERSION:-}" ]; then
|
||||
set -o pipefail
|
||||
fi
|
||||
|
||||
LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=common.sh
|
||||
source "${LIB_DIR}/common.sh"
|
||||
|
||||
main_uninstall() {
|
||||
require_root
|
||||
|
||||
local root=""
|
||||
if ! root="$(resolve_repo_root)"; then
|
||||
if [[ -d "${INSTALL_ROOT}" ]]; then
|
||||
root="${INSTALL_ROOT}"
|
||||
else
|
||||
die "未找到安装目录 ${INSTALL_ROOT}"
|
||||
fi
|
||||
fi
|
||||
REPO_ROOT="${root}"
|
||||
|
||||
echo ""
|
||||
echo "将卸载 eth_hedge_sim:"
|
||||
echo " - 停止并删除 PM2 进程: ${PM2_APP_NAME}"
|
||||
echo " - 移走目录: ${INSTALL_ROOT}"
|
||||
echo " - 备份 .env 到 ${BACKUP_ROOT}"
|
||||
echo " - 不影响其它 PM2 应用"
|
||||
echo ""
|
||||
if ! confirm_yes "确认卸载?"; then
|
||||
log "已取消卸载"
|
||||
return 0
|
||||
fi
|
||||
|
||||
local stamp backup_dir removed_dir
|
||||
stamp="$(TZ="${TZ_NAME}" date +%Y%m%d-%H%M%S)"
|
||||
backup_dir="${BACKUP_ROOT}/pre-uninstall-${stamp}"
|
||||
removed_dir="${INSTALL_ROOT}.removed.${stamp}"
|
||||
mkdir -p "${backup_dir}"
|
||||
|
||||
step "备份配置"
|
||||
if [[ -f "${REPO_ROOT}/.env" ]]; then
|
||||
cp -a "${REPO_ROOT}/.env" "${backup_dir}/.env"
|
||||
fi
|
||||
if [[ -d "${REPO_ROOT}/backend/data" ]]; then
|
||||
cp -a "${REPO_ROOT}/backend/data" "${backup_dir}/data" 2>/dev/null || true
|
||||
fi
|
||||
{
|
||||
echo "created_at=${stamp}"
|
||||
echo "install_root=${INSTALL_ROOT}"
|
||||
echo "removed_dir=${removed_dir}"
|
||||
echo "pm2_app=${PM2_APP_NAME}"
|
||||
} >"${backup_dir}/uninstall.manifest"
|
||||
|
||||
step "停止并移除 PM2 进程 ${PM2_APP_NAME}"
|
||||
pm2_stop_project
|
||||
pm2_delete_project
|
||||
|
||||
step "移走安装目录"
|
||||
if [[ -d "${INSTALL_ROOT}" ]]; then
|
||||
mv "${INSTALL_ROOT}" "${removed_dir}"
|
||||
log "已移动: ${INSTALL_ROOT} -> ${removed_dir}"
|
||||
else
|
||||
log "安装目录不存在,跳过"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "卸载完成."
|
||||
echo " 配置备份: ${backup_dir}"
|
||||
echo " 旧目录: ${removed_dir} (确认无误后可手动 rm -rf)"
|
||||
echo ""
|
||||
echo "回滚示例:"
|
||||
echo " mv ${removed_dir} ${INSTALL_ROOT}"
|
||||
echo " bash ${INSTALL_ROOT}/deploy/manage.sh # 选 1 修复环境"
|
||||
}
|
||||
|
||||
main_uninstall "$@"
|
||||
Executable
+29
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env bash
|
||||
# deploy/lib/update.sh — 更新(仅 git pull,禁止 scp)
|
||||
set -e
|
||||
set -u
|
||||
if [ -n "${BASH_VERSION:-}" ]; then
|
||||
set -o pipefail
|
||||
fi
|
||||
|
||||
LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=common.sh
|
||||
source "${LIB_DIR}/common.sh"
|
||||
|
||||
main_update() {
|
||||
require_root
|
||||
if ! REPO_ROOT="$(resolve_repo_root)"; then
|
||||
die "未找到安装目录 ${INSTALL_ROOT},请先执行「1) 一键部署」"
|
||||
fi
|
||||
if ! repo_ready "${REPO_ROOT}"; then
|
||||
die "安装不完整,请先执行「1) 一键部署」"
|
||||
fi
|
||||
|
||||
step "更新 eth_hedge_sim (git pull + 构建 + pm2 reload)"
|
||||
bash "${REPO_ROOT}/deploy/pull_and_restart.sh"
|
||||
verify_health || true
|
||||
echo ""
|
||||
log "更新完成"
|
||||
}
|
||||
|
||||
main_update "$@"
|
||||
Executable
+158
@@ -0,0 +1,158 @@
|
||||
#!/usr/bin/env bash
|
||||
# eth_hedge_sim 部署管理器 — 一键部署 / 卸载 / 更新
|
||||
#
|
||||
# 新服务器(免克隆):
|
||||
# curl -fsSL https://git.bz121.com/dekun/eth_hedge_sim/raw/branch/main/deploy/manage.sh | bash
|
||||
#
|
||||
# 已安装:
|
||||
# bash /opt/eth_hedge_sim/deploy/manage.sh
|
||||
#
|
||||
set -e
|
||||
if [ -n "${BASH_VERSION:-}" ]; then
|
||||
set -o pipefail
|
||||
fi
|
||||
|
||||
INSTALL_ROOT="${INSTALL_ROOT:-/opt/eth_hedge_sim}"
|
||||
GIT_URL="${GIT_URL:-https://git.bz121.com/dekun/eth_hedge_sim.git}"
|
||||
GIT_BRANCH="${GIT_BRANCH:-main}"
|
||||
|
||||
# curl | bash 时脚本从 stdin 执行,BASH_SOURCE[0] 为空;须先安全探测再 set -u
|
||||
_script_src="${BASH_SOURCE[0]:-}"
|
||||
if [[ -n "${_script_src}" && -f "${_script_src}" ]]; then
|
||||
DEPLOY_DIR="$(cd "$(dirname "${_script_src}")" && pwd)"
|
||||
REPO_ROOT="$(cd "${DEPLOY_DIR}/.." && pwd)"
|
||||
LIB_DIR="${DEPLOY_DIR}/lib"
|
||||
else
|
||||
DEPLOY_DIR=""
|
||||
REPO_ROOT=""
|
||||
LIB_DIR=""
|
||||
fi
|
||||
unset _script_src
|
||||
|
||||
set -u
|
||||
|
||||
repo_ready() {
|
||||
[[ -f "${1}/deploy/manage.sh" && -f "${1}/deploy/pull_and_restart.sh" ]]
|
||||
}
|
||||
|
||||
sync_repo_if_present() {
|
||||
local root="$1"
|
||||
if [[ -d "${root}/.git" ]] && command -v git >/dev/null 2>&1; then
|
||||
git -C "${root}" pull -q --ff-only 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
bootstrap_repo() {
|
||||
if repo_ready "${INSTALL_ROOT}"; then
|
||||
REPO_ROOT="${INSTALL_ROOT}"
|
||||
DEPLOY_DIR="${REPO_ROOT}/deploy"
|
||||
LIB_DIR="${DEPLOY_DIR}/lib"
|
||||
sync_repo_if_present "${REPO_ROOT}"
|
||||
return 0
|
||||
fi
|
||||
if [[ -n "${REPO_ROOT}" ]] && repo_ready "${REPO_ROOT}"; then
|
||||
DEPLOY_DIR="${REPO_ROOT}/deploy"
|
||||
LIB_DIR="${DEPLOY_DIR}/lib"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "eth_hedge_sim 部署管理器 — 首次自举"
|
||||
echo "将克隆到: ${INSTALL_ROOT}"
|
||||
if [[ "$(id -u)" -ne 0 ]]; then
|
||||
echo "错误: 请使用 root 执行" >&2
|
||||
exit 1
|
||||
fi
|
||||
if ! command -v git >/dev/null 2>&1; then
|
||||
if command -v apt-get >/dev/null 2>&1; then
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update -qq
|
||||
apt-get install -y git ca-certificates curl
|
||||
else
|
||||
echo "错误: 未找到 git" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if [[ -d "${INSTALL_ROOT}" ]]; then
|
||||
echo "错误: ${INSTALL_ROOT} 已存在但不是有效仓库" >&2
|
||||
echo "请手动处理后再运行,或设置 INSTALL_ROOT 指向其它路径" >&2
|
||||
exit 1
|
||||
fi
|
||||
mkdir -p "$(dirname "${INSTALL_ROOT}")"
|
||||
git clone -b "${GIT_BRANCH}" "${GIT_URL}" "${INSTALL_ROOT}"
|
||||
# clone 后用仓库内脚本 + 终端 stdin(管道已 EOF)
|
||||
exec bash "${INSTALL_ROOT}/deploy/manage.sh" "$@" </dev/tty
|
||||
}
|
||||
|
||||
show_banner() {
|
||||
local path
|
||||
path="${INSTALL_ROOT}"
|
||||
if [[ -n "${REPO_ROOT}" ]] && repo_ready "${REPO_ROOT}"; then
|
||||
path="${REPO_ROOT}"
|
||||
fi
|
||||
echo ""
|
||||
echo "╔══════════════════════════════════════╗"
|
||||
echo "║ eth_hedge_sim 部署管理器 ║"
|
||||
echo "║ 路径: ${path}"
|
||||
echo "╚══════════════════════════════════════╝"
|
||||
echo ""
|
||||
}
|
||||
|
||||
show_menu() {
|
||||
echo " 1) 一键部署"
|
||||
echo " 2) 一键卸载"
|
||||
echo " 3) 更新"
|
||||
echo " 0) 退出"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 交互读入(兼容 curl|bash)
|
||||
cm_read() {
|
||||
local __var="$1"
|
||||
local __prompt="${2:-}"
|
||||
local __line=""
|
||||
if [[ -n "${__prompt}" ]]; then
|
||||
printf '%s' "${__prompt}" >/dev/tty 2>/dev/null || printf '%s' "${__prompt}"
|
||||
fi
|
||||
if [[ -r /dev/tty ]]; then
|
||||
IFS= read -r __line </dev/tty || true
|
||||
else
|
||||
IFS= read -r __line || true
|
||||
fi
|
||||
printf -v "${__var}" '%s' "${__line}"
|
||||
}
|
||||
|
||||
main_menu() {
|
||||
bootstrap_repo
|
||||
# shellcheck source=lib/common.sh
|
||||
source "${LIB_DIR}/common.sh"
|
||||
REPO_ROOT="$(resolve_repo_root || echo "${INSTALL_ROOT}")"
|
||||
|
||||
while true; do
|
||||
show_banner
|
||||
show_menu
|
||||
local choice=""
|
||||
cm_read choice "请选择 [0-3]: "
|
||||
case "${choice}" in
|
||||
1)
|
||||
bash "${LIB_DIR}/install.sh"
|
||||
;;
|
||||
2)
|
||||
bash "${LIB_DIR}/uninstall.sh"
|
||||
;;
|
||||
3)
|
||||
bash "${LIB_DIR}/update.sh"
|
||||
;;
|
||||
0)
|
||||
echo "再见."
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "无效选项,请输入 0-3"
|
||||
;;
|
||||
esac
|
||||
echo ""
|
||||
cm_read _ "按 Enter 返回菜单..."
|
||||
done
|
||||
}
|
||||
|
||||
main_menu "$@"
|
||||
Regular → Executable
+10
-5
@@ -1,14 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
# 一键更新/部署:仅 git pull,禁止 scp 传代码。
|
||||
# 用法(服务器上): bash /opt/eth_hedge_sim/deploy/pull_and_restart.sh
|
||||
# 用法:
|
||||
# bash /opt/eth_hedge_sim/deploy/pull_and_restart.sh
|
||||
# 或通过 manage.sh 选 1/3
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
echo "[eth_hedge_sim] pull @ $ROOT"
|
||||
git fetch --all --prune
|
||||
git pull --ff-only
|
||||
if [[ -d "$ROOT/.git" ]]; then
|
||||
git fetch --all --prune
|
||||
git pull --ff-only
|
||||
fi
|
||||
|
||||
if [[ ! -f "$ROOT/.env" ]]; then
|
||||
echo "[eth_hedge_sim] missing .env — copy from example"
|
||||
@@ -17,6 +21,7 @@ if [[ ! -f "$ROOT/.env" ]]; then
|
||||
sed -i 's/^OKX_HTTP_PROXY=.*/OKX_HTTP_PROXY=/' "$ROOT/.env" || true
|
||||
sed -i 's/^API_PORT=.*/API_PORT=5155/' "$ROOT/.env" || true
|
||||
sed -i 's/^ENV_NAME=.*/ENV_NAME=test/' "$ROOT/.env" || true
|
||||
sed -i 's/^EXCHANGE=.*/EXCHANGE=okx/' "$ROOT/.env" || true
|
||||
echo "[eth_hedge_sim] wrote .env — please review AUTH_* secrets"
|
||||
fi
|
||||
|
||||
@@ -29,7 +34,7 @@ pip install -U pip
|
||||
pip install -r "$ROOT/requirements.txt"
|
||||
|
||||
if ! command -v npm >/dev/null 2>&1; then
|
||||
echo "ERROR: npm not found. Install Node.js 18+ first."
|
||||
echo "ERROR: npm not found. Install Node.js 18+ first (manage.sh 一键部署会自动装)."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -47,4 +52,4 @@ fi
|
||||
pm2 startOrReload "$ROOT/deploy/ecosystem.config.cjs" --update-env
|
||||
pm2 save
|
||||
|
||||
echo "[eth_hedge_sim] done. health: http://127.0.0.1:5155/health public: https://dc.hyf2.cc/health"
|
||||
echo "[eth_hedge_sim] done. health: http://127.0.0.1:5155/health"
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
DEPLOY_PASS 服务器密码
|
||||
DEPLOY_ROOT 默认 /opt/eth_hedge_sim
|
||||
REPO_URL 默认 https://git.bz121.com/dekun/eth_hedge_sim.git
|
||||
DEPLOY_MODE update|bootstrap 默认 update(跑 pull_and_restart)
|
||||
bootstrap 时执行 manage 非交互更新路径
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -19,6 +21,7 @@ USER = os.environ.get("DEPLOY_USER", "root")
|
||||
PASSWORD = os.environ.get("DEPLOY_PASS", "")
|
||||
ROOT = os.environ.get("DEPLOY_ROOT", "/opt/eth_hedge_sim")
|
||||
REPO = os.environ.get("REPO_URL", "https://git.bz121.com/dekun/eth_hedge_sim.git")
|
||||
MODE = os.environ.get("DEPLOY_MODE", "update").strip().lower()
|
||||
|
||||
|
||||
def main() -> int:
|
||||
@@ -31,28 +34,33 @@ def main() -> int:
|
||||
print("pip install paramiko", file=sys.stderr)
|
||||
return 2
|
||||
|
||||
remote = f"""
|
||||
if MODE == "bootstrap":
|
||||
remote = f"""
|
||||
set -euo pipefail
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
if ! command -v git >/dev/null; then apt-get update -y && apt-get install -y git; fi
|
||||
if ! command -v python3 >/dev/null; then apt-get update -y && apt-get install -y python3 python3-venv python3-pip; fi
|
||||
if ! command -v node >/dev/null; then
|
||||
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
|
||||
apt-get install -y nodejs
|
||||
fi
|
||||
if [[ ! -d '{ROOT}/.git' ]]; then
|
||||
mkdir -p /opt
|
||||
git clone '{REPO}' '{ROOT}'
|
||||
fi
|
||||
bash '{ROOT}/deploy/pull_and_restart.sh'
|
||||
curl -fsS http://127.0.0.1:5155/health || true
|
||||
"""
|
||||
else:
|
||||
remote = f"""
|
||||
set -euo pipefail
|
||||
if [[ ! -d '{ROOT}/.git' ]]; then
|
||||
mkdir -p /opt
|
||||
git clone '{REPO}' '{ROOT}'
|
||||
fi
|
||||
bash '{ROOT}/deploy/lib/update.sh'
|
||||
curl -fsS http://127.0.0.1:5155/health || true
|
||||
"""
|
||||
|
||||
client = paramiko.SSHClient()
|
||||
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
print(f"connecting {USER}@{HOST} ...")
|
||||
client.connect(HOST, username=USER, password=PASSWORD, timeout=30)
|
||||
print("running remote bootstrap/pull ...")
|
||||
print("running remote pull/update ...")
|
||||
stdin, stdout, stderr = client.exec_command(remote, get_pty=True)
|
||||
while True:
|
||||
chunk = stdout.read(1024)
|
||||
|
||||
Reference in New Issue
Block a user