210 lines
6.9 KiB
Bash
Executable File
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 "$@"
|