Files
market_intel/deploy/manage.sh
T
dekun 4743f3efdd fix: normalize deploy shell scripts to LF for Linux curl|bash
CRLF line endings broke manage.sh on Ubuntu (set -e and function syntax errors).
Add .gitattributes to keep *.sh on LF in git.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-02 08:41:15 +08:00

229 lines
6.3 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# 比特骆驼行情采集分析 部署管理器(工程 market_intel
# 部署环境: Ubuntu 22.04 LTS · Docker Compose
#
# 新服务器(免克隆):
# curl -fsSL https://git.bz121.com/dekun/market_intel/raw/branch/main/deploy/manage.sh | bash
#
# 已安装:
# bash /opt/market_intel/deploy/manage.sh
#
set -e
if [ -n "${BASH_VERSION:-}" ]; then
set -o pipefail
fi
INSTALL_ROOT="${INSTALL_ROOT:-/opt/market_intel}"
GIT_URL="${GIT_URL:-https://git.bz121.com/dekun/market_intel.git}"
GIT_BRANCH="${GIT_BRANCH:-main}"
_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}/docker-compose.yml" && -d "${1}/deploy/lib" ]]
}
ensure_git_cli() {
if command -v git >/dev/null 2>&1; then
return 0
fi
if command -v apt-get >/dev/null 2>&1; then
export DEBIAN_FRONTEND=noninteractive
local waited=0
while pgrep -x unattended-upgr >/dev/null 2>&1 \
|| pgrep -x apt-get >/dev/null 2>&1 \
|| pgrep -x apt >/dev/null 2>&1 \
|| pgrep -x dpkg >/dev/null 2>&1 \
|| { command -v fuser >/dev/null 2>&1 && fuser /var/lib/dpkg/lock-frontend >/dev/null 2>&1; }; do
if [[ "${waited}" -eq 0 ]]; then
echo "等待 apt 锁释放(unattended-upgrades)…"
fi
if [[ "${waited}" -ge 600 ]]; then
echo "错误: 等待 apt 锁超时,请稍后再试" >&2
exit 1
fi
sleep 5
waited=$((waited + 5))
done
apt-get update -qq
apt-get install -y git ca-certificates curl
else
echo "错误: 未找到 git" >&2
exit 1
fi
}
sync_repo_if_present() {
local root="$1"
if [[ -d "${root}/.git" ]] && command -v git >/dev/null 2>&1; then
git -C "${root}" fetch --all --prune 2>/dev/null || true
git -C "${root}" checkout "${GIT_BRANCH}" 2>/dev/null || true
git -C "${root}" pull --ff-only origin "${GIT_BRANCH}" 2>/dev/null \
|| git -C "${root}" pull --ff-only 2>/dev/null \
|| true
fi
}
heal_existing_install() {
local root="$1"
echo "检测到已有目录但缺少管理脚本: ${root}"
echo "尝试同步最新代码…"
ensure_git_cli
if [[ -d "${root}/.git" ]]; then
sync_repo_if_present "${root}"
if repo_ready "${root}"; then
echo "同步成功,切换到仓库内 manage.sh"
exec bash "${root}/deploy/manage.sh" "$@" </dev/tty
fi
echo "git pull 后仍不完整,尝试强制对齐 origin/${GIT_BRANCH}"
git -C "${root}" fetch origin "${GIT_BRANCH}" || true
git -C "${root}" reset --hard "origin/${GIT_BRANCH}" || true
if repo_ready "${root}"; then
echo "对齐成功,切换到仓库内 manage.sh"
exec bash "${root}/deploy/manage.sh" "$@" </dev/tty
fi
fi
echo "将备份配置并重新克隆到 ${root}"
local stamp backup_dir
stamp="$(date +%Y%m%d-%H%M%S)"
backup_dir="/root/backups/market_intel/heal-${stamp}"
mkdir -p "${backup_dir}"
[[ -f "${root}/.env" ]] && cp -a "${root}/.env" "${backup_dir}/.env"
echo "备份目录: ${backup_dir}"
local removed="${root}.old.${stamp}"
mv "${root}" "${removed}"
echo "旧目录已移至: ${removed}"
mkdir -p "$(dirname "${root}")"
git clone -b "${GIT_BRANCH}" "${GIT_URL}" "${root}"
if [[ -f "${backup_dir}/.env" ]]; then
cp -a "${backup_dir}/.env" "${root}/.env"
echo "已恢复 .env"
fi
exec bash "${root}/deploy/manage.sh" "$@" </dev/tty
}
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}"
if ! repo_ready "${REPO_ROOT}"; then
heal_existing_install "${INSTALL_ROOT}" "$@"
fi
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
if [[ -d "${INSTALL_ROOT}" ]]; then
if [[ "$(id -u)" -ne 0 ]]; then
echo "错误: 请使用 root 执行" >&2
exit 1
fi
heal_existing_install "${INSTALL_ROOT}" "$@"
fi
echo "比特骆驼行情采集分析 部署管理器 — 首次自举"
echo "将克隆到: ${INSTALL_ROOT}"
if [[ "$(id -u)" -ne 0 ]]; then
echo "错误: 请使用 root 执行" >&2
exit 1
fi
ensure_git_cli
mkdir -p "$(dirname "${INSTALL_ROOT}")"
git clone -b "${GIT_BRANCH}" "${GIT_URL}" "${INSTALL_ROOT}"
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 "║ 比特骆驼行情采集分析 部署管理器 ║"
echo "║ 路径: ${path}"
echo "╚══════════════════════════════════════╝"
echo ""
}
show_menu() {
echo " 1) 一键部署"
echo " 2) 更新"
echo " 3) 停止"
echo " 4) 启动"
echo " 5) 查看状态"
echo " 6) 一键卸载"
echo " 0) 退出"
echo ""
}
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-6]: "
case "${choice}" in
1) bash "${LIB_DIR}/install.sh" ;;
2) bash "${LIB_DIR}/update.sh" ;;
3) compose_stop ;;
4) compose_start ;;
5) show_status ;;
6) bash "${LIB_DIR}/uninstall.sh" ;;
0)
echo "再见."
exit 0
;;
*)
echo "无效选项,请输入 0-6"
;;
esac
echo ""
cm_read _ "按 Enter 返回菜单..."
done
}
main_menu "$@"