PSA/ee/setup/entrypoint.sh
Hermes 284313f908
Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Initial import of AlgaPSA codebase from PSA server
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz

Source: /opt/alga-psa on psa.joliet.tech
2026-06-22 16:12:17 -05:00

194 lines
7.2 KiB
Bash
Executable File

#!/bin/bash
# Function to log with timestamp
log() {
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1"
}
# Function to handle errors
handle_error() {
local exit_code=$?
local last_command=${BASH_COMMAND}
log "ERROR: Command '$last_command' failed with exit code $exit_code."
log "Exiting with error code: $exit_code"
# Exit with the captured exit code
exit $exit_code
}
# Set up error handling to call handle_error on ERR
# and also exit immediately if a command exits with a non-zero status.
set -e
trap 'handle_error' ERR
# Function to check if postgres is ready
wait_for_postgres() {
log "Waiting for PostgreSQL to be ready..."
set +e # Temporarily disable exit on error for the until loop
until PGPASSWORD=$(cat /run/secrets/postgres_password) psql -h ${DB_HOST:-postgres} -p ${DB_PORT:-5432} -U postgres -c '\q' 2>/dev/null; do
log "PostgreSQL is unavailable - sleeping"
sleep 1
done
set -e # Re-enable exit on error
log "PostgreSQL is up and running!"
}
# Verify Postgres is configured to use md5 authentication (and not trust/scram) for host connections
check_postgres_md5_auth() {
if [ "${SKIP_MD5_AUTH_CHECK}" = "true" ] || [ "${SKIP_MD5_AUTH_CHECK}" = "1" ]; then
log "Skipping PostgreSQL md5 authentication check (SKIP_MD5_AUTH_CHECK=${SKIP_MD5_AUTH_CHECK})"
return 0
fi
log "Validating PostgreSQL authentication configuration (md5)..."
local psql_base=(psql -h ${DB_HOST:-postgres} -p ${DB_PORT:-5432} -U postgres -d ${DB_NAME_SERVER:-server} -tAc)
# 1) Ensure password_encryption is md5 so newly created passwords are compatible with md5 auth
local password_encryption
password_encryption=$(PGPASSWORD=$(cat /run/secrets/postgres_password) "${psql_base[@]}" "SHOW password_encryption;" | tr -d '[:space:]')
if [ "${password_encryption}" != "md5" ]; then
log "ERROR: password_encryption is '${password_encryption}', expected 'md5'."
log " Update postgresql.conf to set password_encryption = 'md5' and restart Postgres,"
log " or set SKIP_MD5_AUTH_CHECK=true to bypass this enforcement."
exit 1
fi
# 2) Ensure pg_hba rules use md5 for host connections
# Check if pg_hba_file_rules view exists (PG 10+)
local has_hba_view
has_hba_view=$(PGPASSWORD=$(cat /run/secrets/postgres_password) "${psql_base[@]}" "SELECT to_regclass('pg_catalog.pg_hba_file_rules') IS NOT NULL;" | tr -d '[:space:]')
if [ "${has_hba_view}" != "t" ]; then
log "WARNING: pg_hba_file_rules view is not available on this Postgres version; skipping pg_hba auth check."
return 0
fi
# Count any non-md5 host rules
local non_md5_count
non_md5_count=$(PGPASSWORD=$(cat /run/secrets/postgres_password) "${psql_base[@]}" \
"SELECT count(*) FROM pg_hba_file_rules WHERE type IN ('host','hostssl','hostnossl') AND auth_method <> 'md5';")
non_md5_count=$(echo "$non_md5_count" | tr -d '[:space:]')
if [ "${non_md5_count}" != "0" ]; then
log "ERROR: Found ${non_md5_count} pg_hba host rules that are not using md5 authentication."
PGPASSWORD=$(cat /run/secrets/postgres_password) "${psql_base[@]}" \
"SELECT line_number, type, database, user_name, address, netmask, auth_method FROM pg_hba_file_rules WHERE type IN ('host','hostssl','hostnossl') AND auth_method <> 'md5' ORDER BY line_number;"
log " Update pg_hba.conf to use 'md5' for host entries (and reload Postgres),"
log " or set SKIP_MD5_AUTH_CHECK=true to bypass this enforcement."
exit 1
fi
log "PostgreSQL authentication check passed (md5)."
}
# Function to merge CE and EE migrations
merge_migrations() {
log "Merging CE and EE migrations..."
# Create the final migrations directory
mkdir -p /app/server/migrations
# Copy all CE migrations first
if [ -d "/app/server/migrations-ce" ] && [ "$(ls -A /app/server/migrations-ce)" ]; then
log "Copying CE migrations..."
cp -r /app/server/migrations-ce/* /app/server/migrations/
log "CE migrations copied successfully"
else
log "No CE migrations found"
fi
# Overlay EE migrations (overwrites CE files with same name)
if [ -d "/app/server/migrations-ee" ] && [ "$(ls -A /app/server/migrations-ee)" ]; then
log "Overlaying EE migrations..."
cp -r /app/server/migrations-ee/* /app/server/migrations/
log "EE migrations overlaid successfully"
else
log "No EE migrations found"
fi
# List final migrations for verification
log "Final migration files:"
ls -la /app/server/migrations/ | head -20
}
# Function to merge CE and EE seeds
merge_seeds() {
log "Merging CE and EE seeds..."
# Create the final seeds directory
mkdir -p /app/server/seeds
# Copy all CE seeds first
if [ -d "/app/server/seeds-ce" ] && [ "$(ls -A /app/server/seeds-ce)" ]; then
log "Copying CE seeds..."
cp -r /app/server/seeds-ce/* /app/server/seeds/
log "CE seeds copied successfully"
else
log "No CE seeds found"
fi
# Overlay EE seeds (overwrites CE files with same name)
if [ -d "/app/server/seeds-ee" ] && [ "$(ls -A /app/server/seeds-ee)" ]; then
log "Overlaying EE seeds..."
cp -r /app/server/seeds-ee/* /app/server/seeds/
log "EE seeds overlaid successfully"
else
log "No EE seeds found"
fi
}
# Function to check if seeds have been run
check_seeds_status() {
local has_seeds
has_seeds=$(PGPASSWORD=$(cat /run/secrets/postgres_password) psql -h ${DB_HOST:-postgres} -p ${DB_PORT:-5432} -U postgres -d ${DB_NAME_SERVER:-server} -tAc "SELECT EXISTS (SELECT 1 FROM users LIMIT 1);")
if [ "$has_seeds" = "t" ]; then
return 0 # Seeds have been run
else
return 1 # Seeds haven't been run
fi
}
# Main setup process
main() {
log "Starting Enterprise Edition setup..."
wait_for_postgres
check_postgres_md5_auth
# Merge CE and EE migrations/seeds
merge_migrations
merge_seeds
log "Creating database..."
node /app/server/setup/create_database.js
log "Creating pgboss schema..."
PGPASSWORD=$(cat /run/secrets/postgres_password) psql -h ${DB_HOST:-postgres} -p ${DB_PORT:-5432} -U postgres -d ${DB_NAME_SERVER:-server} -c 'CREATE SCHEMA IF NOT EXISTS pgboss;'
log "Granting necessary permissions..."
PGPASSWORD=$(cat /run/secrets/postgres_password) psql -h ${DB_HOST:-postgres} -p ${DB_PORT:-5432} -U postgres -d ${DB_NAME_SERVER:-server} -c 'GRANT ALL ON SCHEMA public TO postgres;'
log "Running merged migrations (CE + EE)..."
NODE_ENV=migration npx knex migrate:latest --knexfile /app/server/knexfile.cjs
# Check if seeds need to be run
if ! check_seeds_status; then
log "Running seeds..."
NODE_ENV=migration npx knex seed:run --knexfile /app/server/knexfile.cjs || {
local exit_code=$?
log "ERROR: Seeds failed with exit code $exit_code"
exit $exit_code
}
log "Seeds completed!"
else
log "Seeds have already been run, skipping..."
fi
log "Enterprise Edition setup completed!"
log "Exiting with success code: 0"
exit 0
}
# Execute main function
main