From a03867de69fb88a5d66c8466b9da9c091edf2899 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 7 Nov 2025 10:35:57 +0100 Subject: [PATCH] Add setup_postgresql_db function for database creation Introduces setup_postgresql_db to automate PostgreSQL database and user creation, extension installation, role configuration, and credential management. Supports options for superuser privileges, schema permissions, and compatibility settings for frameworks like Django and Rails. --- misc/tools.func | 97 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/misc/tools.func b/misc/tools.func index b55f1de1b..8a39009d3 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -3818,6 +3818,103 @@ function setup_postgresql() { fi } +# ------------------------------------------------------------------------------ +# Creates PostgreSQL database with user and optional extensions +# +# Description: +# - Creates PostgreSQL role with login and password +# - Creates database with UTF8 encoding and template0 +# - Installs optional extensions (postgis, pgvector, etc.) +# - Configures ALTER ROLE settings for Django/Rails compatibility +# - Saves credentials to file +# - Exports variables for use in calling script +# +# Usage: +# DB_NAME="myapp_db" DB_USER="myapp_user" setup_postgresql_db +# DB_NAME="immich" DB_USER="immich" DB_EXTENSIONS="pgvector" setup_postgresql_db +# DB_NAME="ghostfolio" DB_USER="ghostfolio" DB_GRANT_SUPERUSER="true" setup_postgresql_db +# DB_NAME="adventurelog" DB_USER="adventurelog" DB_EXTENSIONS="postgis" setup_postgresql_db +# +# Variables: +# DB_NAME - Database name (required) +# DB_USER - Database user (required) +# DB_PASS - Database password (optional, auto-generated if empty) +# DB_EXTENSIONS - Comma-separated list of extensions (optional, e.g. "postgis,pgvector") +# DB_GRANT_SUPERUSER - Grant SUPERUSER privilege (optional, "true" to enable, security risk!) +# DB_SCHEMA_PERMS - Grant schema-level permissions (optional, "true" to enable) +# DB_SKIP_ALTER_ROLE - Skip ALTER ROLE settings (optional, "true" to skip) +# DB_CREDS_FILE - Credentials file path (optional, default: ~/pg_${DB_NAME}.creds) +# +# Exports: +# PG_DB_NAME, PG_DB_USER, PG_DB_PASS - For use in calling script +# ------------------------------------------------------------------------------ + +function setup_postgresql_db() { + # Validation + if [[ -z "$DB_NAME" || -z "$DB_USER" ]]; then + msg_error "DB_NAME and DB_USER must be set before calling setup_postgresql_db" + return 1 + fi + + # Generate password if not provided + if [[ -z "$DB_PASS" ]]; then + DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13) + fi + + msg_info "Setting up PostgreSQL Database" + $STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';" + $STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;" + + # Install extensions (comma-separated) + if [[ -n "$DB_EXTENSIONS" ]]; then + IFS=',' read -ra EXT_LIST <<<"$DB_EXTENSIONS" + for ext in "${EXT_LIST[@]}"; do + ext=$(echo "$ext" | xargs) # Trim whitespace + $STD sudo -u postgres psql -d "$DB_NAME" -c "CREATE EXTENSION IF NOT EXISTS $ext;" + done + fi + + # ALTER ROLE settings for Django/Rails compatibility (unless skipped) + if [[ "$DB_SKIP_ALTER_ROLE" != "true" ]]; then + $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';" + $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';" + $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC';" + fi + + # Schema permissions (if requested) + if [[ "$DB_SCHEMA_PERMS" == "true" ]]; then + $STD sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;" + $STD sudo -u postgres psql -c "ALTER USER $DB_USER CREATEDB;" + $STD sudo -u postgres psql -d "$DB_NAME" -c "GRANT ALL ON SCHEMA public TO $DB_USER;" + $STD sudo -u postgres psql -d "$DB_NAME" -c "GRANT CREATE ON SCHEMA public TO $DB_USER;" + $STD sudo -u postgres psql -d "$DB_NAME" -c "ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO $DB_USER;" + $STD sudo -u postgres psql -d "$DB_NAME" -c "ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO $DB_USER;" + fi + + # Superuser grant (if requested - WARNING!) + if [[ "$DB_GRANT_SUPERUSER" == "true" ]]; then + msg_warn "Granting SUPERUSER privilege (security risk!)" + $STD sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $DB_NAME to $DB_USER;" + $STD sudo -u postgres psql -c "ALTER USER $DB_USER WITH SUPERUSER;" + fi + + # Save credentials + local CREDS_FILE="${DB_CREDS_FILE:-~/pg_${DB_NAME}.creds}" + { + echo "PostgreSQL Credentials" + echo "Database: $DB_NAME" + echo "User: $DB_USER" + echo "Password: $DB_PASS" + } >>"$CREDS_FILE" + + msg_ok "Set up PostgreSQL Database" + + # Export for use in calling script + export PG_DB_NAME="$DB_NAME" + export PG_DB_USER="$DB_USER" + export PG_DB_PASS="$DB_PASS" +} + # ------------------------------------------------------------------------------ # Installs rbenv and ruby-build, installs Ruby and optionally Rails. #