Files
managed-container/ocf/loxthelion/managed-container.d/applications/postgresql/peer_config.sh
T

55 lines
2.5 KiB
Bash

# POSIX-compatible shared normalizer. Also mounted beside the bootstrap script.
# Inputs are data, never evaluated shell. IPv4/DNS endpoints only in API 1.
mc_peer_endpoints()
{
LC_ALL=C awk -v peers="$1" -v self="$2" -v select_node="${3:-}" '
BEGIN {
n=split(peers, entries, ","); self=tolower(self); select_node=tolower(select_node);
if(n<2 || n>32 || self=="") exit 1;
for(i=1;i<=n;i++) {
if(split(entries[i],pair,"=")!=2 || pair[1]!~/^[A-Za-z0-9_][A-Za-z0-9_.-]*$/) exit 1;
node=tolower(pair[1]); if(seen[node]++) exit 1;
if(split(pair[2],addr,":")!=2 || addr[1]!~/^[A-Za-z0-9][A-Za-z0-9.-]*$/ || addr[2]!~/^[0-9]+$/ || addr[2]+0<1 || addr[2]+0>65535) exit 1;
endpoint=tolower(addr[1]) ":" (addr[2]+0); if(addresses[endpoint]++) exit 1;
if(node==self) { own++; continue; }
if(select_node!="" && node!=select_node) continue;
hosts=hosts (count?",":"") addr[1]; ports=ports (count?",":"") (addr[2]+0); count++;
}
if(own!=1 || count<1 || (select_node!="" && count!=1)) exit 1;
print hosts "|" ports;
}'
}
mc_peer_conninfo()
{
# peers, self, replication user, application name
case "$3" in ''|*[!a-zA-Z0-9_.-]*) return 1;; esac
case "$4" in ''|*[!a-zA-Z0-9_.-]*) return 1;; esac
mc_peer_pair=$(mc_peer_endpoints "$1" "$2") || return 1
printf 'host=%s port=%s user=%s application_name=%s target_session_attrs=primary connect_timeout=2\n' \
"${mc_peer_pair%|*}" "${mc_peer_pair#*|}" "$3" "$4"
}
mc_peer_write_recovery()
(
# PGDATA, peers, self, user, application, slot. No credentials in output.
set -eu
data=$1
conn=$(mc_peer_conninfo "$2" "$3" "$4" "$5") || exit 1
case "$6" in ''|*[!a-z0-9_]*) exit 1;; esac
[ ${#6} -le 63 ] || exit 1
[ -d "$data" ] && [ -f "$data/postgresql.auto.conf" ] && [ ! -L "$data/postgresql.auto.conf" ] || exit 1
[ ! -L "$data/standby.signal" ] || exit 1
umask 077
tmp=$(mktemp "$data/.peer-recovery.XXXXXXXX")
trap 'rm -f "$tmp"' EXIT HUP INT TERM
sed -e '/^[[:space:]]*primary_conninfo[[:space:]]*=/d' \
-e '/^[[:space:]]*primary_slot_name[[:space:]]*=/d' "$data/postgresql.auto.conf" > "$tmp"
printf "primary_conninfo = '%s'\nprimary_slot_name = '%s'\n" "$conn" "$6" >> "$tmp"
chmod 600 "$tmp"
mv -f "$tmp" "$data/postgresql.auto.conf"
[ ! -L "$data/standby.signal" ] || exit 1
touch "$data/standby.signal"
chmod 600 "$data/standby.signal"
)