PostDock icon indicating copy to clipboard operation
PostDock copied to clipboard

Support for multiple users and multiple databases

Open wilmardo opened this issue 4 years ago • 0 comments

Currently I am using the upstream image and a replica with hot_standby=on. I mount a shell script to /docker-entrypoint-initdb.d/ to create multiple users and multiple databases. These script read from an environment variable in the format <user>:<password>:<db1>,<db2>|<second_user>:<password>:<db2>

# Create user harbor with password pass when non existing then create databases registry and clair and grant access to harbor when databases are non existing.
# Then create user test with password pass when non existing and create test_db and grant access to test.
POSTGRES_MULTIPLE_DATABASES="harbor:pass:registry,clair,notary_server,notary_signer|test:pass:test_db"
#!/bin/bash

set -e
set -u

# Source for the create user logic:
# https://stackoverflow.com/a/49858797
function create_user() {
	local user=$1
	local password=$2
	echo "  Creating user '$user'"
	psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL
    DO \$\$
    BEGIN
      CREATE USER $user WITH ENCRYPTED PASSWORD '$password';
      EXCEPTION WHEN OTHERS THEN
      RAISE NOTICE 'not creating role $user -- it already exists';
    END
    \$\$;
EOSQL
}

function create_database() {
	local database=$1
	local owner=$2
	echo "  Creating database '$database' and granting to '$owner'"
	psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL
    DO \$\$
    BEGIN
      CREATE DATABASE $database;
      GRANT ALL PRIVILEGES ON DATABASE $database TO $owner;
      EXCEPTION WHEN OTHERS THEN
      RAISE NOTICE 'not creating and granting database $database -- it already exists';
    END
    \$\$;
EOSQL
}

function main() {
  if [ -n "$POSTGRES_MULTIPLE_DATABASES" ]; then
    echo "Multiple database creation requested: $POSTGRES_MULTIPLE_DATABASES"
    # Declare variables
    local user
    local password
    local db_list

    for entry in $(echo "$POSTGRES_MULTIPLE_DATABASES" | tr '|' ' '); do
      # Split user
      user=$(echo "$entry" | tr ':' ' ' | awk  '{print $1}')
      # Split password
      password=$(echo "$entry" | tr ':' ' ' | awk  '{print $2}')
      # Split access list
      db_list=$(echo "$entry" | tr ':' ' ' | awk  '{print $3}')

      create_user "$user" "$password"
      for db in $(echo "$db_list" | tr ',' ' '); do
        create_database "$db" "$user"
      done
    done
    echo "Multiple databases created"
  fi
}

main

Is this something you would like to be built in the Docker containers and made available within the Helm chart?

Suggestions for improvements are welcome to!

wilmardo avatar Nov 26 '19 15:11 wilmardo