# Shared OCF scoring wrappers; application policy is supplied by the plugin. # Promotion scores are scoped by Pacemaker to OCF_RESOURCE_INSTANCE and the # executing node. Do not construct a legacy attribute name or cache locally: # querying attrd on every observation also repairs a lost transient attribute. mc_promotion_score_set() { local score="$1" current local resource="${MC_PROMOTION_RESOURCE_INSTANCE:-}" if [ -z "${resource}" ]; then ocf_log warn "Cannot publish promotion score without OCF_RESOURCE_INSTANCE" return 1 fi case "${score}" in 1000|100|50|-INFINITY) ;; *) return 1 ;; esac current="$( timeout --kill-after=1s 2s crm_attribute \ --promotion="${resource}" --lifetime=reboot \ --query --quiet 2>/dev/null )" || current="" [ "${current}" = "${score}" ] && return 0 if ! timeout --kill-after=1s 2s crm_attribute \ --promotion="${resource}" --lifetime=reboot \ --update="${score}" >/dev/null 2>&1 then ocf_log err "Unable to publish promotion score ${score} for ${resource}; prior score may remain" return 1 fi return 0 } mc_promotion_score_from_monitor() { local monitor_rc="$1" score=-INFINITY case "${monitor_rc}" in "${OCF_RUNNING_PROMOTED}") score=1000 ;; "${OCF_SUCCESS}") score="$(mc_application_standby_score)" || score=-INFINITY ;; esac case "${score}" in 1000|100|50|-INFINITY) ;; *) score=-INFINITY ;; esac mc_promotion_score_set "${score}" } # managed-containerd is authoritative for recurring monitor/status results. # The packaged application monitor is used only when managed-containerd # explicitly delegates monitoring to the container backend. Promotion scoring # remains supplied by the existing application scoring hook. mc_promotion_monitor() { local monitor_rc proxy_result proxy_rc cached_rc proxy_result="$(mc_proxy_monitor)" proxy_rc=$? if [ "${proxy_rc}" -ne 0 ]; then case "${proxy_rc}" in "${MC_PROXY_RC_TRANSPORT}") # Transport loss is a control-plane failure, not proof that # the managed application itself has failed. cached_rc="$(mc_proxy_cached_monitor 2>/dev/null)" || cached_rc="" if [ -n "${cached_rc}" ]; then monitor_rc="${cached_rc}" case "${monitor_rc}" in "${OCF_SUCCESS}") # A standby with an unavailable control plane must # never remain promotion-eligible during grace. mc_promotion_score_set -INFINITY || true ;; "${OCF_RUNNING_PROMOTED}") # Preserve the established primary during a brief # bounded transport outage. ;; esac ocf_log warn \ "managed-containerd unavailable; using recent cached authoritative rc=${monitor_rc} for bounded control-plane grace" return "${monitor_rc}" fi mc_promotion_score_set -INFINITY || true ocf_exit_reason \ "managed-containerd authoritative monitor transport failure and no valid control-plane grace observation exists" return "${OCF_ERR_GENERIC}" ;; *) # Protocol/result/configuration/client failures are hard. # Never conceal them behind cached authoritative health. mc_proxy_monitor_cache_clear || true mc_promotion_score_set -INFINITY || true ocf_exit_reason \ "managed-containerd authoritative monitor hard failure; cached grace is not permitted" return "${OCF_ERR_GENERIC}" ;; esac fi # A successful managed-containerd response may explicitly delegate # monitoring to the RA's already-loaded packaged container/runtime path. # # The daemon remains authoritative for backend selection: this path is # reachable only after managed-containerd successfully requested it. case "${proxy_result}" in delegate\|*) local delegate_tag delegate_backend delegate_runtime delegate_extra local configured_runtime IFS='|' read -r delegate_tag delegate_backend delegate_runtime delegate_extra </dev/null 2>&1; then ocf_exit_reason "Required promotion scoring command '${utility}' is not installed" return "${OCF_ERR_INSTALLED}" fi done mc_application_validate }