diff --git a/bitnami/postgresql/12/debian-10/Dockerfile b/bitnami/postgresql/12/debian-10/Dockerfile new file mode 100644 index 000000000000..514e3c876987 --- /dev/null +++ b/bitnami/postgresql/12/debian-10/Dockerfile @@ -0,0 +1,38 @@ +FROM bitnami/minideb:buster +LABEL maintainer "Bitnami " + +ENV BITNAMI_PKG_CHMOD="-R g+rwX" \ + HOME="/" \ + OS_ARCH="amd64" \ + OS_FLAVOUR="debian-10" \ + OS_NAME="linux" + +COPY prebuildfs / +# Install required system packages and dependencies +RUN install_packages ca-certificates curl libbsd0 libc6 libedit2 libffi6 libgcc1 libgmp10 libgnutls30 libhogweed4 libicu63 libidn2-0 libldap-2.4-2 liblzma5 libnettle6 libp11-kit0 libsasl2-2 libsqlite3-0 libssl1.1 libstdc++6 libtasn1-6 libtinfo6 libunistring2 libuuid1 libxml2 libxslt1.1 locales procps sudo unzip zlib1g +RUN . ./libcomponent.sh && component_unpack "postgresql" "12.1.0-0" --checksum 7dec274a34ff153cfb00690d0b38933d443e465ea088e0ca7c8fc2f761780a21 +RUN apt-get update && apt-get upgrade && \ + rm -r /var/lib/apt/lists /var/cache/apt/archives +RUN /build/install-gosu.sh +RUN update-locale LANG=C.UTF-8 LC_MESSAGES=POSIX && \ + DEBIAN_FRONTEND=noninteractive dpkg-reconfigure locales +RUN echo 'en_GB.UTF-8 UTF-8' >> /etc/locale.gen && locale-gen +RUN echo 'en_US.UTF-8 UTF-8' >> /etc/locale.gen && locale-gen + +COPY rootfs / +RUN /postunpack.sh +ENV BITNAMI_APP_NAME="postgresql" \ + BITNAMI_IMAGE_VERSION="12.1.0-debian-10-r0" \ + LANG="en_US.UTF-8" \ + LANGUAGE="en_US:en" \ + NAMI_PREFIX="/.nami" \ + NSS_WRAPPER_LIB="/opt/bitnami/common/lib/libnss_wrapper.so" \ + PATH="/opt/bitnami/postgresql/bin:$PATH" + +VOLUME [ "/bitnami/postgresql", "/docker-entrypoint-initdb.d", "/docker-entrypoint-preinitdb.d" ] + +EXPOSE 5432 + +USER 1001 +ENTRYPOINT [ "/entrypoint.sh" ] +CMD [ "/run.sh" ] diff --git a/bitnami/postgresql/12/debian-10/docker-compose.yml b/bitnami/postgresql/12/debian-10/docker-compose.yml new file mode 100644 index 000000000000..6a63c71c26ab --- /dev/null +++ b/bitnami/postgresql/12/debian-10/docker-compose.yml @@ -0,0 +1,15 @@ +version: '2' + +services: + postgresql: + image: 'bitnami/postgresql:12' + ports: + - '5432:5432' + volumes: + - 'postgresql_data:/bitnami/postgresql' + environment: + - 'ALLOW_EMPTY_PASSWORD=yes' + +volumes: + postgresql_data: + driver: local diff --git a/bitnami/postgresql/12/debian-10/prebuildfs/build/install-gosu.sh b/bitnami/postgresql/12/debian-10/prebuildfs/build/install-gosu.sh new file mode 100755 index 000000000000..1756700daa89 --- /dev/null +++ b/bitnami/postgresql/12/debian-10/prebuildfs/build/install-gosu.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +VERSION="1.11" +SHA256="0b843df6d86e270c5b0f5cbd3c326a04e18f4b7f9b8457fa497b0454c4b138d7" + +curl --silent -L "https://github.com/tianon/gosu/releases/download/${VERSION}/gosu-amd64" > "/usr/local/bin/gosu" +echo "$SHA256" "/usr/local/bin/gosu" | sha256sum --check +chmod u+x "/usr/local/bin/gosu" +mkdir -p "/opt/bitnami/licenses" +curl --silent -L "https://raw.githubusercontent.com/tianon/gosu/master/LICENSE" > "/opt/bitnami/licenses/gosu-${VERSION}.txt" diff --git a/bitnami/postgresql/12/debian-10/prebuildfs/libbitnami.sh b/bitnami/postgresql/12/debian-10/prebuildfs/libbitnami.sh new file mode 100644 index 000000000000..529c3fd4a3e2 --- /dev/null +++ b/bitnami/postgresql/12/debian-10/prebuildfs/libbitnami.sh @@ -0,0 +1,50 @@ +#!/bin/bash +# +# Bitnami custom library + +# Load Generic Libraries +. /liblog.sh + +# Constants +BOLD='\033[1m' + +# Functions + +######################## +# Print the welcome page +# Globals: +# DISABLE_WELCOME_MESSAGE +# BITNAMI_APP_NAME +# Arguments: +# None +# Returns: +# None +######################### +print_welcome_page() { + if [[ -z "${DISABLE_WELCOME_MESSAGE:-}" ]]; then + if [[ -n "$BITNAMI_APP_NAME" ]]; then + print_image_welcome_page + fi + fi +} + +######################## +# Print the welcome page for a Bitnami Docker image +# Globals: +# BITNAMI_APP_NAME +# Arguments: +# None +# Returns: +# None +######################### +print_image_welcome_page() { + local github_url="https://github.com/bitnami/bitnami-docker-${BITNAMI_APP_NAME}" + + log "" + log "${BOLD}Welcome to the Bitnami ${BITNAMI_APP_NAME} container${RESET}" + log "Subscribe to project updates by watching ${BOLD}${github_url}${RESET}" + log "Submit issues and feature requests at ${BOLD}${github_url}/issues${RESET}" + log "Send us your feedback at ${BOLD}containers@bitnami.com${RESET}" + log "" +} + diff --git a/bitnami/postgresql/12/debian-10/prebuildfs/libcomponent.sh b/bitnami/postgresql/12/debian-10/prebuildfs/libcomponent.sh new file mode 100644 index 000000000000..025288664f69 --- /dev/null +++ b/bitnami/postgresql/12/debian-10/prebuildfs/libcomponent.sh @@ -0,0 +1,64 @@ +#!/bin/bash +# +# Library for managing Bitnami components + +# Constants +CACHE_ROOT="/tmp/bitnami/pkg/cache" +DOWNLOAD_URL="https://downloads.bitnami.com/files/stacksmith" + +# Functions + +######################## +# Download and unpack a Bitnami package +# Globals: +# OS_NAME +# OS_ARCH +# OS_FLAVOUR +# Arguments: +# $1 - component's name +# $2 - component's version +# Returns: +# None +######################### +component_unpack() { + local name="${1:?name is required}" + local version="${2:?version is required}" + local base_name="${name}-${version}-${OS_NAME}-${OS_ARCH}-${OS_FLAVOUR}" + local package_sha256="" + + # Validate arguments + shift 2 + while [ "$#" -gt 0 ]; do + case "$1" in + -c|--checksum) + shift + package_sha256="${1:?missing package checksum}" + ;; + *) + echo "Invalid command line flag $1" >&2 + return 1 + ;; + esac + shift + done + + echo "Downloading $base_name package" + if [ -f "${CACHE_ROOT}/${base_name}.tar.gz" ]; then + echo "${CACHE_ROOT}/${base_name}.tar.gz already exists, skipping download." + cp "${CACHE_ROOT}/${base_name}.tar.gz" . + rm "${CACHE_ROOT}/${base_name}.tar.gz" + if [ -f "${CACHE_ROOT}/${base_name}.tar.gz.sha256" ]; then + echo "Using the local sha256 from ${CACHE_ROOT}/${base_name}.tar.gz.sha256" + package_sha256="$(< "${CACHE_ROOT}/${base_name}.tar.gz.sha256")" + rm "${CACHE_ROOT}/${base_name}.tar.gz.sha256" + fi + else + curl --remote-name --silent "${DOWNLOAD_URL}/${base_name}.tar.gz" + fi + if [ -n "$package_sha256" ]; then + echo "Verifying package integrity" + echo "$package_sha256 ${base_name}.tar.gz" | sha256sum --check - + fi + tar --directory /opt/bitnami --extract --gunzip --file "${base_name}.tar.gz" --no-same-owner --strip-components=2 "${base_name}/files/" + rm "${base_name}.tar.gz" +} diff --git a/bitnami/postgresql/12/debian-10/prebuildfs/libfile.sh b/bitnami/postgresql/12/debian-10/prebuildfs/libfile.sh new file mode 100644 index 000000000000..12010f043e49 --- /dev/null +++ b/bitnami/postgresql/12/debian-10/prebuildfs/libfile.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# +# Library for managing files + +# Functions + +######################## +# Ensure a line exists in the file by replacing a matching line. +# Arguments: +# $1 - filename +# $2 - line +# $3 - match +# Returns: +# None +######################### +file_contains_line() { + local filename="${1:?filename is required}" + local line="${2:?line is required}" + local match="${3:?match is required}" + + sed --in-place "s/^$match\$/$line/" "$filename" +} diff --git a/bitnami/postgresql/12/debian-10/prebuildfs/libfs.sh b/bitnami/postgresql/12/debian-10/prebuildfs/libfs.sh new file mode 100644 index 000000000000..10a24735c096 --- /dev/null +++ b/bitnami/postgresql/12/debian-10/prebuildfs/libfs.sh @@ -0,0 +1,129 @@ +#!/bin/bash +# +# Library for file system actions + +# Load Generic Libraries +. /liblog.sh + +# Functions + +######################## +# Ensure a file/directory is owned (user and group) but the given user +# Arguments: +# $1 - filepath +# $2 - owner +# Returns: +# None +######################### +owned_by() { + local path="${1:?path is missing}" + local owner="${2:?owner is missing}" + + chown "$owner":"$owner" "$path" +} + +######################## +# Ensure a directory exists and, optionally, is owned by the given user +# Arguments: +# $1 - directory +# $2 - owner +# Returns: +# None +######################### +ensure_dir_exists() { + local dir="${1:?directory is missing}" + local owner="${2:-}" + + mkdir -p "${dir}" + if [[ -n $owner ]]; then + owned_by "$dir" "$owner" + fi +} + +######################## +# Checks whether a directory is empty or not +# Arguments: +# $1 - directory +# Returns: +# Boolean +######################### +is_dir_empty() { + local dir="${1:?missing directory}" + + if [[ ! -e "$dir" ]] || [[ -z "$(ls -A "$dir")" ]]; then + true + else + false + fi +} + +######################## +# Configure permisions and ownership recursively +# Globals: +# None +# Arguments: +# $1 - paths (as a string). +# Flags: +# -f|--file-mode - mode for directories. +# -d|--dir-mode - mode for files. +# -u|--user - user +# -g|--group - group +# Returns: +# None +######################### +configure_permissions_ownership() { + local -r paths="${1:?paths is missing}" + local dir_mode="" + local file_mode="" + local user="" + local group="" + + # Validate arguments + shift 1 + while [ "$#" -gt 0 ]; do + case "$1" in + -f|--file-mode) + shift + file_mode="${1:?missing mode for files}" + ;; + -d|--dir-mode) + shift + dir_mode="${1:?missing mode for directories}" + ;; + -u|--user) + shift + user="${1:?missing user}" + ;; + -g|--group) + shift + group="${1:?missing group}" + ;; + *) + echo "Invalid command line flag $1" >&2 + return 1 + ;; + esac + shift + done + + read -r -a filepaths <<< "$paths" + for p in "${filepaths[@]}"; do + if [[ -e "$p" ]]; then + if [[ -n $dir_mode ]]; then + find -L "$p" -type d -exec chmod "$dir_mode" {} \; + fi + if [[ -n $file_mode ]]; then + find -L "$p" -type f -exec chmod "$file_mode" {} \; + fi + if [[ -n $user ]] && [[ -n $group ]]; then + chown -LR "$user":"$group" "$p" + elif [[ -n $user ]] && [[ -z $group ]]; then + chown -LR "$user" "$p" + elif [[ -z $user ]] && [[ -n $group ]]; then + chgrp -LR "$group" "$p" + fi + else + stderr_print "$p does not exist" + fi + done +} diff --git a/bitnami/postgresql/12/debian-10/prebuildfs/liblog.sh b/bitnami/postgresql/12/debian-10/prebuildfs/liblog.sh new file mode 100644 index 000000000000..04118273394a --- /dev/null +++ b/bitnami/postgresql/12/debian-10/prebuildfs/liblog.sh @@ -0,0 +1,83 @@ +#!/bin/bash +# +# Library for logging functions + +# Constants +RESET='\033[0m' +RED='\033[38;5;1m' +GREEN='\033[38;5;2m' +YELLOW='\033[38;5;3m' +MAGENTA='\033[38;5;5m' +CYAN='\033[38;5;6m' + +# Functions + +######################## +# Print to STDERR +# Arguments: +# Message to print +# Returns: +# None +######################### +stderr_print() { + printf "%b\\n" "${*}" >&2 +} + +######################## +# Log message +# Arguments: +# Message to log +# Returns: +# None +######################### +log() { + stderr_print "${CYAN}${MODULE:-} ${MAGENTA}$(date "+%T.%2N ")${RESET}${*}" +} +######################## +# Log an 'info' message +# Arguments: +# Message to log +# Returns: +# None +######################### +info() { + log "${GREEN}INFO ${RESET} ==> ${*}" +} +######################## +# Log message +# Arguments: +# Message to log +# Returns: +# None +######################### +warn() { + log "${YELLOW}WARN ${RESET} ==> ${*}" +} +######################## +# Log an 'error' message +# Arguments: +# Message to log +# Returns: +# None +######################### +error() { + log "${RED}ERROR${RESET} ==> ${*}" +} +######################## +# Log a 'debug' message +# Globals: +# BITNAMI_DEBUG +# Arguments: +# None +# Returns: +# None +######################### +debug() { + # 'is_boolean_yes' is defined in libvalidations.sh, but depends on this file so we cannot source it + local -r bool="${BITNAMI_DEBUG:-false}" + # comparison is performed without regard to the case of alphabetic characters + shopt -s nocasematch + if [[ "$bool" = 1 || "$bool" =~ ^(yes|true)$ ]]; then + log "${MAGENTA}DEBUG${RESET} ==> ${*}" + fi +} diff --git a/bitnami/postgresql/12/debian-10/prebuildfs/libnet.sh b/bitnami/postgresql/12/debian-10/prebuildfs/libnet.sh new file mode 100644 index 000000000000..f884b7661fd7 --- /dev/null +++ b/bitnami/postgresql/12/debian-10/prebuildfs/libnet.sh @@ -0,0 +1,44 @@ +#!/bin/bash +# +# Library for network functions + +# Functions + +######################## +# Resolve dns +# Arguments: +# $1 - Hostname to resolve +# Returns: +# IP +######################### +dns_lookup() { + local host="${1:?host is missing}" + getent ahosts "$host" | awk '/STREAM/ {print $1 }' +} + +######################## +# Get machine's IP +# Arguments: +# None +# Returns: +# Machine IP +######################### +get_machine_ip() { + dns_lookup "$(hostname)" +} + +######################## +# Check if the provided argument is a resolved hostname +# Arguments: +# $1 - Value to check +# Returns: +# Boolean +######################### +is_hostname_resolved() { + local -r host="${1:?missing value}" + if [[ -n "$(dns_lookup "$host")" ]]; then + true + else + false + fi +} diff --git a/bitnami/postgresql/12/debian-10/prebuildfs/libos.sh b/bitnami/postgresql/12/debian-10/prebuildfs/libos.sh new file mode 100644 index 000000000000..1a5ba3bb2a64 --- /dev/null +++ b/bitnami/postgresql/12/debian-10/prebuildfs/libos.sh @@ -0,0 +1,132 @@ +#!/bin/bash +# +# Library for operating system actions + +# Functions + +######################## +# Check if an user exists in the system +# Arguments: +# $1 - user +# Returns: +# Boolean +######################### +user_exists() { + local user="${1:?user is missing}" + id "$user" >/dev/null 2>&1 +} + +######################## +# Check if a group exists in the system +# Arguments: +# $1 - group +# Returns: +# Boolean +######################### +group_exists() { + local group="${1:?group is missing}" + getent group "$group" >/dev/null 2>&1 +} + +######################## +# Create a group in the system if it does not exist already +# Arguments: +# $1 - group +# Returns: +# None +######################### +ensure_group_exists() { + local group="${1:?group is missing}" + + if ! group_exists "$group"; then + groupadd "$group" >/dev/null 2>&1 + fi +} + +######################## +# Create an user in the system if it does not exist already +# Arguments: +# $1 - user +# $2 - group +# Returns: +# None +######################### +ensure_user_exists() { + local user="${1:?user is missing}" + local group="${2:-}" + + if ! user_exists "$user"; then + useradd "$user" >/dev/null 2>&1 + if [[ -n "$group" ]]; then + ensure_group_exists "$group" + usermod -a -G "$group" "$user" >/dev/null 2>&1 + fi + fi +} + +######################## +# Check if the script is currently running as root +# Arguments: +# $1 - user +# $2 - group +# Returns: +# Boolean +######################### +am_i_root() { + if [[ "$(id -u)" = "0" ]]; then + true + else + false + fi +} + +######################## +# Get total memory available +# Arguments: +# None +# Returns: +# Memory in bytes +######################### +get_total_memory() { + echo $(($(grep MemTotal /proc/meminfo | awk '{print $2}') / 1024)) +} + +######################### +# Redirects output to /dev/null if debug mode is disabled +# Globals: +# BITNAMI_DEBUG +# Arguments: +# $@ - Command to execute +# Returns: +# None +######################### +debug_execute() { + if ${BITNAMI_DEBUG:-false}; then + "$@" + else + "$@" >/dev/null 2>&1 + fi +} + +######################## +# Retries a command a given number of times +# Arguments: +# $1 - cmd (as a string) +# $2 - max retries. Default: 12 +# $3 - sleep between retries (in seconds). Default: 5 +# Returns: +# Boolean +######################### +retry_while() { + local -r cmd="${1:?cmd is missing}" + local -r retries="${2:-12}" + local -r sleep_time="${3:-5}" + local return_value=1 + + read -r -a command <<< "$cmd" + for ((i = 1 ; i <= retries ; i+=1 )); do + "${command[@]}" && return_value=0 && break + sleep "$sleep_time" + done + return $return_value +} diff --git a/bitnami/postgresql/12/debian-10/prebuildfs/libservice.sh b/bitnami/postgresql/12/debian-10/prebuildfs/libservice.sh new file mode 100644 index 000000000000..0a83cd3d927f --- /dev/null +++ b/bitnami/postgresql/12/debian-10/prebuildfs/libservice.sh @@ -0,0 +1,57 @@ +#!/bin/bash +# +# Library for managing services + +# Functions + +######################## +# Read the provided pid file and returns a PID +# Arguments: +# $1 - Pid file +# Returns: +# PID +######################### +get_pid_from_file() { + local pid_file="${1:?pid file is missing}" + + if [[ -f "$pid_file" ]]; then + if [[ -n "$(< "$pid_file")" ]] && [[ "$(< "$pid_file")" -gt 0 ]]; then + echo "$(< "$pid_file")" + fi + fi +} + +######################## +# Check if a provided PID corresponds to a running service +# Arguments: +# $1 - PID +# Returns: +# Boolean +######################### +is_service_running() { + local pid="${1:?pid is missing}" + + kill -0 "$pid" 2>/dev/null +} + +######################## +# Stop a service by sending a termination signal to its pid +# Arguments: +# $1 - Pid file +# Returns: +# None +######################### +stop_service_using_pid() { + local pid_file="${1:?pid file is missing}" + local pid + + pid="$(get_pid_from_file "$pid_file")" + [[ -z "$pid" ]] || ! is_service_running "$pid" && return + + kill "$pid" + local counter=10 + while [[ "$counter" -ne 0 ]] && is_service_running "$pid"; do + sleep 1 + counter=$((counter - 1)) + done +} diff --git a/bitnami/postgresql/12/debian-10/prebuildfs/libvalidations.sh b/bitnami/postgresql/12/debian-10/prebuildfs/libvalidations.sh new file mode 100644 index 000000000000..ef9aaf0cf31f --- /dev/null +++ b/bitnami/postgresql/12/debian-10/prebuildfs/libvalidations.sh @@ -0,0 +1,246 @@ +#!/bin/bash +# +# Validation functions library + +# Load Generic Libraries +. /liblog.sh + +# Functions + +######################## +# Check if the provided argument is an integer +# Arguments: +# $1 - Value to check +# Returns: +# Boolean +######################### +is_int() { + local -r int="${1:?missing value}" + if [[ "$int" =~ ^-?[0-9]+ ]]; then + true + else + false + fi +} + +######################## +# Check if the provided argument is a positive integer +# Arguments: +# $1 - Value to check +# Returns: +# Boolean +######################### +is_positive_int() { + local -r int="${1:?missing value}" + if is_int "$int" && (( "${int}" >= 0 )); then + true + else + false + fi +} + +######################## +# Check if the provided argument is a boolean or is the string 'yes/true' +# Arguments: +# $1 - Value to check +# Returns: +# Boolean +######################### +is_boolean_yes() { + local -r bool="${1:-}" + # comparison is performed without regard to the case of alphabetic characters + shopt -s nocasematch + if [[ "$bool" = 1 || "$bool" =~ ^(yes|true)$ ]]; then + true + else + false + fi +} + +######################## +# Check if the provided argument is a boolean yes/no value +# Arguments: +# $1 - Value to check +# Returns: +# Boolean +######################### +is_yes_no_value() { + local -r bool="${1:-}" + if [[ "$bool" =~ ^(yes|no)$ ]]; then + true + else + false + fi +} + +######################## +# Check if the provided argument is a boolean true/false value +# Arguments: +# $1 - Value to check +# Returns: +# Boolean +######################### +is_true_false_value() { + local -r bool="${1:-}" + if [[ "$bool" =~ ^(true|false)$ ]]; then + true + else + false + fi +} + +######################## +# Check if the provided argument is an empty string or not defined +# Arguments: +# $1 - Value to check +# Returns: +# Boolean +######################### +is_empty_value() { + local -r val="${1:-}" + if [[ -z "$val" ]]; then + true + else + false + fi +} + +######################## +# Validate if the provided argument is a valid port +# Arguments: +# $1 - Port to validate +# Returns: +# Boolean and error message +######################### +validate_port() { + local value + local unprivileged=0 + + # Parse flags + while [[ "$#" -gt 0 ]]; do + case "$1" in + -unprivileged) + unprivileged=1 + ;; + --) + shift + break + ;; + -*) + stderr_print "unrecognized flag $1" + return 1 + ;; + *) + break + ;; + esac + shift + done + + if [[ "$#" -gt 1 ]]; then + echo "too many arguments provided" + return 2 + elif [[ "$#" -eq 0 ]]; then + stderr_print "missing port argument" + return 1 + else + value=$1 + fi + + if [[ -z "$value" ]]; then + echo "the value is empty" + return 1 + else + if ! is_int "$value"; then + echo "value is not an integer" + return 2 + elif [[ "$value" -lt 0 ]]; then + echo "negative value provided" + return 2 + elif [[ "$value" -gt 65535 ]]; then + echo "requested port is greater than 65535" + return 2 + elif [[ "$unprivileged" = 1 && "$value" -lt 1024 ]]; then + echo "privileged port requested" + return 3 + fi + fi +} + +######################## +# Validate if the provided argument is a valid IPv4 address +# Arguments: +# $1 - IP to validate +# Returns: +# Boolean +######################### +validate_ipv4() { + local ip="${1:?ip is missing}" + local stat=1 + + if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then + read -r -a ip_array <<< "$(tr '.' ' ' <<< "$ip")" + [[ ${ip_array[0]} -le 255 && ${ip_array[1]} -le 255 \ + && ${ip_array[2]} -le 255 && ${ip_array[3]} -le 255 ]] + stat=$? + fi + return $stat +} + +######################## +# Validate a string format +# Arguments: +# $1 - String to validate +# Returns: +# Boolean +######################### +validate_string() { + local string + local min_length=-1 + local max_length=-1 + + # Parse flags + while [ "$#" -gt 0 ]; do + case "$1" in + -min-length) + shift + min_length=${1:-} + ;; + -max-length) + shift + max_length=${1:-} + ;; + --) + shift + break + ;; + -*) + stderr_print "unrecognized flag $1" + return 1 + ;; + *) + break + ;; + esac + shift + done + + if [ "$#" -gt 1 ]; then + stderr_print "too many arguments provided" + return 2 + elif [ "$#" -eq 0 ]; then + stderr_print "missing string" + return 1 + else + string=$1 + fi + + if [[ "$min_length" -ge 0 ]] && [[ "${#string}" -lt "$min_length" ]]; then + echo "string length is less than $min_length" + return 1 + fi + if [[ "$max_length" -ge 0 ]] && [[ "${#string}" -gt "$max_length" ]]; then + echo "string length is great than $max_length" + return 1 + fi +} diff --git a/bitnami/postgresql/12/debian-10/prebuildfs/libversion.sh b/bitnami/postgresql/12/debian-10/prebuildfs/libversion.sh new file mode 100644 index 000000000000..b16090cfe1f4 --- /dev/null +++ b/bitnami/postgresql/12/debian-10/prebuildfs/libversion.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# +# Library for managing versions strings + +# Load Generic Libraries +. ./liblog.sh + +# Functions +######################## +# Gets semantic version +# Arguments: +# $1 - version: string to extract major.minor.patch +# $2 - section: 1 to extract major, 2 to extract minor, 3 to extract patch +# Returns: +# array with the major, minor and release +######################### +get_sematic_version () { + local version="${1:?version is required}" + local section="${2:?section is required}" + local -a version_sections + + #Regex to parse versions: x.y.z + local -r regex='([0-9]+)(\.([0-9]+)(\.([0-9]+))?)?' + + if [[ "$version" =~ $regex ]]; then + local i=1 + local j=1 + local n=${#BASH_REMATCH[*]} + + while [[ $i -lt $n ]]; do + if [[ -n "${BASH_REMATCH[$i]}" ]] && [[ "${BASH_REMATCH[$i]:0:1}" != '.' ]]; then + version_sections[$j]=${BASH_REMATCH[$i]} + ((j++)) + fi + ((i++)) + done + + local number_regex='^[0-9]+$' + if [[ "$section" =~ $number_regex ]] && (( $section > 0 )) && (( $section <= 3 )); then + echo "${version_sections[$section]}" + return + else + stderr_print "Section allowed values are: 1, 2, and 3" + return 1 + fi + fi +} diff --git a/bitnami/postgresql/12/debian-10/prebuildfs/opt/bitnami/.exists b/bitnami/postgresql/12/debian-10/prebuildfs/opt/bitnami/.exists new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/bitnami/postgresql/12/debian-10/rootfs/entrypoint.sh b/bitnami/postgresql/12/debian-10/rootfs/entrypoint.sh new file mode 100755 index 000000000000..2be8e9121691 --- /dev/null +++ b/bitnami/postgresql/12/debian-10/rootfs/entrypoint.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +set -o errexit +set -o nounset +set -o pipefail +#set -o xtrace +# shellcheck disable=SC1091 + +# Load libraries +. /libbitnami.sh +. /libpostgresql.sh + +# Load PostgreSQL environment variables +eval "$(postgresql_env)" +export MODULE=postgresql + +print_welcome_page + +# Enable the nss_wrapper settings +postgresql_enable_nss_wrapper + +if [[ "$*" = *"/run.sh"* ]]; then + info "** Starting PostgreSQL setup **" + /setup.sh + touch "$POSTGRESQL_TMP_DIR"/.initialized + info "** PostgreSQL setup finished! **" +fi + +echo "" +exec "$@" diff --git a/bitnami/postgresql/12/debian-10/rootfs/libpostgresql.sh b/bitnami/postgresql/12/debian-10/rootfs/libpostgresql.sh new file mode 100644 index 000000000000..2750369ca486 --- /dev/null +++ b/bitnami/postgresql/12/debian-10/rootfs/libpostgresql.sh @@ -0,0 +1,941 @@ +#!/bin/bash +# +# Bitnami PostgreSQL library + +# shellcheck disable=SC1090 +# shellcheck disable=SC1091 + +# Load Generic Libraries +. /libfile.sh +. /liblog.sh +. /libservice.sh +. /libvalidations.sh + + +######################## +# Overwrite info, debug, warn and error functions (liblog.sh) +######################## +postgresql_info() { + MODULE=postgresql info "${*}" +} +postgresql_debug() { + MODULE=postgresql debug "${*}" +} +postgresql_warn() { + MODULE=postgresql warn "${*}" +} +postgresql_error() { + MODULE=postgresql error "${*}" +} + +######################## +# Configure libnss_wrapper so PostgreSQL commands work with a random user. +# Globals: +# POSTGRESQL_* +# Arguments: +# None +# Returns: +# None +######################### +postgresql_enable_nss_wrapper() { + if ! getent passwd "$(id -u)" &> /dev/null && [ -e "$NSS_WRAPPER_LIB" ]; then + postgresql_debug "Configuring libnss_wrapper..." + export LD_PRELOAD="$NSS_WRAPPER_LIB" + # shellcheck disable=SC2155 + export NSS_WRAPPER_PASSWD="$(mktemp)" + # shellcheck disable=SC2155 + export NSS_WRAPPER_GROUP="$(mktemp)" + echo "postgres:x:$(id -u):$(id -g):PostgreSQL:$POSTGRESQL_DATA_DIR:/bin/false" > "$NSS_WRAPPER_PASSWD" + echo "postgres:x:$(id -g):" > "$NSS_WRAPPER_GROUP" + fi +} + +######################## +# Load global variables used on PostgreSQL configuration. +# Globals: +# POSTGRESQL_* +# Arguments: +# None +# Returns: +# Series of exports to be used as 'eval' arguments +######################### +postgresql_env() { + declare_env_alias() { + local -r alias="${1:?missing environment variable alias}" + local -r original="${2:?missing original environment variable}" + + if printenv "${original}" > /dev/null; then + cat << EOF +export $alias="${!original}" +EOF + fi + } + + # Alias created for official PostgreSQL image compatibility + [[ -z "${POSTGRESQL_DATABASE:-}" ]] && declare_env_alias POSTGRESQL_DATABASE POSTGRES_DB + [[ -z "${POSTGRESQL_USERNAME:-}" ]] && declare_env_alias POSTGRESQL_USERNAME POSTGRES_USER + [[ -z "${POSTGRESQL_DATA_DIR:-}" ]] && declare_env_alias POSTGRESQL_DATA_DIR PGDATA + + local -r suffixes=( + "PASSWORD" "POSTGRES_PASSWORD" "INITDB_WAL_DIR" "INITDB_ARGS" "CLUSTER_APP_NAME" + "MASTER_HOST" "MASTER_PORT_NUMBER" "NUM_SYNCHRONOUS_REPLICAS" + "PORT_NUMBER" "REPLICATION_MODE" "REPLICATION_PASSWORD" "REPLICATION_USER" "FSYNC" + "SYNCHRONOUS_COMMIT_MODE" "PASSWORD_FILE" "POSTGRES_PASSWORD_FILE" + "REPLICATION_PASSWORD_FILE" "INIT_MAX_TIMEOUT" + ) + for s in "${suffixes[@]}"; do + declare_env_alias "POSTGRESQL_${s}" "POSTGRES_${s}" + done + + # Ensure the image is compatible with Helm chart 3.x.x series + local -r postgresql_data="${POSTGRESQL_DATA_DIR:-${PGDATA:-}}" + if [[ -n "${postgresql_data:-}" ]]; then + if [[ -d "${postgresql_data}/data" ]] || [[ "${postgresql_data}" = "/bitnami/postgresql" ]]; then + postgresql_warn "Data directory is set with a legacy value, adapting POSTGRESQL_DATA_DIR..." + postgresql_warn "POSTGRESQL_DATA_DIR set to \"${postgresql_data}/data\"!!" + cat << EOF +export POSTGRESQL_DATA_DIR="${postgresql_data}/data" +EOF + fi + fi + + cat <<"EOF" +# Paths +export POSTGRESQL_VOLUME_DIR="${POSTGRESQL_VOLUME_DIR:-/bitnami/postgresql}" +export POSTGRESQL_DATA_DIR="${POSTGRESQL_DATA_DIR:-$POSTGRESQL_VOLUME_DIR/data}" +export POSTGRESQL_BASE_DIR="/opt/bitnami/postgresql" +export POSTGRESQL_CONF_DIR="$POSTGRESQL_BASE_DIR/conf" +export POSTGRESQL_MOUNTED_CONF_DIR="/bitnami/postgresql/conf" +export POSTGRESQL_CONF_FILE="$POSTGRESQL_CONF_DIR/postgresql.conf" +export POSTGRESQL_PGHBA_FILE="$POSTGRESQL_CONF_DIR/pg_hba.conf" +export POSTGRESQL_RECOVERY_FILE="$POSTGRESQL_DATA_DIR/recovery.conf" +export POSTGRESQL_LOG_DIR="$POSTGRESQL_BASE_DIR/logs" +export POSTGRESQL_LOG_FILE="$POSTGRESQL_LOG_DIR/postgresql.log" +export POSTGRESQL_TMP_DIR="$POSTGRESQL_BASE_DIR/tmp" +export POSTGRESQL_PID_FILE="$POSTGRESQL_TMP_DIR/postgresql.pid" +export POSTGRESQL_BIN_DIR="$POSTGRESQL_BASE_DIR/bin" +export POSTGRESQL_INITSCRIPTS_DIR=/docker-entrypoint-initdb.d +export POSTGRESQL_PREINITSCRIPTS_DIR=/docker-entrypoint-preinitdb.d +export PATH="$POSTGRESQL_BIN_DIR:$PATH" + +# Users +export POSTGRESQL_DAEMON_USER="postgresql" +export POSTGRESQL_DAEMON_GROUP="postgresql" + +# Version +export POSTGRESQL_VERSION="$(echo "$BITNAMI_IMAGE_VERSION" | grep -oE "^[0-9]+\.[0-9]+\.[0-9]+")" +export POSTGRESQL_MAJOR_VERSION="$(echo "$BITNAMI_IMAGE_VERSION" | grep -oE "^[0-9]+")" + +# Settings +export POSTGRESQL_INIT_MAX_TIMEOUT=${POSTGRESQL_INIT_MAX_TIMEOUT:-60} +export POSTGRESQL_CLUSTER_APP_NAME=${POSTGRESQL_CLUSTER_APP_NAME:-walreceiver} +export POSTGRESQL_DATABASE="${POSTGRESQL_DATABASE:-postgres}" +export POSTGRESQL_INITDB_ARGS="${POSTGRESQL_INITDB_ARGS:-}" +export ALLOW_EMPTY_PASSWORD="${ALLOW_EMPTY_PASSWORD:-no}" +export POSTGRESQL_INITDB_WAL_DIR="${POSTGRESQL_INITDB_WAL_DIR:-}" +export POSTGRESQL_MASTER_HOST="${POSTGRESQL_MASTER_HOST:-}" +export POSTGRESQL_MASTER_PORT_NUMBER="${POSTGRESQL_MASTER_PORT_NUMBER:-5432}" +export POSTGRESQL_NUM_SYNCHRONOUS_REPLICAS="${POSTGRESQL_NUM_SYNCHRONOUS_REPLICAS:-0}" +export POSTGRESQL_PORT_NUMBER="${POSTGRESQL_PORT_NUMBER:-5432}" +export POSTGRESQL_REPLICATION_MODE="${POSTGRESQL_REPLICATION_MODE:-master}" +export POSTGRESQL_REPLICATION_USER="${POSTGRESQL_REPLICATION_USER:-}" +export POSTGRESQL_SYNCHRONOUS_COMMIT_MODE="${POSTGRESQL_SYNCHRONOUS_COMMIT_MODE:-on}" +export POSTGRESQL_FSYNC="${POSTGRESQL_FSYNC:-on}" +export POSTGRESQL_USERNAME="${POSTGRESQL_USERNAME:-postgres}" +export POSTGRESQL_ENABLE_LDAP="${POSTGRESQL_ENABLE_LDAP:-no}" +export POSTGRESQL_LDAP_URL="${POSTGRESQL_LDAP_URL:-}" +export POSTGRESQL_LDAP_PREFIX="${POSTGRESQL_LDAP_PREFIX:-}" +export POSTGRESQL_LDAP_SUFFIX="${POSTGRESQL_LDAP_SUFFIX:-}" +export POSTGRESQL_LDAP_SERVER="${POSTGRESQL_LDAP_SERVER:-}" +export POSTGRESQL_LDAP_PORT="${POSTGRESQL_LDAP_PORT:-}" +export POSTGRESQL_LDAP_SCHEME="${POSTGRESQL_LDAP_SCHEME:-}" +export POSTGRESQL_LDAP_TLS="${POSTGRESQL_LDAP_TLS:-}" +export POSTGRESQL_LDAP_BASE_DN="${POSTGRESQL_LDAP_BASE_DN:-}" +export POSTGRESQL_LDAP_BIND_DN="${POSTGRESQL_LDAP_BIND_DN:-}" +export POSTGRESQL_LDAP_BIND_PASSWORD="${POSTGRESQL_LDAP_BIND_PASSWORD:-}" +export POSTGRESQL_LDAP_SEARCH_ATTR="${POSTGRESQL_LDAP_SEARCH_ATTR:-}" +export POSTGRESQL_LDAP_SEARCH_FILTER="${POSTGRESQL_LDAP_SEARCH_FILTER:-}" + +# Internal +export POSTGRESQL_FIRST_BOOT="yes" +EOF + if [[ -z "${POSTGRESQL_INITSCRIPTS_USERNAME:-}" ]]; then + cat <<"EOF" +export POSTGRESQL_INITSCRIPTS_USERNAME="${POSTGRESQL_USERNAME}" +EOF + else + cat <<"EOF" +export POSTGRESQL_INITSCRIPTS_USERNAME="${POSTGRESQL_INITSCRIPTS_USERNAME}" +EOF + fi + if [[ -f "${POSTGRESQL_PASSWORD_FILE:-}" ]]; then + cat <<"EOF" +export POSTGRESQL_PASSWORD="$(< "${POSTGRESQL_PASSWORD_FILE}")" +EOF + else + cat <<"EOF" +export POSTGRESQL_PASSWORD="${POSTGRESQL_PASSWORD:-}" +EOF + fi + if [[ -f "${POSTGRESQL_REPLICATION_PASSWORD_FILE:-}" ]]; then + cat <<"EOF" +export POSTGRESQL_REPLICATION_PASSWORD="$(< "${POSTGRESQL_REPLICATION_PASSWORD_FILE}")" +EOF + else + cat <<"EOF" +export POSTGRESQL_REPLICATION_PASSWORD="${POSTGRESQL_REPLICATION_PASSWORD:-}" +EOF + fi + if [[ -f "${POSTGRESQL_POSTGRES_PASSWORD_FILE:-}" ]]; then + cat <<"EOF" +export POSTGRESQL_POSTGRES_PASSWORD="$(< "${POSTGRESQL_POSTGRES_PASSWORD_FILE}")" +EOF + else + cat <<"EOF" +export POSTGRESQL_POSTGRES_PASSWORD="${POSTGRESQL_POSTGRES_PASSWORD:-}" +EOF + fi + if [[ -z "${POSTGRESQL_INITSCRIPTS_PASSWORD:-}" ]]; then + cat <<"EOF" +export POSTGRESQL_INITSCRIPTS_PASSWORD="${POSTGRESQL_PASSWORD:-}" +EOF + else + cat <<"EOF" +export POSTGRESQL_INITSCRIPTS_PASSWORD="${POSTGRESQL_INITSCRIPTS_PASSWORD:-}" +EOF + fi +} + +######################## +# Validate settings in POSTGRESQL_* environment variables +# Globals: +# POSTGRESQL_* +# Arguments: +# None +# Returns: +# None +######################### +postgresql_validate() { + postgresql_info "Validating settings in POSTGRESQL_* env vars.." + local error_code=0 + + # Auxiliary functions + print_validation_error() { + postgresql_error "$1" + error_code=1 + } + + empty_password_enabled_warn() { + postgresql_warn "You set the environment variable ALLOW_EMPTY_PASSWORD=${ALLOW_EMPTY_PASSWORD}. For safety reasons, do not use this flag in a production environment." + } + empty_password_error() { + print_validation_error "The $1 environment variable is empty or not set. Set the environment variable ALLOW_EMPTY_PASSWORD=yes to allow the container to be started with blank passwords. This is recommended only for development." + } + if is_boolean_yes "$ALLOW_EMPTY_PASSWORD"; then + empty_password_enabled_warn + else + if [[ -z "$POSTGRESQL_PASSWORD" ]]; then + empty_password_error "POSTGRESQL_PASSWORD" + fi + if (( ${#POSTGRESQL_PASSWORD} > 100 )); then + print_validation_error "The password cannot be longer than 100 characters. Set the environment variable POSTGRESQL_PASSWORD with a shorter value" + fi + if [[ -n "$POSTGRESQL_USERNAME" ]] && [[ -z "$POSTGRESQL_PASSWORD" ]]; then + empty_password_error "POSTGRESQL_PASSWORD" + fi + if [[ -n "$POSTGRESQL_USERNAME" ]] && [[ "$POSTGRESQL_USERNAME" != "postgres" ]] && [[ -n "$POSTGRESQL_PASSWORD" ]] && [[ -z "$POSTGRESQL_DATABASE" ]]; then + print_validation_error "In order to use a custom PostgreSQL user you need to set the environment variable POSTGRESQL_DATABASE as well" + fi + fi + if [[ -n "$POSTGRESQL_REPLICATION_MODE" ]]; then + if [[ "$POSTGRESQL_REPLICATION_MODE" = "master" ]]; then + if (( POSTGRESQL_NUM_SYNCHRONOUS_REPLICAS < 0 )); then + print_validation_error "The number of synchronous replicas cannot be less than 0. Set the environment variable POSTGRESQL_NUM_SYNCHRONOUS_REPLICAS" + fi + elif [[ "$POSTGRESQL_REPLICATION_MODE" = "slave" ]]; then + if [[ -z "$POSTGRESQL_MASTER_HOST" ]]; then + print_validation_error "Slave replication mode chosen without setting the environment variable POSTGRESQL_MASTER_HOST. Use it to indicate where the Master node is running" + fi + if [[ -z "$POSTGRESQL_REPLICATION_USER" ]]; then + print_validation_error "Slave replication mode chosen without setting the environment variable POSTGRESQL_REPLICATION_USER. Make sure that the master also has this parameter set" + fi + else + print_validation_error "Invalid replication mode. Available options are 'master/slave'" + fi + # Common replication checks + if [[ -n "$POSTGRESQL_REPLICATION_USER" ]] && [[ -z "$POSTGRESQL_REPLICATION_PASSWORD" ]]; then + empty_password_error "POSTGRESQL_REPLICATION_PASSWORD" + fi + else + if is_boolean_yes "$ALLOW_EMPTY_PASSWORD"; then + empty_password_enabled_warn + else + if [[ -z "$POSTGRESQL_PASSWORD" ]]; then + empty_password_error "POSTGRESQL_PASSWORD" + fi + if [[ -n "$POSTGRESQL_USERNAME" ]] && [[ -z "$POSTGRESQL_PASSWORD" ]]; then + empty_password_error "POSTGRESQL_PASSWORD" + fi + fi + fi + + if ! is_yes_no_value "$POSTGRESQL_ENABLE_LDAP"; then + empty_password_error "The values allowed for POSTGRESQL_ENABLE_LDAP are: yes or no" + fi + + if is_boolean_yes "$POSTGRESQL_ENABLE_LDAP" && [[ -n "$POSTGRESQL_LDAP_URL" ]] && [[ -n "$POSTGRESQL_LDAP_SERVER" ]]; then + empty_password_error "You can not set POSTGRESQL_LDAP_URL and POSTGRESQL_LDAP_SERVER at the same time. Check your LDAP configuration." + fi + + [[ "$error_code" -eq 0 ]] || exit "$error_code" +} + +######################## +# Create basic postgresql.conf file using the example provided in the share/ folder +# Globals: +# POSTGRESQL_* +# Arguments: +# None +# Returns: +# None +######################### +postgresql_create_config() { + postgresql_info "postgresql.conf file not detected. Generating it..." + cp "$POSTGRESQL_BASE_DIR/share/postgresql.conf.sample" "$POSTGRESQL_CONF_FILE" + # Update default value for 'include_dir' directive + # ref: https://github.com/postgres/postgres/commit/fb9c475597c245562a28d1e916b575ac4ec5c19f#diff-f5544d9b6d218cc9677524b454b41c60 + if ! grep include_dir "$POSTGRESQL_CONF_FILE" > /dev/null; then + postgresql_error "include_dir line is not present in $POSTGRESQL_CONF_FILE. This may be due to a changes in a new version of PostgreSQL. Please check" + exit 1 + fi + sed -i -E "/#include_dir/i include_dir = 'conf.d'" "$POSTGRESQL_CONF_FILE" +} + +######################## +# Create ldap auth configuration in pg_hba, +# but keeps postgres user to authenticate locally +# Globals: +# POSTGRESQL_* +# Arguments: +# None +# Returns: +# None +######################### +postgresql_ldap_auth_configuration() { + postgresql_info "Generating LDAP authentication configuration" + local ldap_configuration="" + + if [[ -n "$POSTGRESQL_LDAP_URL" ]]; then + ldap_configuration="ldapurl=\"$POSTGRESQL_LDAP_URL\"" + else + ldap_configuration="ldapserver=${POSTGRESQL_LDAP_SERVER}" + + [[ -n "$POSTGRESQL_LDAP_PREFIX" ]] && ldap_configuration+=" ldapprefix=\"${POSTGRESQL_LDAP_PREFIX}\"" + [[ -n "$POSTGRESQL_LDAP_SUFFIX" ]] && ldap_configuration+=" ldapsuffix=\"${POSTGRESQL_LDAP_SUFFIX}\"" + [[ -n "$POSTGRESQL_LDAP_PORT" ]] && ldap_configuration+=" ldapport=${POSTGRESQL_LDAP_PORT}" + [[ -n "$POSTGRESQL_LDAP_BASE_DN" ]] && ldap_configuration+=" ldapbasedn=\"${POSTGRESQL_LDAP_BASE_DN}\"" + [[ -n "$POSTGRESQL_LDAP_BIND_DN" ]] && ldap_configuration+=" ldapbinddn=\"${POSTGRESQL_LDAP_BIND_DN}\"" + [[ -n "$POSTGRESQL_LDAP_BIND_PASSWORD" ]] && ldap_configuration+=" ldapbindpasswd=${POSTGRESQL_LDAP_BIND_PASSWORD}" + [[ -n "$POSTGRESQL_LDAP_SEARCH_ATTR" ]] && ldap_configuration+=" ldapsearchattribute=${POSTGRESQL_LDAP_SEARCH_ATTR}" + [[ -n "$POSTGRESQL_LDAP_SEARCH_FILTER" ]] && ldap_configuration+=" ldapsearchfilter=\"${POSTGRESQL_LDAP_SEARCH_FILTER}\"" + [[ -n "$POSTGRESQL_LDAP_TLS" ]] && ldap_configuration+=" ldaptls=${POSTGRESQL_LDAP_TLS}" + [[ -n "$POSTGRESQL_LDAP_SCHEME" ]] && ldap_configuration+=" ldapscheme=${POSTGRESQL_LDAP_SCHEME}" + fi + + cat << EOF > "$POSTGRESQL_PGHBA_FILE" +host all postgres 0.0.0.0/0 trust +host all postgres ::1/128 trust +host all all 0.0.0.0/0 ldap $ldap_configuration +host all all ::1/128 ldap $ldap_configuration +EOF +} + +######################## +# Create local auth configuration in pg_hba +# Globals: +# POSTGRESQL_* +# Arguments: +# None +# Returns: +# None +######################### +postgresql_password_auth_configuration() { + postgresql_info "Generating local authentication configuration" + cat << EOF > "$POSTGRESQL_PGHBA_FILE" +host all all 0.0.0.0/0 trust +host all all ::1/128 trust +EOF +} + +######################## +# Create basic pg_hba.conf file +# Globals: +# POSTGRESQL_* +# Arguments: +# None +# Returns: +# None +######################### +postgresql_create_pghba() { + postgresql_info "pg_hba.conf file not detected. Generating it..." + + if is_boolean_yes "$POSTGRESQL_ENABLE_LDAP"; then + postgresql_ldap_auth_configuration + else + postgresql_password_auth_configuration + fi +} + +######################## +# Change pg_hba.conf so it allows local UNIX socket-based connections +# Globals: +# POSTGRESQL_* +# Arguments: +# None +# Returns: +# None +######################### +postgresql_allow_local_connection() { + cat << EOF >> "$POSTGRESQL_PGHBA_FILE" +local all all trust +EOF +} + +######################## +# Change pg_hba.conf so only password-based authentication is allowed +# Globals: +# POSTGRESQL_* +# Arguments: +# None +# Returns: +# None +######################### +postgresql_restrict_pghba() { + if [[ -n "$POSTGRESQL_PASSWORD" ]]; then + sed -i 's/trust/md5/g' "$POSTGRESQL_PGHBA_FILE" + fi +} + +######################## +# Change pg_hba.conf so it allows access from replication users +# Globals: +# POSTGRESQL_* +# Arguments: +# None +# Returns: +# None +######################### +postgresql_add_replication_to_pghba() { + local replication_auth="trust" + if [[ -n "$POSTGRESQL_REPLICATION_PASSWORD" ]]; then + replication_auth="md5" + fi + cat << EOF >> "$POSTGRESQL_PGHBA_FILE" +host replication all 0.0.0.0/0 ${replication_auth} +EOF +} + +######################## +# Change a PostgreSQL configuration file by setting a property +# Globals: +# POSTGRESQL_* +# Arguments: +# $1 - property +# $2 - value +# $3 - Path to configuration file (default: $POSTGRESQL_CONF_FILE) +# Returns: +# None +######################### +postgresql_set_property() { + local -r property="${1:?missing property}" + local -r value="${2:?missing value}" + local -r conf_file="${3:-$POSTGRESQL_CONF_FILE}" + sed -i "s?^#*\s*${property}\s*=.*?${property} = '${value}'?g" "$conf_file" +} + +######################## +# Create a user for master-slave replication +# Globals: +# POSTGRESQL_* +# Arguments: +# None +# Returns: +# None +######################### +postgresql_create_replication_user() { + local -r escaped_password="${POSTGRESQL_REPLICATION_PASSWORD//\'/\'\'}" + postgresql_info "Creating replication user $POSTGRESQL_REPLICATION_USER" + echo "CREATE ROLE \"$POSTGRESQL_REPLICATION_USER\" REPLICATION LOGIN ENCRYPTED PASSWORD '$escaped_password'" | postgresql_execute +} + +######################## +# Change postgresql.conf by setting replication parameters +# Globals: +# POSTGRESQL_* +# Arguments: +# None +# Returns: +# None +######################### +postgresql_configure_replication_parameters() { + postgresql_info "Configuring replication parameters" + postgresql_set_property "wal_level" "hot_standby" + postgresql_set_property "max_wal_size" "400MB" + postgresql_set_property "max_wal_senders" "16" + postgresql_set_property "wal_keep_segments" "12" + postgresql_set_property "hot_standby" "on" + if (( POSTGRESQL_NUM_SYNCHRONOUS_REPLICAS > 0 )); then + postgresql_set_property "synchronous_commit" "$POSTGRESQL_SYNCHRONOUS_COMMIT_MODE" + postgresql_set_property "synchronous_standby_names" "${POSTGRESQL_NUM_SYNCHRONOUS_REPLICAS} (\"${POSTGRESQL_CLUSTER_APP_NAME}\")" + fi +} + +######################## +# Change postgresql.conf by setting fsync +# Globals: +# POSTGRESQL_* +# Arguments: +# None +# Returns: +# None +######################### +postgresql_configure_fsync() { + postgresql_info "Configuring fsync" + postgresql_set_property "fsync" "$POSTGRESQL_FSYNC" +} + +######################## +# Alter password of the postgres user +# Globals: +# POSTGRESQL_* +# Arguments: +# Password +# Returns: +# None +######################### +postgresql_alter_postgres_user() { + local -r escaped_password="${1//\'/\'\'}" + postgresql_info "Changing password of postgres" + echo "ALTER ROLE postgres WITH PASSWORD '$escaped_password';" | postgresql_execute +} + +######################## +# Create an admin user with all privileges in POSTGRESQL_DATABASE +# Globals: +# POSTGRESQL_* +# Arguments: +# None +# Returns: +# None +######################### +postgresql_create_admin_user() { + local -r escaped_password="${POSTGRESQL_PASSWORD//\'/\'\'}" + postgresql_info "Creating user ${POSTGRESQL_USERNAME}" + echo "CREATE ROLE \"${POSTGRESQL_USERNAME}\" WITH LOGIN CREATEDB PASSWORD '${escaped_password}';" | postgresql_execute + postgresql_info "Grating access to \"${POSTGRESQL_USERNAME}\" to the database \"${POSTGRESQL_DATABASE}\"" + echo "GRANT ALL PRIVILEGES ON DATABASE \"${POSTGRESQL_DATABASE}\" TO \"${POSTGRESQL_USERNAME}\"\;" | postgresql_execute "" "postgres" "$POSTGRESQL_PASSWORD" +} + +######################## +# Create a database with name $POSTGRESQL_DATABASE +# Globals: +# POSTGRESQL_* +# Arguments: +# None +# Returns: +# None +######################### +postgresql_create_custom_database() { + echo "CREATE DATABASE \"$POSTGRESQL_DATABASE\"" | postgresql_execute "" "postgres" "" "localhost" +} + +######################## +# Change postgresql.conf to listen in 0.0.0.0 +# Arguments: +# None +# Returns: +# None +######################### +postgresql_enable_remote_connections() { + postgresql_set_property "listen_addresses" "*" +} + +######################## +# Check if a given configuration file was mounted externally +# Globals: +# POSTGRESQL_* +# Arguments: +# $1 - Filename +# Returns: +# 1 if the file was mounted externally, 0 otherwise +######################### +postgresql_is_file_external() { + local -r filename=$1 + if [[ -d "$POSTGRESQL_MOUNTED_CONF_DIR" ]] && [[ -f "$POSTGRESQL_MOUNTED_CONF_DIR"/"$filename" ]]; then + return 0 + else + return 1 + fi +} + +######################## +# Remove flags and postmaster files from a previous run (case of container restart) +# Globals: +# POSTGRESQL_* +# Arguments: +# None +# Returns: +# None +######################### +postgresql_clean_from_restart() { + local -r -a files=( + "$POSTGRESQL_DATA_DIR"/postmaster.pid + "$POSTGRESQL_DATA_DIR"/standby.signal + "$POSTGRESQL_DATA_DIR"/recovery.signal + ) + + for file in "${files[@]}"; do + if [[ -f "$file" ]]; then + postgresql_info "Cleaning stale $file file" + rm "$file" + fi + done +} + +######################## +# Ensure PostgreSQL is initialized +# Globals: +# POSTGRESQL_* +# Arguments: +# None +# Returns: +# None +######################### +postgresql_initialize() { + postgresql_info "Initializing PostgreSQL database..." + postgresql_clean_from_restart + # This fixes an issue where the trap would kill the entrypoint.sh, if a PID was left over from a previous run + # Exec replaces the process without creating a new one, and when the container is restarted it may have the same PID + rm -f "$POSTGRESQL_PID_FILE" + + # User injected custom configuration + if [[ -d "$POSTGRESQL_MOUNTED_CONF_DIR" ]] && compgen -G "$POSTGRESQL_MOUNTED_CONF_DIR"/* > /dev/null; then + postgresql_debug "Copying files from $POSTGRESQL_MOUNTED_CONF_DIR to $POSTGRESQL_CONF_DIR" + cp -fr "$POSTGRESQL_MOUNTED_CONF_DIR"/. "$POSTGRESQL_CONF_DIR" + fi + local create_conf_file=yes + local create_pghba_file=yes + + if postgresql_is_file_external "postgresql.conf"; then + postgresql_info "Custom configuration $POSTGRESQL_CONF_FILE detected" + create_conf_file=no + fi + + if postgresql_is_file_external "pg_hba.conf"; then + postgresql_info "Custom configuration $POSTGRESQL_PGHBA_FILE detected" + create_pghba_file=no + fi + + postgresql_debug "Ensuring expected directories/files exist..." + for dir in "$POSTGRESQL_TMP_DIR" "$POSTGRESQL_LOG_DIR"; do + ensure_dir_exists "$dir" + am_i_root && chown "$POSTGRESQL_DAEMON_USER:$POSTGRESQL_DAEMON_GROUP" "$dir" + done + is_boolean_yes "$create_conf_file" && postgresql_create_config + is_boolean_yes "$create_pghba_file" && postgresql_create_pghba && postgresql_allow_local_connection + + if ! is_dir_empty "$POSTGRESQL_DATA_DIR"; then + postgresql_info "Deploying PostgreSQL with persisted data..." + export POSTGRESQL_FIRST_BOOT="no" + is_boolean_yes "$create_pghba_file" && postgresql_restrict_pghba + is_boolean_yes "$create_conf_file" && postgresql_configure_replication_parameters + is_boolean_yes "$create_conf_file" && postgresql_configure_fsync + [[ "$POSTGRESQL_REPLICATION_MODE" = "master" ]] && [[ -n "$POSTGRESQL_REPLICATION_USER" ]] && is_boolean_yes "$create_pghba_file" && postgresql_add_replication_to_pghba + [[ "$POSTGRESQL_REPLICATION_MODE" = "slave" ]] && postgresql_configure_recovery + else + ensure_dir_exists "$POSTGRESQL_DATA_DIR" + am_i_root && chown "$POSTGRESQL_DAEMON_USER:$POSTGRESQL_DAEMON_GROUP" "$POSTGRESQL_DATA_DIR" + if [[ "$POSTGRESQL_REPLICATION_MODE" = "master" ]]; then + postgresql_master_init_db + postgresql_start_bg + [[ -n "${POSTGRESQL_DATABASE}" ]] && [[ "$POSTGRESQL_DATABASE" != "postgres" ]] && postgresql_create_custom_database + if [[ "$POSTGRESQL_USERNAME" = "postgres" ]]; then + postgresql_alter_postgres_user "$POSTGRESQL_PASSWORD" + else + if [[ -n "$POSTGRESQL_POSTGRES_PASSWORD" ]]; then + postgresql_alter_postgres_user "$POSTGRESQL_POSTGRES_PASSWORD" + fi + postgresql_create_admin_user + fi + is_boolean_yes "$create_pghba_file" && postgresql_restrict_pghba + [[ -n "$POSTGRESQL_REPLICATION_USER" ]] && postgresql_create_replication_user + is_boolean_yes "$create_conf_file" && postgresql_configure_replication_parameters + is_boolean_yes "$create_conf_file" && postgresql_configure_fsync + [[ -n "$POSTGRESQL_REPLICATION_USER" ]] && is_boolean_yes "$create_pghba_file" && postgresql_add_replication_to_pghba + else + postgresql_slave_init_db + is_boolean_yes "$create_pghba_file" && postgresql_restrict_pghba + is_boolean_yes "$create_conf_file" && postgresql_configure_replication_parameters + is_boolean_yes "$create_conf_file" && postgresql_configure_fsync + postgresql_configure_recovery + fi + fi + + # Delete conf files generated on first run + rm -f "$POSTGRESQL_DATA_DIR"/postgresql.conf "$POSTGRESQL_DATA_DIR"/pg_hba.conf +} + +######################## +# Run custom pre-initialization scripts +# Globals: +# POSTGRESQL_* +# Arguments: +# None +# Returns: +# None +######################### +postgresql_custom_pre_init_scripts() { + info "Loading custom pre-init scripts..." + if [[ -n $(find "$POSTGRESQL_PREINITSCRIPTS_DIR/" -type f -name "*.sh") ]]; then + info "Loading user's custom files from $POSTGRESQL_PREINITSCRIPTS_DIR ..."; + find "$POSTGRESQL_PREINITSCRIPTS_DIR/" -type f -name "*.sh" | sort | while read -r f; do + if [[ -x "$f" ]]; then + debug "Executing $f"; "$f" + else + debug "Sourcing $f"; . "$f" + fi + done + fi +} + +######################## +# Run custom initialization scripts +# Globals: +# POSTGRESQL_* +# Arguments: +# None +# Returns: +# None +######################### +postgresql_custom_init_scripts() { + postgresql_info "Loading custom scripts..." + if [[ -n $(find "$POSTGRESQL_INITSCRIPTS_DIR/" -type f -regex ".*\.\(sh\|sql\|sql.gz\)") ]] && [[ ! -f "$POSTGRESQL_VOLUME_DIR/.user_scripts_initialized" ]] ; then + postgresql_info "Loading user's custom files from $POSTGRESQL_INITSCRIPTS_DIR ..."; + postgresql_start_bg + find "$POSTGRESQL_INITSCRIPTS_DIR/" -type f -regex ".*\.\(sh\|sql\|sql.gz\)" | sort | while read -r f; do + case "$f" in + *.sh) + if [[ -x "$f" ]]; then + postgresql_debug "Executing $f"; "$f" + else + postgresql_debug "Sourcing $f"; . "$f" + fi + ;; + *.sql) postgresql_debug "Executing $f"; postgresql_execute "$POSTGRESQL_DATABASE" "$POSTGRESQL_INITSCRIPTS_USERNAME" "$POSTGRESQL_INITSCRIPTS_PASSWORD" < "$f";; + *.sql.gz) postgresql_debug "Executing $f"; gunzip -c "$f" | postgresql_execute "$POSTGRESQL_DATABASE" "$POSTGRESQL_INITSCRIPTS_USERNAME" "$POSTGRESQL_INITSCRIPTS_PASSWORD";; + *) postgresql_debug "Ignoring $f" ;; + esac + done + touch "$POSTGRESQL_VOLUME_DIR"/.user_scripts_initialized + fi +} + +######################## +# Stop PostgreSQL +# Globals: +# POSTGRESQL_* +# Arguments: +# None +# Returns: +# None +######################### +postgresql_stop() { + postgresql_info "Stopping PostgreSQL..." + stop_service_using_pid "$POSTGRESQL_PID_FILE" +} + +######################## +# Execute an arbitrary query/queries against the running PostgreSQL service +# Stdin: +# Query/queries to execute +# Globals: +# BITNAMI_DEBUG +# POSTGRESQL_* +# Arguments: +# $1 - Database where to run the queries +# $2 - User to run queries +# $3 - Password +# $4 - Host +# $5 - Port +# $6 - Extra options (eg. -tA) +# Returns: +# None +postgresql_execute() { + local -r db="${1:-}" + local -r user="${2:-postgres}" + local -r pass="${3:-}" + local -r host="${4:-localhost}" + local -r port="${5:-5432}" + local -r opts="${6:-}" + + local args=( "-h" "$host" "-p" "$port" "-U" "$user" ) + local cmd=("$POSTGRESQL_BIN_DIR/psql") + [[ -n "$db" ]] && args+=( "-d" "$db" ) + [[ -n "$opts" ]] && args+=( "$opts" ) + if [[ "${BITNAMI_DEBUG:-false}" = true ]]; then + PGPASSWORD=$pass "${cmd[@]}" "${args[@]}" + elif [[ "${NO_ERRORS:-false}" = true ]]; then + PGPASSWORD=$pass "${cmd[@]}" "${args[@]}" 2>/dev/null + else + PGPASSWORD=$pass "${cmd[@]}" "${args[@]}" >/dev/null 2>&1 + fi +} + +######################## +# Start PostgreSQL and wait until it is ready +# Globals: +# POSTGRESQL_* +# Arguments: +# None +# Returns: +# None +######################### +postgresql_start_bg() { + local -r pg_ctl_flags=("-w" "-D" "$POSTGRESQL_DATA_DIR" "-l" "$POSTGRESQL_LOG_FILE" "-o" "--config-file=$POSTGRESQL_CONF_FILE --external_pid_file=$POSTGRESQL_PID_FILE --hba_file=$POSTGRESQL_PGHBA_FILE") + postgresql_info "Starting PostgreSQL in background..." + is_postgresql_running && return + if [[ "${BITNAMI_DEBUG:-false}" = true ]]; then + "$POSTGRESQL_BIN_DIR"/pg_ctl "start" "${pg_ctl_flags[@]}" + else + "$POSTGRESQL_BIN_DIR"/pg_ctl "start" "${pg_ctl_flags[@]}" >/dev/null 2>&1 + fi + local -r pg_isready_args=("-U" "postgres") + local counter=$POSTGRESQL_INIT_MAX_TIMEOUT + while ! "$POSTGRESQL_BIN_DIR"/pg_isready "${pg_isready_args[@]}" >/dev/null 2>&1; do + sleep 1 + counter=$((counter - 1 )) + if (( counter <= 0 )); then + postgresql_error "PostgreSQL is not ready after $POSTGRESQL_INIT_MAX_TIMEOUT seconds" + exit 1 + fi + done +} + +######################## +# Check if PostgreSQL is running +# Globals: +# POSTGRESQL_* +# Arguments: +# None +# Returns: +# Boolean +######################### +is_postgresql_running() { + local pid + pid="$(get_pid_from_file "$POSTGRESQL_PID_FILE")" + + if [[ -z "$pid" ]]; then + false + else + is_service_running "$pid" + fi +} + +######################## +# Initialize master node database by running initdb +# Globals: +# POSTGRESQL_* +# Arguments: +# None +# Returns: +# Boolean +######################### +postgresql_master_init_db() { + local envExtraFlags=() + local initdb_args=() + if [[ -n "${POSTGRESQL_INITDB_ARGS}" ]]; then + read -r -a envExtraFlags <<< "$POSTGRESQL_INITDB_ARGS" + initdb_args+=("${envExtraFlags[@]}") + fi + if [[ -n "$POSTGRESQL_INITDB_WAL_DIR" ]]; then + ensure_dir_exists "$POSTGRESQL_INITDB_WAL_DIR" + am_i_root && chown "$POSTGRESQL_DAEMON_USER:$POSTGRESQL_DAEMON_GROUP" "$POSTGRESQL_INITDB_WAL_DIR" + initdb_args+=("--waldir" "$POSTGRESQL_INITDB_WAL_DIR") + fi + if [[ -n "${initdb_args[*]:-}" ]]; then + postgresql_info "Initializing PostgreSQL with ${initdb_args[*]} extra initdb arguments" + if [[ "${BITNAMI_DEBUG:-false}" = true ]]; then + "$POSTGRESQL_BIN_DIR/initdb" -E UTF8 -D "$POSTGRESQL_DATA_DIR" -U "postgres" "${initdb_args[@]}" + else + "$POSTGRESQL_BIN_DIR/initdb" -E UTF8 -D "$POSTGRESQL_DATA_DIR" -U "postgres" "${initdb_args[@]}" >/dev/null 2>&1 + fi + elif [[ "${BITNAMI_DEBUG:-false}" = true ]]; then + "$POSTGRESQL_BIN_DIR/initdb" -E UTF8 -D "$POSTGRESQL_DATA_DIR" -U "postgres" + else + "$POSTGRESQL_BIN_DIR/initdb" -E UTF8 -D "$POSTGRESQL_DATA_DIR" -U "postgres" >/dev/null 2>&1 + fi +} + +######################## +# Initialize slave node by running pg_basebackup +# Globals: +# POSTGRESQL_* +# Arguments: +# None +# Returns: +# Boolean +######################### +postgresql_slave_init_db() { + postgresql_info "Waiting for replication master to accept connections (${POSTGRESQL_INIT_MAX_TIMEOUT} timeout)..." + local -r check_args=("-U" "$POSTGRESQL_REPLICATION_USER" "-h" "$POSTGRESQL_MASTER_HOST" "-p" "$POSTGRESQL_MASTER_PORT_NUMBER" "-d" "postgres") + local -r check_cmd=("$POSTGRESQL_BIN_DIR"/pg_isready) + local ready_counter=$POSTGRESQL_INIT_MAX_TIMEOUT + + while ! PGPASSWORD=$POSTGRESQL_REPLICATION_PASSWORD "${check_cmd[@]}" "${check_args[@]}";do + sleep 1 + ready_counter=$(( ready_counter - 1 )) + if (( ready_counter <= 0 )); then + postgresql_error "PostgreSQL master is not ready after $POSTGRESQL_INIT_MAX_TIMEOUT seconds" + exit 1 + fi + + done + postgresql_info "Replicating the initial database" + local -r backup_args=("-D" "$POSTGRESQL_DATA_DIR" "-U" "$POSTGRESQL_REPLICATION_USER" "-h" "$POSTGRESQL_MASTER_HOST" "-p" "$POSTGRESQL_MASTER_PORT_NUMBER" "-X" "stream" "-w" "-v" "-P") + local -r backup_cmd=("$POSTGRESQL_BIN_DIR"/pg_basebackup) + local replication_counter=$POSTGRESQL_INIT_MAX_TIMEOUT + while ! PGPASSWORD=$POSTGRESQL_REPLICATION_PASSWORD "${backup_cmd[@]}" "${backup_args[@]}";do + postgresql_debug "Backup command failed. Sleeping and trying again" + sleep 1 + replication_counter=$(( replication_counter - 1 )) + if (( replication_counter <= 0 )); then + postgresql_error "Slave replication failed after trying for $POSTGRESQL_INIT_MAX_TIMEOUT seconds" + exit 1 + fi + done + chmod 0700 "$POSTGRESQL_DATA_DIR" +} + +######################## +# Create recovery.conf in slave node +# Globals: +# POSTGRESQL_* +# Arguments: +# None +# Returns: +# Boolean +######################### +postgresql_configure_recovery() { + postgresql_info "Setting up streaming replication slave..." + if (( POSTGRESQL_MAJOR_VERSION >= 12 )); then + postgresql_set_property "primary_conninfo" "host=${POSTGRESQL_MASTER_HOST} port=${POSTGRESQL_MASTER_PORT_NUMBER} user=${POSTGRESQL_REPLICATION_USER} password=${POSTGRESQL_REPLICATION_PASSWORD} application_name=${POSTGRESQL_CLUSTER_APP_NAME}" "$POSTGRESQL_CONF_FILE" + postgresql_set_property "promote_trigger_file" "/tmp/postgresql.trigger.${POSTGRESQL_MASTER_PORT_NUMBER}" "$POSTGRESQL_CONF_FILE" + touch "$POSTGRESQL_DATA_DIR"/standby.signal + else + cp -f "$POSTGRESQL_BASE_DIR/share/recovery.conf.sample" "$POSTGRESQL_RECOVERY_FILE" + chmod 600 "$POSTGRESQL_RECOVERY_FILE" + postgresql_set_property "standby_mode" "on" "$POSTGRESQL_RECOVERY_FILE" + postgresql_set_property "primary_conninfo" "host=${POSTGRESQL_MASTER_HOST} port=${POSTGRESQL_MASTER_PORT_NUMBER} user=${POSTGRESQL_REPLICATION_USER} password=${POSTGRESQL_REPLICATION_PASSWORD} application_name=${POSTGRESQL_CLUSTER_APP_NAME}" "$POSTGRESQL_RECOVERY_FILE" + postgresql_set_property "trigger_file" "/tmp/postgresql.trigger.${POSTGRESQL_MASTER_PORT_NUMBER}" "$POSTGRESQL_RECOVERY_FILE" + fi +} diff --git a/bitnami/postgresql/12/debian-10/rootfs/licenses/licenses.txt b/bitnami/postgresql/12/debian-10/rootfs/licenses/licenses.txt new file mode 100644 index 000000000000..c76ba31f3b8a --- /dev/null +++ b/bitnami/postgresql/12/debian-10/rootfs/licenses/licenses.txt @@ -0,0 +1,3 @@ +Bitnami containers ship with software bundles. You can find the licenses under: +/opt/bitnami/nami/COPYING +/opt/bitnami/[name-of-bundle]/licenses/[bundle-version].txt diff --git a/bitnami/postgresql/12/debian-10/rootfs/postunpack.sh b/bitnami/postgresql/12/debian-10/rootfs/postunpack.sh new file mode 100755 index 000000000000..9ac77d65d696 --- /dev/null +++ b/bitnami/postgresql/12/debian-10/rootfs/postunpack.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +# shellcheck disable=SC1091 + +# Load libraries +. /libfs.sh +. /libpostgresql.sh + +# Load PostgreSQL environment variables +eval "$(postgresql_env)" + +for dir in "$POSTGRESQL_INITSCRIPTS_DIR" "$POSTGRESQL_TMP_DIR" "$POSTGRESQL_LOG_DIR" "$POSTGRESQL_CONF_DIR" "${POSTGRESQL_CONF_DIR}/conf.d" "$POSTGRESQL_VOLUME_DIR"; do + ensure_dir_exists "$dir" +done +chmod -R g+rwX "$POSTGRESQL_INITSCRIPTS_DIR" "$POSTGRESQL_TMP_DIR" "$POSTGRESQL_LOG_DIR" "$POSTGRESQL_CONF_DIR" "${POSTGRESQL_CONF_DIR}/conf.d" "$POSTGRESQL_VOLUME_DIR" + +# Redirect all logging to stdout +ln -sf /dev/stdout "$POSTGRESQL_LOG_DIR/postgresql.log" diff --git a/bitnami/postgresql/12/debian-10/rootfs/run.sh b/bitnami/postgresql/12/debian-10/rootfs/run.sh new file mode 100755 index 000000000000..d78ee7fab884 --- /dev/null +++ b/bitnami/postgresql/12/debian-10/rootfs/run.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +set -o errexit +set -o nounset +set -o pipefail +# set -o xtrace # Uncomment this line for debugging purpose +# shellcheck disable=SC1091 + +# Load libraries +. /libpostgresql.sh +. /libos.sh + +# Load PostgreSQL environment variables +eval "$(postgresql_env)" +readonly flags=("-D" "$POSTGRESQL_DATA_DIR" "--config-file=$POSTGRESQL_CONF_FILE" "--external_pid_file=$POSTGRESQL_PID_FILE" "--hba_file=$POSTGRESQL_PGHBA_FILE") +readonly cmd=$(command -v postgres) + +info "** Starting PostgreSQL **" +if am_i_root; then + exec gosu "$POSTGRESQL_DAEMON_USER" "${cmd}" "${flags[@]}" +else + exec "${cmd}" "${flags[@]}" +fi diff --git a/bitnami/postgresql/12/debian-10/rootfs/setup.sh b/bitnami/postgresql/12/debian-10/rootfs/setup.sh new file mode 100755 index 000000000000..73dfe9c3c51e --- /dev/null +++ b/bitnami/postgresql/12/debian-10/rootfs/setup.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# +# Bitnami PostgreSQL setup + +# shellcheck disable=SC1090 +# shellcheck disable=SC1091 + +set -o errexit +set -o nounset +set -o pipefail + +# Load Generic Libraries +. /libfile.sh +. /liblog.sh +. /libservice.sh +. /libvalidations.sh +. /libfs.sh +. /libos.sh +. /libpostgresql.sh + +# Load PostgreSQL environment variables +eval "$(postgresql_env)" + +# Ensure PostgreSQL environment variables settings are valid +postgresql_validate +# Ensure PostgreSQL is stopped when this script ends. +trap "postgresql_stop" EXIT +# Ensure 'daemon' user exists when running as 'root' +am_i_root && ensure_user_exists "$POSTGRESQL_DAEMON_USER" "$POSTGRESQL_DAEMON_GROUP" +# Allow running custom pre-initialization scripts +postgresql_custom_pre_init_scripts +# Ensure PostgreSQL is initialized +postgresql_initialize +# Allow running custom initialization scripts +postgresql_custom_init_scripts + +# Allow remote connections once the initialization is finished +if ! postgresql_is_file_external "postgresql.conf"; then + info "Enabling remote connections" + postgresql_enable_remote_connections + postgresql_set_property "port" "$POSTGRESQL_PORT_NUMBER" +fi diff --git a/bitnami/postgresql/README.md b/bitnami/postgresql/README.md index ab075630da93..602757e7aa96 100644 --- a/bitnami/postgresql/README.md +++ b/bitnami/postgresql/README.md @@ -39,19 +39,19 @@ Non-root container images add an extra layer of security and are generally recom # Supported tags and respective `Dockerfile` links -> NOTE: Debian 8 images have been deprecated in favor of Debian 9 images. Bitnami will not longer publish new Docker images based on Debian 8. +> NOTE: Debian 9 images have been deprecated in favor of Debian 10 images. Bitnami will not longer publish new Docker images based on Debian 9. Learn more about the Bitnami tagging policy and the difference between rolling tags and immutable tags [in our documentation page](https://docs.bitnami.com/containers/how-to/understand-rolling-tags-containers/). * [`12-ol-7`, `12.1.0-ol-7-r77` (12/ol-7/Dockerfile)](https://github.com/bitnami/bitnami-docker-postgresql/blob/12.1.0-ol-7-r77/12/ol-7/Dockerfile) -* [`12-debian-9`, `12.1.0-debian-9-r58`, `12`, `12.1.0`, `12.1.0-r58` (12/debian-9/Dockerfile)](https://github.com/bitnami/bitnami-docker-postgresql/blob/12.1.0-debian-9-r58/12/debian-9/Dockerfile) +* [`12-debian-10`, `12.1.0-debian-10-r0`, `12`, `12.1.0`, `12.1.0-r0` (12/debian-10/Dockerfile)](https://github.com/bitnami/bitnami-docker-postgresql/blob/12.1.0-debian-10-r0/12/debian-10/Dockerfile) * [`11-ol-7`, `11.6.0-ol-7-r77` (11/ol-7/Dockerfile)](https://github.com/bitnami/bitnami-docker-postgresql/blob/11.6.0-ol-7-r77/11/ol-7/Dockerfile) -* [`11-debian-9`, `11.6.0-debian-9-r54`, `11`, `11.6.0`, `11.6.0-r54`, `latest` (11/debian-9/Dockerfile)](https://github.com/bitnami/bitnami-docker-postgresql/blob/11.6.0-debian-9-r54/11/debian-9/Dockerfile) * [`10-ol-7`, `10.11.0-ol-7-r76` (10/ol-7/Dockerfile)](https://github.com/bitnami/bitnami-docker-postgresql/blob/10.11.0-ol-7-r76/10/ol-7/Dockerfile) -* [`10-debian-9`, `10.11.0-debian-9-r59`, `10`, `10.11.0`, `10.11.0-r59` (10/debian-9/Dockerfile)](https://github.com/bitnami/bitnami-docker-postgresql/blob/10.11.0-debian-9-r59/10/debian-9/Dockerfile) * [`9.6-ol-7`, `9.6.16-ol-7-r71` (9.6/ol-7/Dockerfile)](https://github.com/bitnami/bitnami-docker-postgresql/blob/9.6.16-ol-7-r71/9.6/ol-7/Dockerfile) -* [`9.6-debian-9`, `9.6.16-debian-9-r57`, `9.6`, `9.6.16`, `9.6.16-r57` (9.6/debian-9/Dockerfile)](https://github.com/bitnami/bitnami-docker-postgresql/blob/9.6.16-debian-9-r57/9.6/debian-9/Dockerfile) +* [`11-debian-10`, `0.0.0-debian-10-r0`, `11`, `0.0.0`, `0.0.0-r0`, `latest` (11/debian-10/Dockerfile)](https://github.com/bitnami/bitnami-docker-postgresql/blob/0.0.0-debian-10-r0/11/debian-10/Dockerfile) +* [`9.6-debian-10`, `0.0.0-debian-10-r0`, `9.6`, `0.0.0`, `0.0.0-r0` (9.6/debian-10/Dockerfile)](https://github.com/bitnami/bitnami-docker-postgresql/blob/0.0.0-debian-10-r0/9.6/debian-10/Dockerfile) +* [`10-debian-10`, `0.0.0-debian-10-r0`, `10`, `0.0.0`, `0.0.0-r0` (10/debian-10/Dockerfile)](https://github.com/bitnami/bitnami-docker-postgresql/blob/0.0.0-debian-10-r0/10/debian-10/Dockerfile) Subscribe to project updates by watching the [bitnami/postgresql GitHub repo](https://github.com/bitnami/bitnami-docker-postgresql). @@ -73,7 +73,7 @@ $ docker pull bitnami/postgresql:[TAG] If you wish, you can also build the image yourself. ```bash -$ docker build -t bitnami/postgresql:latest 'https://github.com/bitnami/bitnami-docker-postgresql.git#master:11/debian-9' +$ docker build -t bitnami/postgresql:latest 'https://github.com/bitnami/bitnami-docker-postgresql.git#master:11/debian-10' ``` # Persisting your database diff --git a/bitnami/postgresql/circle.yml b/bitnami/postgresql/circle.yml index ab14affc3e32..c45f98665ef5 100644 --- a/bitnami/postgresql/circle.yml +++ b/bitnami/postgresql/circle.yml @@ -7,7 +7,7 @@ jobs: environment: RELEASE_SERIES_LIST: "10,11,12,9.6" LATEST_STABLE: "11" - DISTRIBUTIONS_LIST: "debian-9,ol-7" + DISTRIBUTIONS_LIST: "debian-10,ol-7" IMAGE_NAME: postgresql DOCKER_PROJECT: bitnami QUAY_PROJECT: bitnami