#!/usr/bin/env bash set -Eeuo pipefail GITEA_BASE_URL="https://git.awaioi.com" REPOSITORY="awaioi/ERP" VERSION="0.3.8" TAG="v${VERSION}" INSTALL_SHA256="716f6a9ea75659be3c7162d031f1b1fe5e8aa0e82e0101296153842dff9b35d6" UNINSTALL_SHA256="98c56fed2fd4d01874e4ab5a1a4f3ec42ec3e29b315ffd87385a95488d587546" PG_ROOT="${ERP_RECOVERY_PG_ROOT:-/www/server/pgsql}" PG_DATA="${ERP_RECOVERY_PG_DATA:-/www/server/pgsql/data}" PG_INIT_SCRIPT="${ERP_RECOVERY_PG_INIT_SCRIPT:-/etc/init.d/pgsql}" TMP_DIR="" say() { printf '[ERP Recovery] %s\n' "$*"; } fail() { printf '[ERP Recovery] ERROR: %s\n' "$*" >&2; exit 1; } cleanup() { [[ -z "$TMP_DIR" || ! -d "$TMP_DIR" ]] || rm -rf -- "$TMP_DIR" } trap cleanup EXIT postgres_port_open() { timeout 2 bash -c 'exec 3<>/dev/tcp/127.0.0.1/5432' >/dev/null 2>&1 } wait_for_postgres() { local _ for _ in {1..60}; do postgres_port_open && return 0 sleep 1 done return 1 } start_erp_postgres() { if postgres_port_open; then say 'PostgreSQL is already listening on 127.0.0.1:5432' return 0 fi [[ -f "$PG_DATA/PG_VERSION" ]] \ || fail "PostgreSQL data directory is missing: $PG_DATA" if [[ -x "$PG_INIT_SCRIPT" ]]; then say "Starting PostgreSQL with $PG_INIT_SCRIPT" if ! "$PG_INIT_SCRIPT" start; then say 'The init script returned an error; checking whether PostgreSQL still started' fi else local pg_ctl pg_user pg_ctl="$(find "$PG_ROOT" -type f -name pg_ctl -print -quit 2>/dev/null || true)" [[ -n "$pg_ctl" && -x "$pg_ctl" ]] || fail "pg_ctl was not found below $PG_ROOT" pg_user="$(stat -c '%U' "$PG_DATA")" || fail 'Unable to determine the PostgreSQL owner' id "$pg_user" >/dev/null 2>&1 || fail "PostgreSQL owner does not exist: $pg_user" say "Starting PostgreSQL as $pg_user" runuser -u "$pg_user" -- "$pg_ctl" \ -D "$PG_DATA" \ -l "$PG_DATA/startup.log" \ -w -t 60 start fi if ! wait_for_postgres; then [[ ! -r "$PG_DATA/startup.log" ]] || tail -n 100 "$PG_DATA/startup.log" >&2 fail 'PostgreSQL did not listen on 127.0.0.1:5432 within 60 seconds' fi say 'PostgreSQL is ready on 127.0.0.1:5432' } download_verified_script() { local name="$1" expected="$2" destination destination="$TMP_DIR/$name" curl -fsSL --connect-timeout 15 --max-time 300 \ "$GITEA_BASE_URL/$REPOSITORY/raw/tag/$TAG/$name" \ -o "$destination" printf '%s %s\n' "$expected" "$destination" | sha256sum -c - >&2 printf '%s' "$destination" } main() { [[ "$(id -u)" == "0" ]] || fail 'Run this recovery command as root' for command in bash curl find runuser sha256sum stat timeout; do command -v "$command" >/dev/null 2>&1 || fail "Missing command: $command" done start_erp_postgres TMP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/kaidi-erp-recovery.XXXXXX")" local uninstaller installer uninstaller="$(download_verified_script uninstall.sh "$UNINSTALL_SHA256")" say 'Removing the pending installation and its PostgreSQL schema safely' bash "$uninstaller" --purge-database --yes installer="$(download_verified_script install.sh "$INSTALL_SHA256")" say "Installing Kaidi ERP $VERSION" bash "$installer" \ --gitea-url "$GITEA_BASE_URL" \ --repository "$REPOSITORY" \ --version "$VERSION" } if [[ "${BASH_SOURCE[0]:-$0}" == "$0" ]]; then main "$@" fi