From 22110be6a68318bb93059aa289c6f55a3dd09733 Mon Sep 17 00:00:00 2001 From: Admire Nyakudya Date: Sun, 20 Aug 2023 20:56:14 +0200 Subject: [PATCH] add option to deactivate cron installation, run bash script through shellcheck --- Dockerfile | 7 ++-- docker-compose.yml | 1 + scripts/docker-entrypoint.sh | 18 ++++----- scripts/env-data.sh | 76 +++++++++++++++++++++--------------- scripts/setup-conf.sh | 40 +++++++++---------- scripts/setup-database.sh | 50 ++++++++++++------------ scripts/setup-pg_hba.sh | 14 +++---- scripts/setup-replication.sh | 2 +- scripts/setup-ssl.sh | 18 ++++----- scripts/setup-user.sh | 4 +- scripts/setup.sh | 8 ++-- 11 files changed, 127 insertions(+), 111 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0b288413..8952ad59 100644 --- a/Dockerfile +++ b/Dockerfile @@ -75,7 +75,8 @@ ARG IMAGE_VERSION ARG POSTGRES_MAJOR_VERSION=15 ARG POSTGIS_MAJOR_VERSION=3 ARG POSTGIS_MINOR_RELEASE=4 -ARG TIMESCALE_VERSION=2-2.9.1 +# https://packagecloud.io/timescale/timescaledb +ARG TIMESCALE_VERSION=2-2.11.2 ARG BUILD_TIMESCALE=false @@ -83,8 +84,8 @@ ARG BUILD_TIMESCALE=false RUN set -eux \ && export DEBIAN_FRONTEND=noninteractive \ && apt-get update \ - && sh -c "echo \"deb http://apt.postgresql.org/pub/repos/apt/ ${IMAGE_VERSION}-pgdg main\" > /etc/apt/sources.list.d/pgdg.list" \ - && wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc -O- | apt-key add - \ + && wget -O- https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | sh -c 'cat > /usr/share/keyrings/postgresql.gpg' > /dev/null \ + && echo deb [arch=amd64,arm64,ppc64el signed-by=/usr/share/keyrings/postgresql.gpg] https://apt.postgresql.org/pub/repos/apt/ ${IMAGE_VERSION}-pgdg main | tee /etc/apt/sources.list.d/pgdg.list 2>/dev/null \ && apt-get -y --purge autoremove \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* \ diff --git a/docker-compose.yml b/docker-compose.yml index cf526fe4..3cc6504a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,6 +20,7 @@ services: # Add extensions you need to be enabled by default in the DB. Default are the five specified below - POSTGRES_MULTIPLE_EXTENSIONS=postgis,hstore,postgis_topology,postgis_raster,pgrouting - RUN_AS_ROOT=true + - ACTIVATE_CRON=False ports: - "25432:5432" restart: on-failure diff --git a/scripts/docker-entrypoint.sh b/scripts/docker-entrypoint.sh index de3e5ad3..ea71e4c0 100755 --- a/scripts/docker-entrypoint.sh +++ b/scripts/docker-entrypoint.sh @@ -29,7 +29,7 @@ if [[ ${RUN_AS_ROOT} =~ [Ff][Aa][Ll][Ss][Ee] ]];then # Add group if [ ! $(getent group "${DB_GROUP_NAME}") ]; then - groupadd -r "${DB_GROUP_NAME}" -g ${GROUP_ID} + groupadd -r "${DB_GROUP_NAME}" -g "${GROUP_ID}" fi # Add user to system @@ -40,7 +40,7 @@ if [[ ${RUN_AS_ROOT} =~ [Ff][Aa][Ll][Ss][Ee] ]];then fi if [[ "${REPLICATION}" =~ [Tt][Rr][Uu][Ee] ]] ; then - echo "/home/"${USER_NAME}"/.pgpass" > /tmp/pg_subs.txt + echo "/home/${USER_NAME}/.pgpass" > /tmp/pg_subs.txt envsubst < /tmp/pg_subs.txt > /tmp/pass_command.txt PGPASSFILE=$(cat /tmp/pass_command.txt) rm /tmp/pg_subs.txt /tmp/pass_command.txt @@ -70,12 +70,12 @@ if [[ -z "$REPLICATE_FROM" ]]; then else # This means this is a slave/replication instance. echo -e "[Entrypoint] Setup replicant database \033[0m" - create_dir ${WAL_ARCHIVE} + create_dir "${WAL_ARCHIVE}" if [[ ${RUN_AS_ROOT} =~ [Ff][Aa][Ll][Ss][Ee] ]];then non_root_permission "${USER_NAME}" "${DB_GROUP_NAME}" else - chown -R postgres:postgres ${DATADIR} ${WAL_ARCHIVE} - chmod -R 750 ${DATADIR} ${WAL_ARCHIVE} + chown -R postgres:postgres "${DATADIR}" "${WAL_ARCHIVE}" + chmod -R 750 "${DATADIR}" "${WAL_ARCHIVE}" fi source /scripts/setup-replication.sh fi @@ -92,7 +92,7 @@ if [[ $# -eq 0 ]];then else echo -e "[Entrypoint] \e[1;31m Postgres initialisation process completed .... restarting in foreground with gosu \033[0m" non_root_permission "${USER_NAME}" "${DB_GROUP_NAME}" - exec gosu $USER_NAME bash -c "$SETVARS $POSTGRES -D $DATADIR -c config_file=$CONF" + exec gosu "${USER_NAME}" bash -c "$SETVARS $POSTGRES -D $DATADIR -c config_file=$CONF" fi @@ -105,13 +105,13 @@ if [[ "${1:0:1}" = '-' ]]; then if [[ ${RUN_AS_ROOT} =~ [Tt][Rr][Uu][Ee] ]];then set -- postgres "$@" else - set -- gosu $USER_NAME "$@" + set -- gosu "${USER_NAME}" "$@" fi fi -echo "The actual command running is "$@"" + if [[ ${RUN_AS_ROOT} =~ [Tt][Rr][Uu][Ee] ]];then exec su - "$@" else - exec gosu $USER_NAME - "$@" + exec gosu "${USER_NAME}" - "$@" fi diff --git a/scripts/env-data.sh b/scripts/env-data.sh index 2f7247b1..b3ac0c19 100644 --- a/scripts/env-data.sh +++ b/scripts/env-data.sh @@ -72,8 +72,8 @@ DATA_PATH=$1 if [[ ! -d ${DATA_PATH} ]]; then - echo "Creating" ${DATA_PATH} "directory" - mkdir -p ${DATA_PATH} + echo "Creating" "${DATA_PATH}" "directory" + mkdir -p "${DATA_PATH}" fi } @@ -81,9 +81,10 @@ function generate_random_string() { STRING_LENGTH=$1 random_pass_string=$(cat /dev/urandom | tr -dc '[:alnum:]' | head -c "${STRING_LENGTH}") if [[ ! -f /scripts/.pass_${STRING_LENGTH}.txt ]]; then - echo ${random_pass_string} > /scripts/.pass_${STRING_LENGTH}.txt + echo "${random_pass_string}" > /scripts/.pass_"${STRING_LENGTH}".txt fi - export RAND=$(cat /scripts/.pass_${STRING_LENGTH}.txt) + RAND=$(cat /scripts/.pass_"${STRING_LENGTH}".txt) + export RAND } # Make sure we have a user set up @@ -328,11 +329,21 @@ if [ -z "$EXTRA_CONF" ]; then EXTRA_CONF="" fi +if [ -z "$ACTIVATE_CRON" ]; then + ACTIVATE_CRON=TRUE +fi + if [ -z "${SHARED_PRELOAD_LIBRARIES}" ]; then if [[ $(dpkg -l | grep "timescaledb") > /dev/null ]];then - SHARED_PRELOAD_LIBRARIES='pg_cron,timescaledb' + if [[ ${ACTIVATE_CRON} =~ [Tt][Rr][Uu][Ee] ]];then + SHARED_PRELOAD_LIBRARIES='pg_cron,timescaledb' + else + SHARED_PRELOAD_LIBRARIES='timescaledb' + fi else - SHARED_PRELOAD_LIBRARIES='pg_cron' + if [[ ${ACTIVATE_CRON} =~ [Tt][Rr][Uu][Ee] ]];then + SHARED_PRELOAD_LIBRARIES='pg_cron' + fi fi fi @@ -381,8 +392,8 @@ if [ -n "${POSTGRES_INITDB_ARGS}" ]; then INITDB_EXTRA_ARGS=${POSTGRES_INITDB_ARGS} fi -list=(`echo ${POSTGRES_DBNAME} | tr ',' ' '`) -arr=(${list}) +list=$(echo "${POSTGRES_DBNAME}" | tr ',' ' ') +arr=("${list}") SINGLE_DB=${arr[0]} if [ -z "${TIMEZONE}" ]; then @@ -391,12 +402,12 @@ fi # usable function definitions function kill_postgres { - PID=`cat ${PG_PID}` - kill -TERM ${PID} + PID=$(cat "${PG_PID}") + kill -TERM "${PID}" # Wait for background postgres main process to exit # wait until PID file gets deleted - while ls -A ${PG_PID} 2> /dev/null; do + while ls -A "${PG_PID}" 2> /dev/null; do sleep 1 done @@ -434,21 +445,21 @@ function entry_point_script { case "$f" in *.sql) echo "$0: running $f"; if [[ "${ALL_DATABASES}" =~ [Ff][Aa][Ll][Ss][Ee] ]]; then - psql ${SINGLE_DB} -U ${POSTGRES_USER} -p 5432 -h localhost -f ${f} || true + psql "${SINGLE_DB}" -U ${POSTGRES_USER} -p 5432 -h localhost -f "${f}" || true else - for db in $(echo ${POSTGRES_DBNAME} | tr ',' ' '); do - psql ${db} -U ${POSTGRES_USER} -p 5432 -h localhost -f ${f} || true + for db in $(echo "${POSTGRES_DBNAME}" | tr ',' ' '); do + psql "${db}" -U ${POSTGRES_USER} -p 5432 -h localhost -f "${f}" || true done fi;; *.sql.gz) echo "$0: running $f"; if [[ "${ALL_DATABASES}" =~ [Ff][Aa][Ll][Ss][Ee] ]]; then - gunzip < "$f" | psql ${SINGLE_DB} -U ${POSTGRES_USER} -p 5432 -h localhost || true + gunzip < "$f" | psql "${SINGLE_DB}" -U ${POSTGRES_USER} -p 5432 -h localhost || true else - for db in $(echo ${POSTGRES_DBNAME} | tr ',' ' '); do - gunzip < "$f" | psql ${db} -U ${POSTGRES_USER} -p 5432 -h localhost || true + for db in $(echo "${POSTGRES_DBNAME}" | tr ',' ' '); do + gunzip < "$f" | psql "${db}" -U ${POSTGRES_USER} -p 5432 -h localhost || true done fi;; - *.sh) echo "$0: running $f"; . $f || true;; + *.sh) echo "$0: running $f"; . "$f" || true;; *) echo "$0: ignoring $f" ;; esac echo @@ -472,8 +483,8 @@ function configure_replication_permissions { non_root_permission "${USER_NAME}" "${DB_GROUP_NAME}" else - chown -R postgres:postgres ${DATADIR} ${WAL_ARCHIVE} - chmod -R 750 ${DATADIR} ${WAL_ARCHIVE} + chown -R postgres:postgres "${DATADIR}" ${WAL_ARCHIVE} + chmod -R 750 "${DATADIR}" ${WAL_ARCHIVE} echo -e "[Entrypoint] \e[1;31m Setup data permissions for replication as root user \033[0m" chown -R postgres:postgres $(getent passwd postgres | cut -d: -f6) su - postgres -c "echo \"${REPLICATE_FROM}:${REPLICATE_PORT}:*:${REPLICATION_USER}:${REPLICATION_PASS}\" > ~/.pgpass" @@ -486,9 +497,9 @@ function streaming_replication { do echo -e "[Entrypoint] \e[1;31m Waiting for master to connect... \033[0m" sleep 1s - if [[ "$(ls -A ${DATADIR})" ]]; then + if [[ "$(ls -A "${DATADIR}")" ]]; then echo -e "[Entrypoint] \e[1;31m Need empty folder. Cleaning directory... \033[0m" - rm -rf ${DATADIR}/* + rm -rf "${DATADIR:?}/"* fi done @@ -518,20 +529,21 @@ function over_write_conf() { function extension_install() { DATABASE=$1 + DB_EXTENSION=$2 IFS=':' - read -a strarr <<< "$ext" + read -a strarr <<< "${DB_EXTENSION}" EXTENSION_NAME=${strarr[0]} EXTENSION_VERSION=${strarr[1]} if [[ -z ${EXTENSION_VERSION} ]];then if [[ ${EXTENSION_NAME} != 'pg_cron' ]]; then echo -e "\e[32m [Entrypoint] Enabling extension \e[1;31m ${EXTENSION_NAME} \e[32m in the database : \e[1;31m ${DATABASE} \033[0m" - psql ${DATABASE} -U ${POSTGRES_USER} -p 5432 -h localhost -c "CREATE EXTENSION IF NOT EXISTS \"${EXTENSION_NAME}\" cascade;" + psql "${DATABASE}" -U ${POSTGRES_USER} -p 5432 -h localhost -c "CREATE EXTENSION IF NOT EXISTS \"${EXTENSION_NAME}\" cascade;" fi else if [[ ${EXTENSION_NAME} != 'pg_cron' ]]; then pattern="${EXTENSION_NAME}--" last_numbers=() - for file in "$EXTDIR"/${pattern}*; do + for file in "$EXTDIR"/"${pattern}"*; do filename=$(basename "$file" .sql) if [[ "$filename" == *"--"* ]]; then last_number=$(echo "$filename" | awk -F '--' '{print $NF}') @@ -542,7 +554,7 @@ function extension_install() { done if [[ " ${last_numbers[@]} " =~ " $EXTENSION_VERSION " ]]; then echo -e "\e[32m [Entrypoint] Installing extension \e[1;31m ${EXTENSION_NAME} \e[32m with version \e[1;31m ${EXTENSION_VERSION} \e[32m in the database : \e[1;31m ${DATABASE} \033[0m" - psql ${DATABASE} -U ${POSTGRES_USER} -p 5432 -h localhost -c "CREATE EXTENSION IF NOT EXISTS \"${EXTENSION_NAME}\" WITH VERSION '${EXTENSION_VERSION}' cascade;" + psql "${DATABASE}" -U ${POSTGRES_USER} -p 5432 -h localhost -c "CREATE EXTENSION IF NOT EXISTS \"${EXTENSION_NAME}\" WITH VERSION '${EXTENSION_VERSION}' cascade;" else echo -e "\e[32m [Entrypoint] Extension \e[1;31m ${EXTENSION_NAME} \e[32m with version \e[1;31m ${EXTENSION_VERSION} \e[32m is not available for install, available versions to install are \e[1;31m "${last_numbers[@]}" \033[0m" fi @@ -554,11 +566,11 @@ function extension_install() { function directory_checker() { DATA_PATH=$1 - if [ -d $DATA_PATH ];then - DB_USER_PERM=$(stat -c '%U' ${DATA_PATH}) - DB_GRP_PERM=$(stat -c '%G' ${DATA_PATH}) + if [ -d "$DATA_PATH" ];then + DB_USER_PERM=$(stat -c '%U' "${DATA_PATH}") + DB_GRP_PERM=$(stat -c '%G' "${DATA_PATH}") if [[ ${DB_USER_PERM} != "${USER}" ]] && [[ ${DB_GRP_PERM} != "${GROUP}" ]];then - chown -R ${USER}:${GROUP} ${DATA_PATH} + chown -R "${USER}":"${GROUP}" "${DATA_PATH}" fi fi @@ -574,9 +586,9 @@ function non_root_permission() { done services=("/usr/lib/postgresql/" "/etc/" "/var/run/!(secrets)" "/var/lib/" "/usr/bin" "/tmp" "/scripts") for paths in "${services[@]}"; do - directory_checker $paths + directory_checker "${paths}" done - chmod -R 750 ${DATADIR} ${WAL_ARCHIVE} + chmod -R 750 "${DATADIR}" ${WAL_ARCHIVE} } diff --git a/scripts/setup-conf.sh b/scripts/setup-conf.sh index c5b21258..1791d2d2 100644 --- a/scripts/setup-conf.sh +++ b/scripts/setup-conf.sh @@ -2,9 +2,9 @@ source /scripts/env-data.sh -create_dir ${EXTRA_CONF_DIR} -create_dir ${CONF_LOCKFILE_DIR} -create_dir ${SCRIPTS_LOCKFILE_DIR} +create_dir "${EXTRA_CONF_DIR}" +create_dir "${CONF_LOCKFILE_DIR}" +create_dir "${SCRIPTS_LOCKFILE_DIR}" SETUP_LOCKFILE="${CONF_LOCKFILE_DIR}/.postgresql.conf.lock" @@ -13,14 +13,14 @@ if [ -f "${SETUP_LOCKFILE}" ]; then fi # Refresh configuration in case environment settings changed. -cat $CONF.template > $CONF +cat "${CONF}".template > "${CONF}" # Reflect DATA DIR location # Delete any data_dir declarations -sed -i '/data_directory/d' $CONF +sed -i '/data_directory/d' "${CONF}" # Create a config to optimise postgis -cat > ${ROOT_CONF}/postgis.conf < "${ROOT_CONF}"/postgis.conf <> $CONF +echo "include 'postgis.conf'" >> "${CONF}" # Create a config for logical replication if [[ "${REPLICATION}" =~ [Tt][Rr][Uu][Ee] && "$WAL_LEVEL" == 'logical' ]]; then -cat > ${ROOT_CONF}/logical_replication.conf < "${ROOT_CONF}"/logical_replication.conf <> $CONF +echo "include 'logical_replication.conf'" >> "${CONF}" fi # Create a config for streaming replication if [[ "${REPLICATION}" =~ [Tt][Rr][Uu][Ee] && "$WAL_LEVEL" == 'replica' ]]; then postgres_ssl_setup -cat > ${ROOT_CONF}/streaming_replication.conf < "${ROOT_CONF}"/streaming_replication.conf <> ${ROOT_CONF}/streaming_replication.conf <> "${ROOT_CONF}"/streaming_replication.conf <> $CONF +echo "include 'streaming_replication.conf'" >> "${CONF}" fi if [[ ! -f ${ROOT_CONF}/extra.conf ]]; then # If it doesn't exists, copy from ${EXTRA_CONF_DIR} directory if exists if [[ -f ${EXTRA_CONF_DIR}/extra.conf ]]; then - cp -f ${EXTRA_CONF_DIR}/extra.conf ${ROOT_CONF}/extra.conf - echo "include 'extra.conf'" >> $CONF + cp -f "${EXTRA_CONF_DIR}"/extra.conf "${ROOT_CONF}"/extra.conf + echo "include 'extra.conf'" >> "${CONF}" else # default value if [[ -n "$EXTRA_CONF" ]]; then - echo -e $EXTRA_CONF >> ${ROOT_CONF}/extra.conf - echo "include 'extra.conf'" >> $CONF + echo -e "${EXTRA_CONF}" >> "${ROOT_CONF}"/extra.conf + echo "include 'extra.conf'" >> "${CONF}" fi fi @@ -108,10 +108,10 @@ if [[ $(dpkg -l | grep "timescaledb") > /dev/null ]] && [[ ${ACCEPT_TIMESCALE_TU over_write_conf echo -e "\e[1;31m Time scale config tuning values below" # TODO Add logic to find defaults memory, CPUS as these can vary from defaults on host machine and in docker container - timescaledb-tune -yes -quiet "${TIMESCALE_TUNING_PARAMS}" --dry-run >"${ROOT_CONF}"/${TIMESCALE_TUNING_CONFIG} + timescaledb-tune -yes -quiet "${TIMESCALE_TUNING_PARAMS}" --dry-run >"${ROOT_CONF}"/"${TIMESCALE_TUNING_CONFIG}" if [[ -f "${ROOT_CONF}"/${TIMESCALE_TUNING_CONFIG} ]]; then - mv "${ROOT_CONF}"/postgresql_orig.conf $CONF - echo "include '${TIMESCALE_TUNING_CONFIG}'" >> $CONF + mv "${ROOT_CONF}"/postgresql_orig.conf "${CONF}" + echo "include '${TIMESCALE_TUNING_CONFIG}'" >> "${CONF}" fi echo -e "\033[0m Time scale config tuning values set in ${ROOT_CONF}/${TIMESCALE_TUNING_CONFIG}" fi @@ -123,4 +123,4 @@ echo "kernel.shmmax=543252480" >> /etc/sysctl.conf echo "kernel.shmall=2097152" >> /etc/sysctl.conf # Put lock file to make sure conf was not reinitialized -touch ${SETUP_LOCKFILE} +touch "${SETUP_LOCKFILE}" diff --git a/scripts/setup-database.sh b/scripts/setup-database.sh index 4dbc508d..229dd4e1 100644 --- a/scripts/setup-database.sh +++ b/scripts/setup-database.sh @@ -26,7 +26,7 @@ EOF *) # For other case, make sure the directory is created with proper permissions create_dir "${POSTGRES_INITDB_WALDIR}" - chown -R postgres:postgres ${POSTGRES_INITDB_WALDIR} + chown -R postgres:postgres "${POSTGRES_INITDB_WALDIR}" ;; esac # Set the --waldir flag for postgres initialization @@ -38,15 +38,15 @@ create_dir "${WAL_ARCHIVE}" # test if DATADIR has content # Do initialization if DATADIR directory is empty, or RECREATE_DATADIR is true -if [[ -z "$(ls -A ${DATADIR} 2> /dev/null)" || "${RECREATE_DATADIR}" =~ [Tt][Rr][Uu][Ee] ]]; then +if [[ -z "$(ls -A "${DATADIR}" 2> /dev/null)" || "${RECREATE_DATADIR}" =~ [Tt][Rr][Uu][Ee] ]]; then # Only attempt reinitializations if ${RECREATE_DATADIR} is true # No Replicate From settings. Assume that this is a master database. # Initialise db echo -e "\e[32m [Entrypoint] Initializing Postgres Database at \e[1;31m ${DATADIR} \033[0m" create_dir "${DATADIR}" - rm -rf ${DATADIR}/* + rm -rf "${DATADIR:?}/"* chown -R postgres:postgres "${DATADIR}" - command="$INITDB -U postgres --pwfile=<(echo "$POSTGRES_PASS") -E ${DEFAULT_ENCODING} --lc-collate=${DEFAULT_COLLATION} --lc-ctype=${DEFAULT_CTYPE} --wal-segsize=${WAL_SEGSIZE} --auth=${PASSWORD_AUTHENTICATION} -D ${DATADIR} ${INITDB_WALDIR_FLAG} ${INITDB_EXTRA_ARGS}" + command="$INITDB -U postgres --pwfile=<(echo $POSTGRES_PASS) -E ${DEFAULT_ENCODING} --lc-collate=${DEFAULT_COLLATION} --lc-ctype=${DEFAULT_CTYPE} --wal-segsize=${WAL_SEGSIZE} --auth=${PASSWORD_AUTHENTICATION} -D ${DATADIR} ${INITDB_WALDIR_FLAG} ${INITDB_EXTRA_ARGS}" echo -e "\e[32m [Entrypoint] Initializing Cluster with the following commands Postgres Database at \e[1;31m $command \033[0m" su - postgres -c "$command" else @@ -54,18 +54,18 @@ else # Check if pg_wal symlink point to the correct directory described by POSTGRES_INITDB_WALDIR. # Give warning if the value is not the same if [[ -n "${POSTGRES_INITDB_WALDIR}" && \ - "$(realpath ${POSTGRES_INITDB_WALDIR})" != "$(realpath "$(readlink ${DATADIR}/pg_wal)")" ]]; then + "$(realpath "${POSTGRES_INITDB_WALDIR}")" != "$(realpath "$(readlink "${DATADIR}"/pg_wal)")" ]]; then cat << EOF 1>&2 Warning! POSTGRES_INITDB_WALDIR is not the same as what pg_wal is pointing to. POSTGRES_INITDB_WALDIR: ${POSTGRES_INITDB_WALDIR} -pg_wal: $(readlink ${DATADIR}/pg_wal) +pg_wal: $(readlink "${DATADIR}"/pg_wal) EOF fi # Check if the pg_wal is empty. # Exit the process if pg_wal is somehow empty - if [[ -z "$(ls -A ${DATADIR}/pg_wal 2> /dev/null)" ]]; then + if [[ -z "$(ls -A "${DATADIR}"/pg_wal 2> /dev/null)" ]]; then cat << EOF 1>&2 Error! Can't proceed because "${DATADIR}/pg_wal" directory is empty. @@ -77,8 +77,8 @@ fi; non_root_permission postgres postgres # Set proper permissions # needs to be done as root: -chown -R postgres:postgres ${DATADIR} ${WAL_ARCHIVE} -chmod -R 750 ${DATADIR} ${WAL_ARCHIVE} +chown -R postgres:postgres "${DATADIR}" "${WAL_ARCHIVE}" +chmod -R 750 "${DATADIR}" "${WAL_ARCHIVE}" # test database existing trap "echo \"Sending SIGTERM to postgres\"; killall -s SIGTERM postgres" SIGTERM @@ -101,28 +101,30 @@ 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 - RESULT=`su - postgres -c "psql -t -c \"SELECT count(1) from pg_database where datname='${db}';\""` +for db in $(echo "${POSTGRES_DBNAME}" | tr ',' ' '); 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" - DB_CREATE=$(createdb -h localhost -p 5432 -U ${POSTGRES_USER} ${db}) - eval ${DB_CREATE} - psql ${SINGLE_DB} -U ${POSTGRES_USER} -p 5432 -h localhost -c 'CREATE EXTENSION IF NOT EXISTS pg_cron cascade;' + DB_CREATE=$(createdb -h localhost -p 5432 -U "${POSTGRES_USER}" "${db}") + eval "${DB_CREATE}" + if [[ ${ACTIVATE_CRON} =~ [Tt][Rr][Uu][Ee] ]];then + psql "${SINGLE_DB}" -U "${POSTGRES_USER}" -p 5432 -h localhost -c 'CREATE EXTENSION IF NOT EXISTS pg_cron cascade;' + fi # Loop through extensions IFS=',' read -a strarr <<< "$POSTGRES_MULTIPLE_EXTENSIONS" for ext in "${strarr[@]}";do - extension_install ${db} + extension_install "${db}" "${ext}" # enable extensions in template1 if env variable set to true - if [[ "$(boolean ${POSTGRES_TEMPLATE_EXTENSIONS})" =~ [Tt][Rr][Uu][Ee] ]] ; then + if [[ "$(boolean "${POSTGRES_TEMPLATE_EXTENSIONS}")" =~ [Tt][Rr][Uu][Ee] ]] ; then extension_install template1 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 + 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;" + psql "${db}" -U "${POSTGRES_USER}" -p 5432 -h localhost -c "CREATE PUBLICATION logical_replication;" fi else @@ -134,15 +136,15 @@ done # Create schemas in the DB -for db in $(echo ${POSTGRES_DBNAME} | tr ',' ' '); 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 = '${schemas}' and catalog_name = '${db}';") +for db in $(echo "${POSTGRES_DBNAME}" | tr ',' ' '); 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 echo -e "\e[32m [Entrypoint] Creating schema \e[1;31m ${schema} \e[32m in database \e[1;31m ${SINGLE_DB} \033[0m" - psql ${SINGLE_DB} -U ${POSTGRES_USER} -p 5432 -h localhost -c " CREATE SCHEMA IF NOT EXISTS ${schema};" + psql "${SINGLE_DB}" -U "${POSTGRES_USER}" -p 5432 -h localhost -c " CREATE SCHEMA IF NOT EXISTS ${schema};" elif [[ ${SCHEMA_RESULT} -eq 0 ]] && [[ "${ALL_DATABASES}" =~ [Tt][Rr][Uu][Ee] ]]; then echo -e "\e[32m [Entrypoint] Creating schema \e[1;31m ${schema} \e[32m in database \e[1;31m ${db} \033[0m" - psql ${db} -U ${POSTGRES_USER} -p 5432 -h localhost -c " CREATE SCHEMA IF NOT EXISTS ${schema};" + psql "${db}" -U "${POSTGRES_USER}" -p 5432 -h localhost -c " CREATE SCHEMA IF NOT EXISTS ${schema};" fi done done diff --git a/scripts/setup-pg_hba.sh b/scripts/setup-pg_hba.sh index 65d2afde..d912f1e5 100644 --- a/scripts/setup-pg_hba.sh +++ b/scripts/setup-pg_hba.sh @@ -11,7 +11,7 @@ fi # This script will setup pg_hba.conf # Reconfigure pg_hba if environment settings changed -cat ${ROOT_CONF}/pg_hba.conf.template > ${ROOT_CONF}/pg_hba.conf +cat "${ROOT_CONF}"/pg_hba.conf.template > "${ROOT_CONF}"/pg_hba.conf if [[ "${FORCE_SSL}" =~ [Ff][Aa][Ll][Ss][Ee] ]]; then @@ -34,16 +34,16 @@ else fi # Restrict subnet to docker private network -echo "$PG_CONF_HOST all all 172.0.0.0/8 ${CERT_AUTH} $CLIENT_VERIFY" >> $ROOT_CONF/pg_hba.conf +echo "$PG_CONF_HOST all all 172.0.0.0/8 ${CERT_AUTH} $CLIENT_VERIFY" >> "${ROOT_CONF}"/pg_hba.conf # And allow access from DockerToolbox / Boot to docker on OSX -echo "$PG_CONF_HOST all all 192.168.0.0/16 ${CERT_AUTH} $CLIENT_VERIFY" >> $ROOT_CONF/pg_hba.conf +echo "$PG_CONF_HOST all all 192.168.0.0/16 ${CERT_AUTH} $CLIENT_VERIFY" >> "${ROOT_CONF}"/pg_hba.conf # Custom IP range via docker run -e (https://docs.docker.com/engine/reference/run/#env-environment-variables) # Usage is: docker run [...] -e ALLOW_IP_RANGE='192.168.0.0/16' if [[ -n "$ALLOW_IP_RANGE" ]] then echo "Add rule to pg_hba: $ALLOW_IP_RANGE" - echo "$PG_CONF_HOST all all $ALLOW_IP_RANGE ${CERT_AUTH} $CLIENT_VERIFY" >> ${ROOT_CONF}/pg_hba.conf + echo "$PG_CONF_HOST all all $ALLOW_IP_RANGE ${CERT_AUTH} $CLIENT_VERIFY" >> "${ROOT_CONF}"/pg_hba.conf fi # check password first so we can output the warning before postgres @@ -77,10 +77,10 @@ if [[ -z "$REPLICATE_FROM" ]]; then # if env not set, then assume this is master instance # add rules to pg_hba.conf to allow replication from all echo "Add rule to pg_hba: replication ${REPLICATION_USER} " - echo "$PG_CONF_HOST replication ${REPLICATION_USER} ${ALLOW_IP_RANGE} $authMethod $CLIENT_VERIFY" >> ${ROOT_CONF}/pg_hba.conf + echo "$PG_CONF_HOST replication ${REPLICATION_USER} ${ALLOW_IP_RANGE} $authMethod $CLIENT_VERIFY" >> "${ROOT_CONF}"/pg_hba.conf fi # Put lock file to make sure conf was not reinitialized export PASSWORD_AUTHENTICATION -envsubst < $ROOT_CONF/pg_hba.conf > /tmp/pg_hba.conf && mv /tmp/pg_hba.conf $ROOT_CONF/pg_hba.conf -touch ${SETUP_LOCKFILE} +envsubst < "${ROOT_CONF}"/pg_hba.conf > /tmp/pg_hba.conf && mv /tmp/pg_hba.conf "${ROOT_CONF}"/pg_hba.conf +touch "${SETUP_LOCKFILE}" diff --git a/scripts/setup-replication.sh b/scripts/setup-replication.sh index 709066a3..139a280c 100755 --- a/scripts/setup-replication.sh +++ b/scripts/setup-replication.sh @@ -15,7 +15,7 @@ else START_COMMAND='su - postgres -c' fi -create_dir ${WAL_ARCHIVE} +create_dir "${WAL_ARCHIVE}" if [[ "$WAL_LEVEL" == 'replica' && "${REPLICATION}" =~ [Tt][Rr][Uu][Ee] ]]; then # No content yet - but this is a slave database diff --git a/scripts/setup-ssl.sh b/scripts/setup-ssl.sh index 9735df8a..56d5c216 100644 --- a/scripts/setup-ssl.sh +++ b/scripts/setup-ssl.sh @@ -18,9 +18,9 @@ rm -r /etc/ssl mv /tmp/ssl-copy /etc/ssl # Setup Permission for SSL Directory -create_dir ${SSL_DIR} -chmod -R 0700 ${SSL_DIR} -chown -R postgres ${SSL_DIR} +create_dir "${SSL_DIR}" +chmod -R 0700 "${SSL_DIR}" +chown -R postgres "${SSL_DIR}" # Docker secrets for certificates file_env 'SSL_CERT_FILE' @@ -28,19 +28,19 @@ file_env 'SSL_KEY_FILE' file_env 'SSL_CA_FILE' # Needed under debian, wasn't needed under ubuntu -mkdir -p ${PGSTAT_TMP} -chmod 0777 ${PGSTAT_TMP} +mkdir -p "${PGSTAT_TMP}" +chmod 0777 "${PGSTAT_TMP}" # moved from setup.sh -cat > ${ROOT_CONF}/ssl.conf < "${ROOT_CONF}"/ssl.conf <> ${ROOT_CONF}/ssl.conf + echo "ssl_ca_file = '${SSL_CA_FILE}' # (change requires restart)" >> "${ROOT_CONF}"/ssl.conf fi -echo "include 'ssl.conf'" >> $CONF +echo "include 'ssl.conf'" >> "${CONF}" # Put lock file to make sure conf was not reinitialized -touch ${SETUP_LOCKFILE} +touch "${SETUP_LOCKFILE}" diff --git a/scripts/setup-user.sh b/scripts/setup-user.sh index 502fbd77..f5a017b8 100644 --- a/scripts/setup-user.sh +++ b/scripts/setup-user.sh @@ -6,10 +6,10 @@ source /scripts/env-data.sh # Check user already exists -role_check $POSTGRES_USER +role_check "$POSTGRES_USER" su - postgres -c "psql postgres -c \"$COMMAND USER $POSTGRES_USER WITH SUPERUSER ENCRYPTED PASSWORD '$POSTGRES_PASS';\"" -role_check $REPLICATION_USER +role_check "$REPLICATION_USER" su - postgres -c "psql postgres -c \"$COMMAND USER $REPLICATION_USER WITH REPLICATION ENCRYPTED PASSWORD '$REPLICATION_PASS';\"" diff --git a/scripts/setup.sh b/scripts/setup.sh index e553ee62..d97b7695 100755 --- a/scripts/setup.sh +++ b/scripts/setup.sh @@ -6,13 +6,13 @@ chmod 600 /etc/ssl/private/ssl-cert-snakeoil.key source /scripts/env-data.sh # Create backup template for conf -cat $CONF > $CONF.template +cat "${CONF}" > "${CONF}".template # Create backup template for pg_hba.conf -sed -i 's/scram-sha-256/${PASSWORD_AUTHENTICATION}/g' $ROOT_CONF/pg_hba.conf -sed -i 's/md5/${PASSWORD_AUTHENTICATION}/g' $ROOT_CONF/pg_hba.conf +sed -i 's/scram-sha-256/${PASSWORD_AUTHENTICATION}/g' "${ROOT_CONF}"/pg_hba.conf +sed -i 's/md5/${PASSWORD_AUTHENTICATION}/g' "${ROOT_CONF}"/pg_hba.conf -cat $ROOT_CONF/pg_hba.conf > $ROOT_CONF/pg_hba.conf.template +cat "${ROOT_CONF}"/pg_hba.conf > "${ROOT_CONF}"/pg_hba.conf.template