Add PostgreSQL promotion database gate

This commit is contained in:
Lyncoln
2026-09-18 02:46:40 -04:00
parent 4229008216
commit 798aa40ae5
7 changed files with 160 additions and 11 deletions
@@ -14,6 +14,7 @@ OCF_RESKEY_application_name_default=""
OCF_RESKEY_rejoin_allow_basebackup_default="false"
OCF_RESKEY_rejoin_basebackup_headroom_percent_default="50"
OCF_RESKEY_demote_database_gate_default="false"
OCF_RESKEY_promote_database_gate_default="false"
: "${OCF_RESKEY_service_user:=${OCF_RESKEY_service_user_default}}"
: "${OCF_RESKEY_service_name:=${OCF_RESKEY_service_name_default}}"
@@ -29,6 +30,7 @@ OCF_RESKEY_demote_database_gate_default="false"
: "${OCF_RESKEY_rejoin_allow_basebackup:=${OCF_RESKEY_rejoin_allow_basebackup_default}}"
: "${OCF_RESKEY_rejoin_basebackup_headroom_percent:=${OCF_RESKEY_rejoin_basebackup_headroom_percent_default}}"
: "${OCF_RESKEY_demote_database_gate:=${OCF_RESKEY_demote_database_gate_default}}"
: "${OCF_RESKEY_promote_database_gate:=${OCF_RESKEY_promote_database_gate_default}}"
SERVICE_USER="${OCF_RESKEY_service_user}"
SERVICE_NAME="${OCF_RESKEY_service_name}"
@@ -44,7 +46,9 @@ APPLICATION_NAME="${OCF_RESKEY_application_name}"
REJOIN_ALLOW_BASEBACKUP="${OCF_RESKEY_rejoin_allow_basebackup}"
REJOIN_BASEBACKUP_HEADROOM_PERCENT="${OCF_RESKEY_rejoin_basebackup_headroom_percent}"
DEMOTE_DATABASE_GATE="${OCF_RESKEY_demote_database_gate}"
PROMOTE_DATABASE_GATE="${OCF_RESKEY_promote_database_gate}"
export MC_DEMOTE_DATABASE_GATE="${DEMOTE_DATABASE_GATE}"
export MC_PROMOTE_DATABASE_GATE="${PROMOTE_DATABASE_GATE}"
# Resolve PostgreSQL configuration from the managed service when Pacemaker has
# not explicitly supplied it. The application configuration remains the source
@@ -303,6 +307,15 @@ validate_all()
;;
esac
case "${PROMOTE_DATABASE_GATE}" in
true|false)
;;
*)
ocf_exit_reason "promote_database_gate must be true or false"
return "${OCF_ERR_CONFIGURED}"
;;
esac
case "${REJOIN_BASEBACKUP_HEADROOM_PERCENT}" in
""|*[!0-9]*)
ocf_exit_reason "rejoin_basebackup_headroom_percent must be a non-negative integer"
@@ -352,6 +365,11 @@ mc_promotion_metadata()
<shortdesc lang="en">Gate demotion on database checks</shortdesc>\
<content type="boolean" default="false"/>\
</parameter>\
<parameter name="promote_database_gate" unique="0" required="0">\
<longdesc lang="en">When true, reject native PostgreSQL promotion unless the managed-containerd promote.database preflight agrees that this node is the notified promotion target, is an eligible standby, and no reachable writable peer exists. When false, the daemon check remains shadow-only and native promotion fails open.</longdesc>\
<shortdesc lang="en">Gate promotion on database checks</shortdesc>\
<content type="boolean" default="false"/>\
</parameter>\
<parameter name="replication_peers" unique="0" required="0">\
<longdesc lang="en">Opt-in stable peer map: node=host:port,node=host:port. Include the local node; exclude the client VIP. IPv4 or DNS hosts only. Requires a configured per-node replication slot, supplied explicitly or resolved from PostgreSQL/the managed container environment, plus peer authentication and slots on every upstream. Uses native primary-only selection; demotion verifies final WAL then ready recovery before successor promotion.</longdesc>\
<shortdesc lang="en">Native replication peer map</shortdesc>\
@@ -29,6 +29,11 @@ mc_pg_promote_database_shadow()
if [ "${rc}" -ne 0 ]; then
ocf_log warn \
"managed-containerd promote.database shadow unavailable rc=${rc}"
if [ "${MC_PROMOTE_DATABASE_GATE:-false}" = true ]; then
return 1
fi
return 0
fi
@@ -50,10 +55,12 @@ if (
else
ocf_log err \
"managed-containerd promote.database shadow MISMATCH response=${response}"
if [ "${MC_PROMOTE_DATABASE_GATE:-false}" = true ]; then
return 1
fi
fi
# Shadow-only milestone: daemon disagreement must not alter the
# authoritative native promotion result yet.
return 0
}
@@ -117,9 +124,13 @@ managed_promote()
"Promoting PostgreSQL standby inside ${CONTAINER_NAME}"
# Independent managed-containerd promotion preflight.
# Shadow-only for now: disagreement is logged but does not block
# the authoritative native PostgreSQL promotion.
mc_pg_promote_database_shadow
# Shadow-only by default; when promote_database_gate=true,
# daemon disagreement or transport failure denies native promotion.
if ! mc_pg_promote_database_shadow; then
ocf_exit_reason \
"Promotion database gate rejected native PostgreSQL promotion"
return "${OCF_ERR_GENERIC}"
fi
if ! pg_command '
BINDIR="$(pg_config --bindir)" || exit 1