Files
ai_site/scripts/linux/setup-host.sh
2026-07-31 10:19:22 +08:00

225 lines
7.0 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
# 在宿主机物理目录自动配置环境(无 Docker
# 数据落盘:$ROOT/.runtime/{postgres,venv,logs,pids} 与 platform/data/uploads
# shellcheck disable=SC1091
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=common.sh
source "$SCRIPT_DIR/common.sh"
c_info "根目录(物理): $ROOT"
c_info "运行时目录: $RUNTIME"
c_info "上传目录: $UPLOAD_DIR"
need_pkgs=()
have_cmd curl || need_pkgs+=(curl)
have_cmd git || need_pkgs+=(git)
have_cmd go || need_pkgs+=(golang-go)
have_cmd python3 || need_pkgs+=(python3)
have_cmd pip3 || need_pkgs+=(python3-pip)
python3 -c "import venv" 2>/dev/null || need_pkgs+=(python3-venv)
have_cmd node || need_pkgs+=(nodejs)
have_cmd npm || need_pkgs+=(npm)
have_cmd psql || need_pkgs+=(postgresql-client)
have_cmd initdb || have_cmd pg_ctl || need_pkgs+=(postgresql)
install_pkgs() {
local os
os="$(detect_os)"
c_info "安装系统包 (OS=$os): ${need_pkgs[*]}"
case "$os" in
ubuntu|debian|linuxmint|pop)
sudo_run apt-get update -y
local pkgs=()
for p in "${need_pkgs[@]}"; do
case "$p" in
golang-go) pkgs+=(golang-go) ;;
python3) pkgs+=(python3 python3-venv python3-dev) ;;
python3-pip) pkgs+=(python3-pip) ;;
python3-venv) pkgs+=(python3-venv) ;;
nodejs) pkgs+=(nodejs) ;;
npm) pkgs+=(npm) ;;
postgresql) pkgs+=(postgresql postgresql-contrib) ;;
postgresql-client) pkgs+=(postgresql-client) ;;
*) pkgs+=("$p") ;;
esac
done
sudo_run apt-get install -y "${pkgs[@]}"
;;
fedora|rhel|centos|rocky|almalinux)
local pkgs=()
for p in "${need_pkgs[@]}"; do
case "$p" in
golang-go) pkgs+=(golang) ;;
python3-pip) pkgs+=(python3-pip) ;;
python3-venv) pkgs+=(python3) ;;
postgresql) pkgs+=(postgresql-server postgresql) ;;
postgresql-client) pkgs+=(postgresql) ;;
*) pkgs+=("$p") ;;
esac
done
if have_cmd dnf; then sudo_run dnf install -y "${pkgs[@]}"
else sudo_run yum install -y "${pkgs[@]}"; fi
;;
arch|manjaro)
local pkgs=()
for p in "${need_pkgs[@]}"; do
case "$p" in
golang-go) pkgs+=(go) ;;
python3) pkgs+=(python) ;;
python3-pip) pkgs+=(python-pip) ;;
python3-venv) ;;
postgresql-client) pkgs+=(postgresql) ;;
*) pkgs+=("$p") ;;
esac
done
sudo_run pacman -Sy --noconfirm "${pkgs[@]}"
;;
*)
c_err "未识别发行版 $os,请手动安装: go python3 node npm postgresql curl"
return 1
;;
esac
}
if ((${#need_pkgs[@]} > 0)); then
install_pkgs
else
c_ok "系统依赖已满足"
fi
missing=()
for c in go python3 curl; do have_cmd "$c" || missing+=("$c"); done
have_cmd node || have_cmd nodejs || missing+=("node")
have_cmd npm || missing+=("npm")
if ((${#missing[@]} > 0)); then
c_err "仍缺少命令: ${missing[*]}"
exit 1
fi
c_ok "$(go version)"
c_info "配置 Python venv → $VENV_DIR"
if [[ ! -d "$VENV_DIR" ]]; then
python3 -m venv "$VENV_DIR"
fi
# shellcheck source=/dev/null
source "$VENV_DIR/bin/activate"
pip install -U pip wheel >/dev/null
pip install -r "$ROOT/ai-service/requirements.txt"
pip install -r "$ROOT/agent_sdk/requirements.txt"
c_ok "venv 依赖已安装"
c_info "安装前端依赖 → $ROOT/web/node_modules"
if [[ ! -d "$ROOT/web/node_modules" ]]; then
(cd "$ROOT/web" && npm install)
else
c_ok "web/node_modules 已存在"
fi
find_pg_bin() {
local name="$1"
if have_cmd "$name"; then command -v "$name"; return; fi
local d
for d in /usr/lib/postgresql/*/bin /usr/pgsql-*/bin; do
if [[ -x "$d/$name" ]]; then echo "$d/$name"; return; fi
done
return 1
}
INITDB="$(find_pg_bin initdb || true)"
PG_CTL="$(find_pg_bin pg_ctl || true)"
PSQL="$(find_pg_bin psql || true)"
ensure_local_postgres() {
if [[ -z "$INITDB" || -z "$PG_CTL" || -z "$PSQL" ]]; then
c_warn "未找到 initdb/pg_ctl/psql跳过本地库初始化请自备 Postgres"
return 0
fi
# 已有可连库则复用
if PGPASSWORD="$PG_PASS" "$PSQL" -h 127.0.0.1 -p "$PG_PORT" -U "$PG_USER" -d "$PG_DB" -c "SELECT 1" >/dev/null 2>&1; then
c_ok "复用已有 Postgres $PG_USER@$PG_DB:$PG_PORT"
PGPASSWORD="$PG_PASS" "$PSQL" -h 127.0.0.1 -p "$PG_PORT" -U "$PG_USER" -d "$PG_DB" \
-c "ALTER USER $PG_USER CREATEDB;" >/dev/null 2>&1 || true
return 0
fi
mkdir -p "$PGDATA" "$RUNTIME/pg_sockets"
if [[ ! -f "$PGDATA/PG_VERSION" ]]; then
c_info "initdb → $PGDATA (物理目录)"
"$INITDB" -D "$PGDATA" --auth=trust -U postgres
{
echo ""
echo "listen_addresses = '127.0.0.1'"
echo "port = $PG_PORT"
echo "unix_socket_directories = '$RUNTIME/pg_sockets'"
} >> "$PGDATA/postgresql.conf"
fi
if ! "$PG_CTL" -D "$PGDATA" status >/dev/null 2>&1; then
c_info "启动本地 Postgres"
"$PG_CTL" -D "$PGDATA" -l "$LOG_DIR/postgres.log" -o "-k $RUNTIME/pg_sockets" start
sleep 1
fi
local sock="$RUNTIME/pg_sockets"
"$PSQL" -h "$sock" -U postgres -d postgres -v ON_ERROR_STOP=1 <<SQL
DO \$\$
BEGIN
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = '$PG_USER') THEN
CREATE ROLE $PG_USER LOGIN PASSWORD '$PG_PASS' CREATEDB;
ELSE
ALTER ROLE $PG_USER WITH LOGIN PASSWORD '$PG_PASS' CREATEDB;
END IF;
END
\$\$;
SELECT 'ok' FROM pg_database WHERE datname = '$PG_DB';
SQL
if ! "$PSQL" -h "$sock" -U postgres -d postgres -tc "SELECT 1 FROM pg_database WHERE datname='$PG_DB'" | grep -q 1; then
"$PSQL" -h "$sock" -U postgres -d postgres -c "CREATE DATABASE $PG_DB OWNER $PG_USER;"
fi
# 校验 TCP
if ! PGPASSWORD="$PG_PASS" "$PSQL" -h 127.0.0.1 -p "$PG_PORT" -U "$PG_USER" -d "$PG_DB" -c "SELECT 1" >/dev/null 2>&1; then
# 补充密码认证
cat > "$PGDATA/pg_hba.conf" <<EOF
local all all trust
host all all 127.0.0.1/32 trust
host all all ::1/128 trust
EOF
"$PG_CTL" -D "$PGDATA" reload || "$PG_CTL" -D "$PGDATA" restart -m fast
sleep 1
fi
PGPASSWORD="$PG_PASS" "$PSQL" -h 127.0.0.1 -p "$PG_PORT" -U "$PG_USER" -d "$PG_DB" -c "SELECT 1" >/dev/null
c_ok "Postgres 就绪 (物理 data=$PGDATA)"
}
ensure_local_postgres
c_info "编译 platform / gateway"
(cd "$ROOT/platform" && go build -o platform .)
(cd "$ROOT/gateway" && go build -o gateway .)
c_ok "二进制已生成"
if [[ ! -f "$ROOT/ai-service/sample_inventory.xlsx" ]]; then
(cd "$ROOT/ai-service" && "$VENV_DIR/bin/python" make_sample_excel.py) || true
fi
date -Iseconds > "$RUNTIME/setup.ok"
cat > "$RUNTIME/env.sh" <<EOF
# 由 setup-host.sh 生成 — 物理目录运行时
export AJZ_ROOT="$ROOT"
export AJZ_RUNTIME="$RUNTIME"
export PATH="$VENV_DIR/bin:\$PATH"
export PGHOST=127.0.0.1
export PGPORT=$PG_PORT
export PGUSER=$PG_USER
export PGPASSWORD=$PG_PASS
export PGDATABASE=$PG_DB
EOF
c_info "环境配置完成(无 Docker全部落在物理目录"
c_ok "下一步: ./start.sh"