{{- /* Copyright Broadcom, Inc. All Rights Reserved. SPDX-License-Identifier: APACHE-2.0 */}} apiVersion: v1 kind: ConfigMap metadata: name: {{ printf "%s-scripts" (include "postgresql-ha.postgresql" .) }} namespace: {{ include "common.names.namespace" . | quote }} labels: {{- include "common.labels.standard" (dict "customLabels" .Values.commonLabels "context" .) | nindent 4 }} app.kubernetes.io/component: postgresql {{- if .Values.commonAnnotations }} annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" .) | nindent 4 }} {{- end }} data: pre-stop.sh: |- #!/bin/bash set -o errexit set -o pipefail set -o nounset # Debug section exec 3>&1 exec 4>&2 # Process input parameters MIN_DELAY_AFTER_PG_STOP_SECONDS=$1 # Load Libraries . /opt/bitnami/scripts/libpostgresql.sh . /opt/bitnami/scripts/librepmgr.sh # Load PostgreSQL & repmgr environment variables . /opt/bitnami/scripts/postgresql-env.sh # Auxiliary functions is_new_primary_ready() { local -a current_primary_node readarray -t current_primary_node < <(repmgr_get_primary_node) local current_primary_host="${current_primary_node[0]}" if [[ -n "$current_primary_host" ]] && [[ "$current_primary_host" != "$REPMGR_NODE_NETWORK_NAME" ]]; then info "New primary detected, leaving the cluster..." return 0 fi info "Waiting for a new primary to be available..." return 1 } export MODULE="pre-stop-hook" if ! is_boolean_yes "$BITNAMI_DEBUG"; then exec 1>/dev/null exec 2>/dev/null fi postgresql_enable_nss_wrapper # Prepare env vars for managing roles readarray -t primary_node < <(repmgr_get_upstream_node) primary_host="${primary_node[0]}" # Stop postgresql for graceful exit. PG_STOP_INIT=$EPOCHSECONDS postgresql_stop if [[ -z "$primary_host" ]] || [[ "$primary_host" = "$REPMGR_NODE_NETWORK_NAME" ]]; then info "Primary node need to wait for a new primary node before leaving the cluster" retry_while is_new_primary_ready 10 5 else info "Standby node doesn't need to wait for a new primary switchover. Leaving the cluster" fi # Make sure pre-stop hook waits at least 25 seconds after stop of PG to make sure Pgpool-II detects node is down. # default terminationGracePeriodSeconds=30 seconds PG_STOP_DURATION=$((EPOCHSECONDS - PG_STOP_INIT)) if (( PG_STOP_DURATION < MIN_DELAY_AFTER_PG_STOP_SECONDS )); then WAIT_TO_PG_POOL_TIME=$((MIN_DELAY_AFTER_PG_STOP_SECONDS - PG_STOP_DURATION)) info "Waiting additional $WAIT_TO_PG_POOL_TIME seconds for Pgpool-II to detect node is down" sleep $WAIT_TO_PG_POOL_TIME fi liveness-probe.sh: |- #!/bin/bash set -o errexit set -o pipefail set -o nounset # Load Libraries . /opt/bitnami/scripts/libpostgresql.sh . /opt/bitnami/scripts/librepmgr.sh # Load PostgreSQL & repmgr environment variables . /opt/bitnami/scripts/postgresql-env.sh # Check if PG is ready pg_isready_args=("-U" "postgres" "-p" "$POSTGRESQL_PORT_NUMBER" "-h" "127.0.0.1") is_boolean_yes "$POSTGRESQL_ENABLE_TLS" && pg_isready_args+=("-d" "sslcert=$POSTGRESQL_TLS_CERT_FILE sslkey=$POSTGRESQL_TLS_KEY_FILE") debug_execute pg_isready "${pg_isready_args[@]}" # Check if repmgr has split-brain issues postgresql_enable_nss_wrapper repmgr_check_status readiness-probe.sh: |- #!/bin/bash set -o errexit set -o pipefail set -o nounset # Load Libraries . /opt/bitnami/scripts/libpostgresql.sh . /opt/bitnami/scripts/librepmgr.sh # Load PostgreSQL & repmgr environment variables . /opt/bitnami/scripts/postgresql-env.sh # We should not proceed if a standby clone is in progress if ps waux | grep "data standby clone" | grep -qv grep; then echo "standby clone in progress" exit 1 fi # Then, let's check if PG is responding to queries {{- if .Values.postgresql.headlessWithNotReadyAddresses }} MIN_DELAY_AFTER_POD_READY_FIRST_TIME={{ add .Values.pgpool.livenessProbe.periodSeconds .Values.pgpool.livenessProbe.timeoutSeconds }} FIRST_READY_TS_FILE="/tmp/.first-ready.epoch" DELAY_SEMAPHORE="/tmp/.delay" {{- end }} if [[ $(PGPASSWORD="$POSTGRESQL_PASSWORD" psql -w -U "$POSTGRESQL_USERNAME" -d $POSTGRESQL_DATABASE -h 127.0.0.1 -p "$POSTGRESQL_PORT_NUMBER" -tA -c "SELECT 1" 2> /dev/null || true) = 1 ]]; then {{- if .Values.postgresql.headlessWithNotReadyAddresses }} # DB up, but initial readiness delay not applied if [[ ! -f "$DELAY_SEMAPHORE" ]] && [[ -f "$FIRST_READY_TS_FILE" ]]; then # calculate delay from the first readiness success FIRST_READY_TS=$(cat $FIRST_READY_TS_FILE) CURRENT_DELAY_SECONDS=$((EPOCHSECONDS - FIRST_READY_TS)) # Wait for the minimal delay after the first readiness state if (( CURRENT_DELAY_SECONDS > MIN_DELAY_AFTER_POD_READY_FIRST_TIME )); then # mark delay as applied touch "$DELAY_APPLIED_FILE" else echo "minimal delay not met" exit 1 fi # first ever readiness test success - store timestamp and report failure elif [[ ! -f "$DELAY_SEMAPHORE" ]]; then echo $EPOCHSECONDS > $FIRST_READY_TS_FILE exit 1 fi {{- end }} # Finally, check if repmgr has split-brain issues postgresql_enable_nss_wrapper repmgr_check_status else echo "connection to database failed" exit 1 fi