kopia lustrzana https://github.com/kartoza/docker-postgis
fix issue with multiple db creation and add test for this (#443)
* fix issue with multiple db creation and add test for thiskubectl-fix^2
rodzic
80b4b715b6
commit
74bb497307
|
@ -39,6 +39,7 @@ jobs:
|
|||
- extensions
|
||||
- logical_replication
|
||||
- init_scripts
|
||||
- multiple_databases
|
||||
include:
|
||||
- distro: debian
|
||||
imageVersion: bookworm
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
|
||||
version: '2.1'
|
||||
|
||||
volumes:
|
||||
pg-db-data-dir:
|
||||
pg-db-schema-dir:
|
||||
|
||||
|
||||
services:
|
||||
pg-database:
|
||||
image: 'kartoza/postgis:${TAG:-manual-build}'
|
||||
restart: 'always'
|
||||
# You can optionally mount to volume, to play with the persistence and
|
||||
# observe how the node will behave after restarts.
|
||||
volumes:
|
||||
- pg-db-data-dir:/var/lib/postgresql
|
||||
- ./tests:/tests
|
||||
- ../utils:/lib/utils
|
||||
environment:
|
||||
POSTGRES_DB: 'gis,data'
|
||||
POSTGRES_PASS: 'docker'
|
||||
ALL_DATABASES: TRUE
|
||||
SCHEMA_NAME: demo
|
||||
healthcheck:
|
||||
interval: 60s
|
||||
timeout: 30s
|
||||
retries: 3
|
||||
test: "PGPASSWORD=docker pg_isready -h 127.0.0.1 -U docker -d gis"
|
||||
|
||||
pg-schema:
|
||||
image: 'kartoza/postgis:${TAG:-manual-build}'
|
||||
restart: 'always'
|
||||
# You can optionally mount to volume, to play with the persistence and
|
||||
# observe how the node will behave after restarts.
|
||||
volumes:
|
||||
- pg-db-schema-dir:/var/lib/postgresql
|
||||
- ./tests:/tests
|
||||
- ../utils:/lib/utils
|
||||
environment:
|
||||
POSTGRES_DB: 'gis,data'
|
||||
POSTGRES_PASS: 'docker'
|
||||
ALL_DATABASES: FALSE
|
||||
SCHEMA_NAME: demo
|
||||
healthcheck:
|
||||
interval: 60s
|
||||
timeout: 30s
|
||||
retries: 3
|
||||
test: "PGPASSWORD=docker pg_isready -h 127.0.0.1 -U docker -d gis"
|
||||
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# exit immediately if test fails
|
||||
set -e
|
||||
|
||||
source ../test-env.sh
|
||||
if [[ $(dpkg -l | grep "docker-compose") > /dev/null ]];then
|
||||
VERSION='docker-compose'
|
||||
else
|
||||
VERSION='docker compose'
|
||||
fi
|
||||
|
||||
|
||||
# Run service as root
|
||||
${VERSION} up -d pg-database
|
||||
|
||||
if [[ -n "${PRINT_TEST_LOGS}" ]]; then
|
||||
${VERSION} logs -f &
|
||||
fi
|
||||
|
||||
sleep 30
|
||||
|
||||
# Preparing all databases and all schemas
|
||||
until ${VERSION} exec -T pg-database pg_isready; do
|
||||
sleep 1
|
||||
done;
|
||||
|
||||
# Execute tests
|
||||
${VERSION} exec -T pg-database /bin/bash /tests/test_schemas.sh
|
||||
|
||||
|
||||
${VERSION} down -v
|
||||
|
||||
|
||||
# Run service for pg-schema
|
||||
${VERSION} up -d pg-schema
|
||||
|
||||
if [[ -n "${PRINT_TEST_LOGS}" ]]; then
|
||||
${VERSION} logs -f &
|
||||
fi
|
||||
|
||||
sleep 30
|
||||
|
||||
# Preparing all databases and single schema
|
||||
until ${VERSION} exec -T pg-schema pg_isready; do
|
||||
sleep 1
|
||||
done;
|
||||
|
||||
# Execute tests
|
||||
${VERSION} exec -T pg-schema /bin/bash /tests/test_schemas.sh
|
||||
|
||||
|
||||
${VERSION} down -v
|
|
@ -0,0 +1,50 @@
|
|||
import unittest
|
||||
import psycopg2
|
||||
import os
|
||||
|
||||
|
||||
class TestSchemaExistence(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.db_host = os.environ.get('POSTGRES_HOST', 'localhost')
|
||||
self.db_port = os.environ.get('POSTGRES_PORT', '5432')
|
||||
self.db_user = os.environ.get('POSTGRES_USER', 'docker')
|
||||
self.db_pass = os.environ.get('POSTGRES_PASS', 'docker')
|
||||
self.db_names = os.environ.get('POSTGRES_DB', '').split(',')
|
||||
self.schemas = os.environ.get('SCHEMA_NAME', '').split(',')
|
||||
self.all_databases = os.environ.get('ALL_DATABASES', 'TRUE').lower() == 'true'
|
||||
|
||||
def connect_to_db(self, db_name):
|
||||
try:
|
||||
conn = psycopg2.connect(
|
||||
dbname=db_name,
|
||||
user=self.db_user,
|
||||
password=self.db_pass,
|
||||
host=self.db_host,
|
||||
port=self.db_port
|
||||
)
|
||||
return conn
|
||||
except psycopg2.Error as e:
|
||||
self.fail(f"Failed to connect to the database: {e}")
|
||||
|
||||
def test_schema_existence(self):
|
||||
for idx, db_name in enumerate(self.db_names):
|
||||
conn = self.connect_to_db(db_name)
|
||||
cursor = conn.cursor()
|
||||
|
||||
for schema in self.schemas:
|
||||
query = f"SELECT schema_name, catalog_name FROM information_schema.schemata \
|
||||
WHERE schema_name = '{schema}' and catalog_name = '{db_name}';"
|
||||
cursor.execute(query)
|
||||
exists = cursor.fetchone()
|
||||
|
||||
if not self.all_databases and idx > 0:
|
||||
self.assertIsNone(exists, f"Schema '{schema}' should not exist in database '{db_name}'")
|
||||
else:
|
||||
self.assertIsNotNone(exists, f"Schema '{schema}' does not exist in database '{db_name}'")
|
||||
|
||||
conn.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -0,0 +1,13 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
source /scripts/env-data.sh
|
||||
|
||||
# execute tests
|
||||
pushd /tests
|
||||
|
||||
PGHOST=localhost \
|
||||
PGDATABASE=gis \
|
||||
PYTHONPATH=/lib \
|
||||
python3 -m unittest -v test_schema_existence.TestSchemaExistence
|
|
@ -392,9 +392,10 @@ if [ -n "${POSTGRES_INITDB_ARGS}" ]; then
|
|||
INITDB_EXTRA_ARGS=${POSTGRES_INITDB_ARGS}
|
||||
fi
|
||||
|
||||
list=$(echo "${POSTGRES_DBNAME}" | tr ',' ' ')
|
||||
arr=("${list}")
|
||||
SINGLE_DB=${arr[0]}
|
||||
IFS=','
|
||||
read -a dbarr <<< "$POSTGRES_DBNAME"
|
||||
SINGLE_DB=${dbarr[0]}
|
||||
export ${SINGLE_DB}
|
||||
|
||||
if [ -z "${TIMEZONE}" ]; then
|
||||
TIMEZONE='Etc/UTC'
|
||||
|
@ -437,6 +438,8 @@ function restart_postgres {
|
|||
|
||||
function entry_point_script {
|
||||
SETUP_LOCKFILE="${SCRIPTS_LOCKFILE_DIR}/.entry_point.lock"
|
||||
IFS=','
|
||||
read -a dbarr <<< "$POSTGRES_DBNAME"
|
||||
# If lockfile doesn't exists, proceed.
|
||||
if [[ ! -f "${SETUP_LOCKFILE}" ]] || [[ "${IGNORE_INIT_HOOK_LOCKFILE}" =~ [Tt][Rr][Uu][Ee] ]]; then
|
||||
if find "/docker-entrypoint-initdb.d" -mindepth 1 -print -quit 2>/dev/null | grep -q .; then
|
||||
|
@ -447,7 +450,7 @@ function entry_point_script {
|
|||
if [[ "${ALL_DATABASES}" =~ [Ff][Aa][Ll][Ss][Ee] ]]; then
|
||||
psql "${SINGLE_DB}" -U ${POSTGRES_USER} -p 5432 -h localhost -f "${f}" || true
|
||||
else
|
||||
for db in $(echo "${POSTGRES_DBNAME}" | tr ',' ' '); do
|
||||
for db in "${dbarr[@]}";do
|
||||
psql "${db}" -U ${POSTGRES_USER} -p 5432 -h localhost -f "${f}" || true
|
||||
done
|
||||
fi;;
|
||||
|
@ -455,7 +458,7 @@ function entry_point_script {
|
|||
if [[ "${ALL_DATABASES}" =~ [Ff][Aa][Ll][Ss][Ee] ]]; then
|
||||
gunzip < "$f" | psql "${SINGLE_DB}" -U ${POSTGRES_USER} -p 5432 -h localhost || true
|
||||
else
|
||||
for db in $(echo "${POSTGRES_DBNAME}" | tr ',' ' '); do
|
||||
for db in "${dbarr[@]}";do
|
||||
gunzip < "$f" | psql "${db}" -U ${POSTGRES_USER} -p 5432 -h localhost || true
|
||||
done
|
||||
fi;;
|
||||
|
@ -493,7 +496,7 @@ function configure_replication_permissions {
|
|||
}
|
||||
|
||||
function streaming_replication {
|
||||
until ${START_COMMAND} "${PG_BASEBACKUP} -X stream -h ${REPLICATE_FROM} -p ${REPLICATE_PORT} -D ${DATADIR} -U ${REPLICATION_USER} -R -vP -w --label=gis_pg_custer"
|
||||
until START_COMMAND "${PG_BASEBACKUP} -X stream -h ${REPLICATE_FROM} -p ${REPLICATE_PORT} -D ${DATADIR} -U ${REPLICATION_USER} -R -vP -w --label=gis_pg_custer"
|
||||
do
|
||||
echo -e "[Entrypoint] \e[1;31m Waiting for master to connect... \033[0m"
|
||||
sleep 1s
|
||||
|
|
|
@ -101,7 +101,10 @@ export PGPASSWORD=${POSTGRES_PASS}
|
|||
# Create a default db called 'gis' or $POSTGRES_DBNAME that you can use to get up and running quickly
|
||||
# It will be owned by the docker db user
|
||||
# Since we now pass a comma separated list in database creation we need to search for all databases as a test
|
||||
for db in $(echo "${POSTGRES_DBNAME}" | tr ',' ' '); do
|
||||
IFS=','
|
||||
read -a dbarr <<< "$POSTGRES_DBNAME"
|
||||
|
||||
for db in "${dbarr[@]}";do
|
||||
RESULT=$(su - postgres -c "psql -t -c \"SELECT count(1) from pg_database where datname='${db}';\"")
|
||||
if [[ ${RESULT} -eq 0 ]]; then
|
||||
echo -e "\e[32m [Entrypoint] Create database \e[1;31m ${db} \033[0m"
|
||||
|
@ -117,16 +120,16 @@ for db in $(echo "${POSTGRES_DBNAME}" | tr ',' ' '); do
|
|||
extension_install "${db}" "${ext}"
|
||||
# enable extensions in template1 if env variable set to true
|
||||
if [[ "$(boolean "${POSTGRES_TEMPLATE_EXTENSIONS}")" =~ [Tt][Rr][Uu][Ee] ]] ; then
|
||||
extension_install template1
|
||||
extension_install template1 "${ext}"
|
||||
fi
|
||||
done
|
||||
echo -e "\e[32m [Entrypoint] loading legacy sql in database \e[1;31m ${db} \033[0m"
|
||||
psql "${db}" -U "${POSTGRES_USER}" -p 5432 -h localhost -f "${SQLDIR}"/legacy_minimal.sql || true
|
||||
psql "${db}" -U "${POSTGRES_USER}" -p 5432 -h localhost -f "${SQLDIR}"/legacy_gist.sql || true
|
||||
if [[ "$WAL_LEVEL" =~ [Ll][Oo][Gg][Ii][Cc][Aa][Ll] ]];then
|
||||
psql "${db}" -U "${POSTGRES_USER}" -p 5432 -h localhost -c "CREATE PUBLICATION logical_replication;"
|
||||
fi
|
||||
|
||||
if [[ "${WAL_LEVEL,,}" == "logical" ]]; then
|
||||
psql -d "${db}" -U "${POSTGRES_USER}" -p 5432 -h localhost -c "CREATE PUBLICATION logical_replication;"
|
||||
fi
|
||||
else
|
||||
echo -e "\e[32m [Entrypoint] Database \e[1;31m ${db} \e[32m already exists \033[0m"
|
||||
|
||||
|
@ -136,7 +139,7 @@ done
|
|||
|
||||
|
||||
# Create schemas in the DB
|
||||
for db in $(echo "${POSTGRES_DBNAME}" | tr ',' ' '); do
|
||||
for db in "${dbarr[@]}";do
|
||||
for schema in $(echo "${SCHEMA_NAME}" | tr ',' ' '); do
|
||||
SCHEMA_RESULT=$(psql -t "${db}" -U "${POSTGRES_USER}" -p 5432 -h localhost -c "select count(1) from information_schema.schemata where schema_name = '${schema}' and catalog_name = '${db}';")
|
||||
if [[ ${SCHEMA_RESULT} -eq 0 ]] && [[ "${ALL_DATABASES}" =~ [Ff][Aa][Ll][Ss][Ee] ]]; then
|
||||
|
|
|
@ -7,12 +7,15 @@ source /scripts/env-data.sh
|
|||
# Adapted from https://github.com/DanielDent/docker-postgres-replication
|
||||
# To set up replication
|
||||
if [[ ${RUN_AS_ROOT} =~ [Ff][Aa][Ll][Ss][Ee] ]];then
|
||||
echo "gosu ${USER_NAME}:${DB_GROUP_NAME} bash -c" > /tmp/gosu_subs.txt
|
||||
envsubst < /tmp/gosu_subs.txt > /tmp/gosu_command.txt
|
||||
START_COMMAND=$(cat /tmp/gosu_command.txt)
|
||||
rm /tmp/gosu_subs.txt /tmp/gosu_command.txt
|
||||
function START_COMMAND() {
|
||||
PARAM=$1
|
||||
gosu ${USER_NAME} bash -c "$1"
|
||||
}
|
||||
else
|
||||
START_COMMAND='su - postgres -c'
|
||||
function START_COMMAND() {
|
||||
PARAM=$1
|
||||
su postgres -c "$1"
|
||||
}
|
||||
fi
|
||||
|
||||
create_dir "${WAL_ARCHIVE}"
|
||||
|
@ -24,8 +27,9 @@ if [[ "$WAL_LEVEL" == 'replica' && "${REPLICATION}" =~ [Tt][Rr][Uu][Ee] ]]; then
|
|||
echo "Specify the master address/hostname in REPLICATE_FROM and REPLICATE_PORT variable."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
until ${START_COMMAND} "/usr/bin/pg_isready -h ${REPLICATE_FROM} -p ${REPLICATE_PORT}"
|
||||
until START_COMMAND "/usr/lib/postgresql/${POSTGRES_MAJOR_VERSION}/bin/pg_isready -h ${REPLICATE_FROM} -p ${REPLICATE_PORT}"
|
||||
do
|
||||
echo -e "[Entrypoint] \e[1;31m Waiting for master to ping... \033[0m"
|
||||
sleep 1s
|
||||
|
|
Ładowanie…
Reference in New Issue