Files
ERP/distribution/bin/erp-run
T

210 lines
6.9 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
INSTALL_ROOT="${ERP_INSTALL_ROOT:-$(cd "$SCRIPT_DIR/../.." && pwd -P)}"
CONFIG_FILE="${ERP_CONFIG_FILE:-$INSTALL_ROOT/config/erp.env}"
say() { printf '[ERP] %s\n' "$*"; }
fail() { printf '[ERP] ERROR: %s\n' "$*" >&2; exit 1; }
migrate_legacy_update_source() {
local legacy_url='http://38.76.196.225:10099'
local official_url='https://git.awaioi.com'
local configured_url="${OA_UPDATE_GITEA_BASE_URL:-}"
[[ "${configured_url%/}" == "$legacy_url" ]] || return 0
local temporary
temporary="$(mktemp "${CONFIG_FILE}.migration.XXXXXX")" \
|| fail 'unable to create the update-source migration file'
if awk -v official_url="$official_url" '
BEGIN { base_url_written = 0; insecure_written = 0 }
/^OA_UPDATE_GITEA_BASE_URL=/ {
if (!base_url_written) print "OA_UPDATE_GITEA_BASE_URL=\047" official_url "\047"
base_url_written = 1
next
}
/^OA_UPDATE_ALLOW_INSECURE_HTTP=/ {
if (!insecure_written) print "OA_UPDATE_ALLOW_INSECURE_HTTP=\047false\047"
insecure_written = 1
next
}
{ print }
END {
if (!base_url_written) print "OA_UPDATE_GITEA_BASE_URL=\047" official_url "\047"
if (!insecure_written) print "OA_UPDATE_ALLOW_INSECURE_HTTP=\047false\047"
}
' "$CONFIG_FILE" > "$temporary" && chmod 600 "$temporary" && mv -f "$temporary" "$CONFIG_FILE"; then
say "Update source migrated to $official_url"
else
rm -f "$temporary"
say "WARNING: could not persist the update source migration; using $official_url for this process"
fi
OA_UPDATE_GITEA_BASE_URL="$official_url"
OA_UPDATE_ALLOW_INSECURE_HTTP=false
export OA_UPDATE_GITEA_BASE_URL OA_UPDATE_ALLOW_INSECURE_HTTP
}
load_configuration() {
[[ -r "$CONFIG_FILE" ]] || fail "configuration not readable: $CONFIG_FILE"
set -a
# The installer writes this file with POSIX shell-safe single-quoted values.
# shellcheck disable=SC1090
source "$CONFIG_FILE"
set +a
migrate_legacy_update_source
RUN_DIR="${ERP_RUN_DIR:-$INSTALL_ROOT/run}"
JAR_PATH="${ERP_JAR_PATH:-$INSTALL_ROOT/current/app/kaidi-erp.jar}"
INSTALLER_JAR="${ERP_INSTALLER_JAR:-$INSTALL_ROOT/installer/kaidi-erp-installer.jar}"
PENDING_FILE="${ERP_INSTALL_PENDING_FILE:-$INSTALL_ROOT/state/install.pending}"
INSTALL_LOCK_FILE="${ERP_INSTALL_LOCK_FILE:-$INSTALL_ROOT/state/install.lock}"
INSTALL_LOG_FILE="${ERP_INSTALL_LOG_FILE:-$(dirname "$PENDING_FILE")/install-formal.log}"
HEALTH_URL="${ERP_HEALTH_URL:-http://127.0.0.1:${SERVER_PORT:-8091}/api/oa/health}"
HEALTH_TIMEOUT_SECONDS="${ERP_INSTALL_HEALTH_TIMEOUT_SECONDS:-240}"
HEALTH_POLL_SECONDS="${ERP_UPDATE_HEALTH_POLL_SECONDS:-2}"
}
resolve_java() {
JAVA_BIN="${ERP_JAVA_BIN:-}"
if [[ -z "$JAVA_BIN" ]]; then
if [[ -n "${JAVA_HOME:-}" && -x "$JAVA_HOME/bin/java" ]]; then
JAVA_BIN="$JAVA_HOME/bin/java"
else
JAVA_BIN="$(command -v java || true)"
fi
fi
[[ -n "$JAVA_BIN" && -x "$JAVA_BIN" ]] || fail 'Java 17+ is not installed'
local java_major
java_major="$("$JAVA_BIN" -version 2>&1 | awk -F'[".]' '/version/ {print $2; exit}')"
[[ "$java_major" =~ ^[0-9]+$ && "$java_major" -ge 17 ]] || fail 'Java 17+ is required'
}
split_java_options() {
IFS=$' \t' read -r -a JAVA_OPTS <<< "${ERP_JAVA_OPTS:--Xms512m -Xmx2g}"
IFS=$' \t' read -r -a INSTALLER_JAVA_OPTS <<< "${ERP_INSTALLER_JAVA_OPTS:--Xms128m -Xmx512m}"
}
write_pid() {
mkdir -p "$RUN_DIR"
printf '%s\n' "$1" > "$RUN_DIR/app.pid"
}
clear_pid() {
local expected="$1"
if [[ -r "$RUN_DIR/app.pid" && "$(<"$RUN_DIR/app.pid")" == "$expected" ]]; then
rm -f "$RUN_DIR/app.pid"
fi
}
run_formal_application_direct() {
[[ -r "$JAR_PATH" ]] || fail "application jar not readable: $JAR_PATH"
write_pid "$$"
exec "$JAVA_BIN" "${JAVA_OPTS[@]}" \
-jar "$JAR_PATH" \
--spring.profiles.active=postgres \
--server.port="${SERVER_PORT:-8091}"
}
run_web_installer() {
[[ -r "$INSTALLER_JAR" ]] || fail "installer jar not readable: $INSTALLER_JAR"
say "Starting first-run installer on port ${SERVER_PORT:-8091}"
printf '%s\n' "$$" > "$RUN_DIR/installer.pid"
set +e
"$JAVA_BIN" "${INSTALLER_JAVA_OPTS[@]}" \
-jar "$INSTALLER_JAR" \
--server.port="${SERVER_PORT:-8091}"
local status=$?
set -e
rm -f "$RUN_DIR/installer.pid"
[[ "$status" == "0" ]] || fail "web installer exited with status $status"
[[ -f "$PENDING_FILE" ]] || fail 'web installer exited before installation was completed'
}
finalize_installation() {
[[ -f "$PENDING_FILE" ]] || fail "pending installation marker is missing: $PENDING_FILE"
[[ ! -e "$INSTALL_LOCK_FILE" ]] || fail "installation lock already exists: $INSTALL_LOCK_FILE"
mkdir -p "$(dirname "$INSTALL_LOCK_FILE")"
mv "$PENDING_FILE" "$INSTALL_LOCK_FILE"
chmod 600 "$INSTALL_LOCK_FILE"
rm -rf "$INSTALL_ROOT/installer"
say "Installation lock written; the web installer has been removed"
}
run_pending_formal_application() {
[[ -r "$JAR_PATH" ]] || fail "application jar not readable: $JAR_PATH"
[[ "$HEALTH_TIMEOUT_SECONDS" =~ ^[1-9][0-9]*$ ]] || fail 'invalid installation health timeout'
[[ "$HEALTH_POLL_SECONDS" =~ ^[1-9][0-9]*$ ]] || fail 'invalid health poll interval'
say 'Starting the formal PostgreSQL application'
mkdir -p "$(dirname "$INSTALL_LOG_FILE")"
: > "$INSTALL_LOG_FILE"
chmod 600 "$INSTALL_LOG_FILE"
"$JAVA_BIN" "${JAVA_OPTS[@]}" \
-jar "$JAR_PATH" \
--spring.profiles.active=postgres \
--server.port="${SERVER_PORT:-8091}" \
> >(tee -a "$INSTALL_LOG_FILE") 2>&1 &
APP_PID=$!
write_pid "$APP_PID"
forward_signal() {
kill -TERM "$APP_PID" 2>/dev/null || true
}
trap forward_signal TERM INT
local deadline=$((SECONDS + HEALTH_TIMEOUT_SECONDS))
while (( SECONDS < deadline )); do
if ! kill -0 "$APP_PID" 2>/dev/null; then
set +e
wait "$APP_PID"
local status=$?
set -e
clear_pid "$APP_PID"
say "Formal application diagnostics: $INSTALL_LOG_FILE"
fail "formal application exited before becoming healthy (status $status)"
fi
if curl -fsS --connect-timeout 2 --max-time 5 "$HEALTH_URL" >/dev/null 2>&1; then
finalize_installation
set +e
wait "$APP_PID"
local status=$?
set -e
clear_pid "$APP_PID"
return "$status"
fi
sleep "$HEALTH_POLL_SECONDS"
done
kill -TERM "$APP_PID" 2>/dev/null || true
set +e
wait "$APP_PID"
set -e
clear_pid "$APP_PID"
say "Formal application diagnostics: $INSTALL_LOG_FILE"
fail "formal application did not become healthy within ${HEALTH_TIMEOUT_SECONDS} seconds"
}
main() {
load_configuration
resolve_java
split_java_options
mkdir -p "$RUN_DIR"
if [[ -f "$INSTALL_LOCK_FILE" ]]; then
run_formal_application_direct
fi
if [[ ! -f "$PENDING_FILE" ]]; then
run_web_installer
load_configuration
resolve_java
split_java_options
fi
run_pending_formal_application
}
main "$@"