#!/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" EXCHANGE="" while [[ $# -gt 0 ]]; do case "$1" in --exchange) EXCHANGE="${2:-}" shift 2 ;; -h|--help) echo "用法: bash deploy/lib/install.sh [--exchange okx|binance|gate]" echo " 无 --exchange: 全套(三所+中控)" echo " 有 --exchange: 仅该所 Flask 实例(不含中控/agent)" exit 0 ;; *) echo "未知参数: $1" >&2 exit 1 ;; esac done install_fresh() { step "克隆仓库" if [[ -d "${INSTALL_ROOT}" ]]; then die "目录已存在: ${INSTALL_ROOT},请选修复环境或深度重装" fi mkdir -p "$(dirname "${INSTALL_ROOT}")" git clone -b "${GIT_BRANCH}" "${GIT_URL}" "${INSTALL_ROOT}" } install_repair() { step "修复环境(保留数据与配置)" bash "${REPO_ROOT}/deploy/setup_env.sh" --install-system-deps } install_deep() { step "深度重装(保留 .env,清库)" bash "${REPO_ROOT}/deploy/reinstall.sh" --yes verify_deployment "$(detect_server_ip)" || true print_post_install_guide "$(detect_server_ip)" } run_install_pipeline() { step "环境部署 setup_env.sh" bash "${REPO_ROOT}/deploy/setup_env.sh" --install-system-deps step "启动 PM2 全部进程" bash "${REPO_ROOT}/deploy/pm2_start_all.sh" pm2_save_startup install_backup_cron_all verify_deployment "$(detect_server_ip)" || true print_post_install_guide "$(detect_server_ip)" } run_instance_pipeline() { local ex_key="$1" local dir_name dir_name="$(exchange_dir "${ex_key}")" step "单所环境部署 setup_env.sh --only ${ex_key}(不含中控)" bash "${REPO_ROOT}/deploy/setup_env.sh" --only "${ex_key}" --install-system-deps step "启动 PM2 仅 ${dir_name}" bash "${REPO_ROOT}/deploy/pm2_start_all.sh" --only "${ex_key}" pm2_save_startup local cron_script="${REPO_ROOT}/${dir_name}/scripts/install_backup_cron.sh" if [[ -x "${cron_script}" ]]; then step "安装 ${ex_key} 备份 cron" bash "${cron_script}" || true fi verify_deployment "$(detect_server_ip)" "${ex_key}" || true print_post_install_guide_instance "${ex_key}" "$(detect_server_ip)" } handle_existing_install() { echo "" echo "检测到已部署安装: ${INSTALL_ROOT}" echo " a) 取消" echo " b) 修复环境(重建 venv,保留 .env 与数据库)" echo " c) 深度重装(保留 .env,清库,见 reinstall.sh)" local choice="" cm_read choice "请选择 [a/b/c]: " case "${choice}" in b|B) install_repair if command -v pm2 >/dev/null 2>&1; then bash "${REPO_ROOT}/deploy/pm2_start_all.sh" 2>/dev/null || pm2 restart all 2>/dev/null || true pm2_save_startup fi verify_deployment "$(detect_server_ip)" || true print_post_install_guide "$(detect_server_ip)" ;; c|C) install_deep ;; *) log "已取消" ;; esac } ensure_repo_ready() { if repo_ready "${INSTALL_ROOT}"; then REPO_ROOT="${INSTALL_ROOT}" elif [[ -n "${REPO_ROOT:-}" ]] && repo_ready "${REPO_ROOT}"; then : else REPO_ROOT="" fi if [[ -z "${REPO_ROOT}" ]]; then install_system_packages install_node_pm2 install_fresh REPO_ROOT="${INSTALL_ROOT}" else install_system_packages install_node_pm2 fi } main_install_instance() { local ex_key="$1" require_root require_ubuntu ensure_repo_ready run_instance_pipeline "${ex_key}" } main_install() { require_root require_ubuntu if [[ -n "${EXCHANGE}" ]]; then local ex_key="" if ! ex_key="$(normalize_exchange_key "${EXCHANGE}")"; then die "无效 --exchange: ${EXCHANGE} (期望 okx|binance|gate)" fi main_install_instance "${ex_key}" return 0 fi if repo_ready "${INSTALL_ROOT}"; then REPO_ROOT="${INSTALL_ROOT}" elif repo_ready "${REPO_ROOT}"; then : else REPO_ROOT="" fi if [[ -n "${REPO_ROOT}" ]] && is_deployed "${REPO_ROOT}"; then handle_existing_install return 0 fi ensure_repo_ready run_install_pipeline } main_install "$@"