2024-09-30 07:27:47 +00:00
#!/bin/bash
2024-10-04 04:47:17 +00:00
# default values
DB_USER = "appsmith"
DB_HOST = "127.0.0.1"
DB_PORT = "5432"
DB_SCHEMA = "appsmith"
DB_NAME = "appsmith"
2024-12-06 05:19:27 +00:00
POSTGRES_ADMIN_USER = "postgres"
POSTGRES_DB_PATH = "/appsmith-stacks/data/postgres/main"
2024-10-04 04:47:17 +00:00
2024-09-30 07:27:47 +00:00
waitForPostgresAvailability( ) {
if [ -z " $PG_DB_HOST " ] ; then
tlog "PostgreSQL host name is empty. Check env variables. Error. Exiting java setup"
exit 2
else
MAX_RETRIES = 50
RETRYSECONDS = 10
retry_count = 0
2024-12-06 05:19:27 +00:00
local unix_socket_directory = $( get_unix_socket_directory " $POSTGRES_DB_PATH " )
2024-09-30 07:27:47 +00:00
while true; do
2024-12-06 05:19:27 +00:00
su postgres -c " pg_isready -h $unix_socket_directory -p ' ${ PG_DB_PORT } ' "
2024-09-30 07:27:47 +00:00
status = $?
case $status in
0)
tlog " PostgreSQL host ' $PG_DB_HOST ' is ready. "
break
; ;
1)
tlog " PostgreSQL host ' $PG_DB_HOST ' is rejecting connections e.g. due to being in recovery mode or not accepting connections eg. connections maxed out. "
; ;
2)
tlog " PostgreSQL host ' $PG_DB_HOST ' is not responding or running. "
; ;
3)
tlog "The connection check failed e.g. due to network issues or incorrect parameters."
; ;
*)
tlog " pg_isready exited with unexpected status code: $status "
break
; ;
esac
retry_count = $(( retry_count + 1 ))
if [ $retry_count -le $MAX_RETRIES ] ; then
tlog " PostgreSQL connection failed. Retrying attempt $retry_count / $MAX_RETRIES in $RETRYSECONDS seconds... "
sleep $RETRYSECONDS
else
tlog " Exceeded maximum retry attempts ( $MAX_RETRIES ). Exiting. "
# use exit code 2 to indicate that the script failed to connect to postgres and supervisor conf is set not to restart the program for 2.
exit 2
fi
done
fi
}
# for PostgreSQL, we use APPSMITH_DB_URL=postgresql://username:password@postgresserver:5432/dbname
# Args:
# conn_string (string): PostgreSQL connection string
# Returns:
# None
# Example:
# postgres syntax
# "postgresql://user:password@localhost:5432/appsmith"
# "postgresql://user:password@localhost/appsmith"
# "postgresql://user@localhost:5432/appsmith"
# "postgresql://user@localhost/appsmith"
extract_postgres_db_params( ) {
local conn_string = $1
# Use node to parse the URI and extract components
IFS = ' ' read -r USER PASSWORD HOST PORT DB <<< " $( node -e "
const connectionString = process.argv[ 1] ;
const pgUri = connectionString.startsWith( \" postgresql://\" )
? connectionString
: 'http://' + connectionString; //Prepend a fake scheme for URL parsing
const url = require( 'url' ) ;
const parsedUrl = new url.URL( pgUri) ;
// Extract the pathname and remove the leading '/'
const db = parsedUrl.pathname.substring( 1) ;
// Default the port to 5432 if it' s empty
const port = parsedUrl.port || '5432' ;
console.log( \` \$ { parsedUrl.username || '-' } \$ { parsedUrl.password || '-' } \$ { parsedUrl.hostname} \$ { port} \$ { db} \` ) ;
" " $conn_string ")"
# Now, set the environment variables
export PG_DB_USER = " $USER "
export PG_DB_PASSWORD = " $PASSWORD "
export PG_DB_HOST = " $HOST "
export PG_DB_PORT = " $PORT "
export PG_DB_NAME = " $DB "
}
2024-09-30 18:12:56 +00:00
init_pg_db( ) {
# Create the appsmith schema
echo "Initializing PostgreSQL with schema..."
# Check if APPSMITH_DB_URL is a PostgreSQL URL
if [ [ -n " $APPSMITH_DB_URL " && " $APPSMITH_DB_URL " = = postgres*://* ] ] ; then
echo "APPSMITH_DB_URL is a valid PostgreSQL URL."
# Check if the DB_HOST is local (localhost or 127.0.0.1)
if [ [ " $PG_DB_HOST " = = "localhost" || " $PG_DB_HOST " = = "127.0.0.1" ] ] ; then
2024-12-06 05:19:27 +00:00
local unix_socket_directory = $( get_unix_socket_directory " $POSTGRES_DB_PATH " )
2024-09-30 18:12:56 +00:00
# Check if the database exists
2024-12-06 05:19:27 +00:00
DB_CHECK = $( psql -h " $unix_socket_directory " -p " $PG_DB_PORT " -U " $POSTGRES_ADMIN_USER " -tAc " SELECT 1 FROM pg_database WHERE datname=' $PG_DB_NAME ' " )
2024-09-30 18:12:56 +00:00
if [ " $DB_CHECK " != "1" ] ; then
echo " Database $PG_DB_NAME does not exist. Creating database... "
2024-12-06 05:19:27 +00:00
psql -h " $unix_socket_directory " -p " $PG_DB_PORT " -U " $POSTGRES_ADMIN_USER " -c " CREATE DATABASE $PG_DB_NAME ; "
2024-09-30 18:12:56 +00:00
else
echo " Database $PG_DB_NAME already exists. "
fi
# Check if the schema exists
2024-12-06 05:19:27 +00:00
SCHEMA_CHECK = $( psql -h " $unix_socket_directory " -p " $PG_DB_PORT " -U " $POSTGRES_ADMIN_USER " -d " $PG_DB_NAME " -tAc "SELECT 1 FROM information_schema.schemata WHERE schema_name='appsmith'" )
2024-09-30 18:12:56 +00:00
# Create schema and user if not exists
if [ " $SCHEMA_CHECK " != "1" ] ; then
echo " Creating user ' $PG_DB_USER ' with password "
2024-12-06 05:19:27 +00:00
psql -h " $unix_socket_directory " -p " $PG_DB_PORT " -U " $POSTGRES_ADMIN_USER " -d " $PG_DB_NAME " -c " CREATE USER \" $PG_DB_USER \" WITH PASSWORD ' $PG_DB_PASSWORD '; "
2024-09-30 18:12:56 +00:00
echo "Schema 'appsmith' does not exist. Creating schema..."
2024-12-06 05:19:27 +00:00
psql -h " $unix_socket_directory " -p " $PG_DB_PORT " -U " $POSTGRES_ADMIN_USER " -d " $PG_DB_NAME " -c "CREATE SCHEMA appsmith;"
2024-09-30 18:12:56 +00:00
fi
2024-10-07 10:53:09 +00:00
echo "Creating pg_trgm extension..."
2024-12-06 05:19:27 +00:00
psql -h " $unix_socket_directory " -p " $PG_DB_PORT " -U " $POSTGRES_ADMIN_USER " -d " $PG_DB_NAME " -c "CREATE EXTENSION IF NOT EXISTS pg_trgm;"
# Grant permissions to the user on the schema
USER = $PG_DB_USER SCHEMA = "appsmith" DB = $PG_DB_NAME HOST = $PG_DB_HOST PORT = $PG_DB_PORT grant_permissions_for_local_db_schema
2024-09-30 18:12:56 +00:00
else
echo "Remote PostgreSQL detected, running as current user."
PGPASSWORD = $PG_DB_PASSWORD psql -h " $PG_DB_HOST " -p " $PG_DB_PORT " -U " $PG_DB_USER " -d " $PG_DB_NAME " -c "CREATE SCHEMA IF NOT EXISTS appsmith;"
2024-10-07 10:53:09 +00:00
echo "Creating pg_trgm extension..."
2024-10-17 10:49:36 +00:00
PGPASSWORD = $PG_DB_PASSWORD psql -h " $PG_DB_HOST " -p " $PG_DB_PORT " -U " $PG_DB_USER " -d " $PG_DB_NAME " -c "CREATE EXTENSION IF NOT EXISTS pg_trgm;"
2024-09-30 18:12:56 +00:00
fi
# Check if the schema creation was successful
if [ $? -eq 0 ] ; then
echo "Schema 'appsmith' created or already exists."
else
echo "Failed to create schema 'appsmith'."
exit 1
fi
echo "PostgreSQL initialization completed."
fi
}
2024-10-04 04:47:17 +00:00
# Utility function to grant permissions to a user on a schema in a database on a host and port in PostgreSQL database
# Args:
# USER (string): User to grant permissions to
# SCHEMA (string): Schema to grant permissions on
# DB (string): Database to grant permissions on
# HOST (string): Host to grant permissions on
# PORT (int): Port to grant permissions on
# Returns:
# None
# Example:
2024-12-06 05:19:27 +00:00
# USER="user" SCHEMA="schema" DB="db" HOST="host" PORT="port" grant_permissions_for_local_db_schema
grant_permissions_for_local_db_schema( ) {
2024-10-04 04:47:17 +00:00
local user = ${ USER - $DB_USER } schema = ${ SCHEMA - $DB_SCHEMA } db = ${ DB - $DB_NAME } host = ${ HOST - $DB_HOST } port = ${ PORT - $DB_PORT }
2024-12-06 05:19:27 +00:00
local unix_socket_directory = $( get_unix_socket_directory " $POSTGRES_DB_PATH " )
2024-10-04 04:47:17 +00:00
tlog " Granting permissions to user ' ${ user } ' on schema ' $schema ' in database ' $db ' on host ' $host ' and port ' $port '... "
2024-12-06 05:19:27 +00:00
psql -h " $unix_socket_directory " -p " $port " -U " $POSTGRES_ADMIN_USER " -d " $db " -c " GRANT ALL PRIVILEGES ON SCHEMA ${ schema } TO ${ user } ; "
psql -h " $unix_socket_directory " -p " $port " -U " $POSTGRES_ADMIN_USER " -d " $db " -c " GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA ${ schema } TO ${ user } ; "
psql -h " $unix_socket_directory " -p " $port " -U " $POSTGRES_ADMIN_USER " -d " $db " -c " ALTER DEFAULT PRIVILEGES IN SCHEMA ${ schema } GRANT ALL PRIVILEGES ON TABLES TO ${ user } ; "
psql -h " $unix_socket_directory " -p " $port " -U " $POSTGRES_ADMIN_USER " -d " $db " -c " GRANT CONNECT ON DATABASE ${ db } TO ${ user } ; "
}
get_unix_socket_directory( ) {
local postgres_db_path = ${ 1 :- " $POSTGRES_DB_PATH " }
local unix_socket_directory
unix_socket_directory = $( grep -E "^unix_socket_directories" " $postgres_db_path /postgresql.conf " | sed -E "s/.*= (.*).*/\1/" | cut -d',' -f1)
# If unix_socket_directory is empty, default to /var/run/postgresql
if [ -z " $unix_socket_directory " ] ; then
unix_socket_directory = "/var/run/postgresql"
fi
echo " $unix_socket_directory "
2024-10-04 04:47:17 +00:00
}
2024-09-30 07:27:47 +00:00
# Example usage of the functions
# waitForPostgresAvailability
2024-09-30 18:12:56 +00:00
# extract_postgres_db_params "postgresql://user:password@localhost:5432/dbname"
2024-10-04 04:47:17 +00:00
# init_pg_db
2024-12-06 05:19:27 +00:00
# USER="user" SCHEMA="schema" DB="db" HOST="host" PORT="port" grant_permissions_for_local_db_schema
# get_unix_socket_directory "/var/lib/postgresql/12/main"