176 lines
5.9 KiB
Bash
176 lines
5.9 KiB
Bash
#!/bin/bash
|
|
set -u
|
|
|
|
PACKAGE_ROOT=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
|
|
APP_ROOT="${TRIM_APPDEST:-$PACKAGE_ROOT/app}"
|
|
DATA_ROOT="${TRIM_PKGVAR:-$PACKAGE_ROOT/var}"
|
|
VOLUME_ROOT="${TRIM_APPDEST_VOL:-$DATA_ROOT/volume}"
|
|
BACKUP_ROOT="${POSTGRES_SERVICE_BACKUP_ROOT:-$VOLUME_ROOT/@appshare/postgresql/backups}"
|
|
RUNTIME_ROOT="$APP_ROOT/runtime"
|
|
SERVER="$APP_ROOT/server/PostgresService.WebApi"
|
|
PG_BIN="$RUNTIME_ROOT/usr/lib/postgresql/15/bin"
|
|
PG_SHARE="$RUNTIME_ROOT/usr/share/postgresql/15"
|
|
PG_LIB="$RUNTIME_ROOT/usr/lib/postgresql/15/lib"
|
|
PG_DATA="$DATA_ROOT/postgres"
|
|
RUN_ROOT="$DATA_ROOT/run"
|
|
LOG_ROOT="$DATA_ROOT/log"
|
|
APP_PID_FILE="$RUN_ROOT/postgres-service.pid"
|
|
APP_LOG="$LOG_ROOT/postgres-service.log"
|
|
PG_LOG="$LOG_ROOT/postgresql.log"
|
|
PG_PORT="${POSTGRES_SERVICE_PORT:-15432}"
|
|
SERVICE_PORT="${TRIM_SERVICE_PORT:-15433}"
|
|
RUNTIME_PATH="$PG_BIN:$RUNTIME_ROOT/usr/bin:${PATH:-/usr/local/bin:/usr/bin:/bin}"
|
|
RUNTIME_LIBRARY_PATH="$RUNTIME_ROOT/usr/lib/x86_64-linux-gnu:$RUNTIME_ROOT/lib/x86_64-linux-gnu:$PG_LIB"
|
|
|
|
log_message() {
|
|
mkdir -p "$LOG_ROOT"
|
|
printf '%s - %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$1" >>"$APP_LOG"
|
|
}
|
|
|
|
run_pg() {
|
|
env LD_LIBRARY_PATH="$RUNTIME_LIBRARY_PATH" PATH="$RUNTIME_PATH" "$@"
|
|
}
|
|
|
|
app_pid() {
|
|
if [ -f "$APP_PID_FILE" ]; then
|
|
pid=$(sed -n '1p' "$APP_PID_FILE" | tr -d '[:space:]')
|
|
if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
|
|
printf '%s' "$pid"
|
|
return 0
|
|
fi
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
postgres_running() {
|
|
[ -x "$PG_BIN/pg_ctl" ] || return 1
|
|
[ -f "$PG_DATA/PG_VERSION" ] || return 1
|
|
run_pg "$PG_BIN/pg_ctl" -D "$PG_DATA" status >/dev/null 2>&1
|
|
}
|
|
|
|
initialize_postgres() {
|
|
[ ! -f "$PG_DATA/PG_VERSION" ] || return 0
|
|
mkdir -p "$PG_DATA" "$RUN_ROOT" "$LOG_ROOT"
|
|
chmod 0700 "$PG_DATA" "$RUN_ROOT"
|
|
run_pg "$PG_BIN/initdb" \
|
|
-D "$PG_DATA" \
|
|
-L "$PG_SHARE" \
|
|
--username=postgres_service \
|
|
--auth-local=trust \
|
|
--auth-host=scram-sha-256 \
|
|
--encoding=UTF8 \
|
|
--no-locale >>"$PG_LOG" 2>&1 || return 1
|
|
|
|
{
|
|
printf "listen_addresses = '127.0.0.1'\n"
|
|
printf "port = %s\n" "$PG_PORT"
|
|
printf "unix_socket_directories = '%s'\n" "$RUN_ROOT"
|
|
printf "password_encryption = 'scram-sha-256'\n"
|
|
printf "max_connections = 100\n"
|
|
printf "shared_buffers = '128MB'\n"
|
|
printf "timezone = 'UTC'\n"
|
|
printf "log_timezone = 'UTC'\n"
|
|
printf "log_min_duration_statement = 5000\n"
|
|
} >>"$PG_DATA/postgresql.conf"
|
|
|
|
{
|
|
printf 'local all postgres_service trust\n'
|
|
printf 'local all all reject\n'
|
|
printf 'host all all 127.0.0.1/32 scram-sha-256\n'
|
|
printf 'host all all ::1/128 scram-sha-256\n'
|
|
} >"$PG_DATA/pg_hba.conf"
|
|
}
|
|
|
|
start_postgres() {
|
|
postgres_running && return 0
|
|
initialize_postgres || { log_message "PostgreSQL 初始化失败。"; return 1; }
|
|
run_pg "$PG_BIN/pg_ctl" -D "$PG_DATA" -l "$PG_LOG" -w start || {
|
|
log_message "PostgreSQL 启动失败。"
|
|
return 1
|
|
}
|
|
}
|
|
|
|
stop_postgres() {
|
|
if postgres_running; then
|
|
run_pg "$PG_BIN/pg_ctl" -D "$PG_DATA" -m fast -t 180 -w stop >>"$PG_LOG" 2>&1 || {
|
|
log_message "PostgreSQL 未能在 180 秒内安全停止。"
|
|
return 1
|
|
}
|
|
fi
|
|
}
|
|
|
|
start_app() {
|
|
mkdir -p "$DATA_ROOT" "$RUN_ROOT" "$LOG_ROOT" "$BACKUP_ROOT" "$DATA_ROOT/tmp" "$DATA_ROOT/cache"
|
|
chmod 0700 "$DATA_ROOT" "$RUN_ROOT" "$DATA_ROOT/tmp" "$DATA_ROOT/cache" 2>/dev/null || true
|
|
[ -x "$SERVER" ] || { log_message "管理服务不存在或不可执行:$SERVER"; return 1; }
|
|
[ -x "$PG_BIN/postgres" ] || { log_message "PostgreSQL 原生运行环境不完整。"; return 1; }
|
|
if app_pid >/dev/null; then return 0; fi
|
|
start_postgres || return 1
|
|
|
|
(
|
|
export ASPNETCORE_ENVIRONMENT=Production
|
|
export ASPNETCORE_URLS="http://0.0.0.0:$SERVICE_PORT"
|
|
export POSTGRES_SERVICE_DATA_ROOT="$DATA_ROOT"
|
|
export POSTGRES_SERVICE_SOCKET_ROOT="$RUN_ROOT"
|
|
export POSTGRES_SERVICE_PORT="$PG_PORT"
|
|
export POSTGRES_SERVICE_ADMIN_USER=postgres_service
|
|
export POSTGRES_SERVICE_PG_BIN="$PG_BIN"
|
|
export POSTGRES_SERVICE_BACKUP_ROOT="$BACKUP_ROOT"
|
|
export DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
|
|
export DOTNET_BUNDLE_EXTRACT_BASE_DIR="$DATA_ROOT/dotnet-bundle"
|
|
export XDG_CACHE_HOME="$DATA_ROOT/cache"
|
|
export TMPDIR="$DATA_ROOT/tmp"
|
|
export LD_LIBRARY_PATH="$RUNTIME_LIBRARY_PATH"
|
|
export PATH="$RUNTIME_PATH"
|
|
mkdir -p "$DOTNET_BUNDLE_EXTRACT_BASE_DIR"
|
|
cd "$APP_ROOT/server" || exit 1
|
|
exec "$SERVER"
|
|
) >>"$APP_LOG" 2>&1 &
|
|
pid=$!
|
|
printf '%s\n' "$pid" >"$APP_PID_FILE"
|
|
|
|
attempt=0
|
|
while [ "$attempt" -lt 90 ]; do
|
|
if ! kill -0 "$pid" 2>/dev/null; then
|
|
log_message "管理服务进程提前退出。"
|
|
stop_postgres
|
|
return 1
|
|
fi
|
|
if (exec 3<>"/dev/tcp/127.0.0.1/$SERVICE_PORT") 2>/dev/null; then
|
|
exec 3>&-
|
|
log_message "PostgreSQL 共享服务启动成功,管理端口 $SERVICE_PORT,数据库端口 $PG_PORT。"
|
|
return 0
|
|
fi
|
|
attempt=$((attempt + 1))
|
|
sleep 1
|
|
done
|
|
log_message "管理服务未能在 90 秒内就绪。"
|
|
stop_app
|
|
return 1
|
|
}
|
|
|
|
stop_app() {
|
|
if pid=$(app_pid); then
|
|
kill "$pid" 2>/dev/null || true
|
|
attempt=0
|
|
while kill -0 "$pid" 2>/dev/null && [ "$attempt" -lt 30 ]; do
|
|
sleep 1
|
|
attempt=$((attempt + 1))
|
|
done
|
|
kill -9 "$pid" 2>/dev/null || true
|
|
fi
|
|
rm -f "$APP_PID_FILE"
|
|
stop_postgres
|
|
}
|
|
|
|
case "${1:-status}" in
|
|
start) start_app ;;
|
|
stop) stop_app ;;
|
|
restart) stop_app && start_app ;;
|
|
status)
|
|
if app_pid >/dev/null && postgres_running; then exit 0; fi
|
|
exit 3
|
|
;;
|
|
*) printf 'usage: %s {start|stop|restart|status}\n' "$0" >&2; exit 2 ;;
|
|
esac
|