#!/bin/sh # # ocf:pacemaker:Stateful resource agent # # Copyright 2006-2023 the Pacemaker project contributors # # The version control history for this file may have further details. # # This source code is licensed under the GNU General Public License version 2 # or later (GPLv2+) WITHOUT ANY WARRANTY. # # # Example of a stateful OCF Resource Agent # ####################################################################### # Initialization: : ${OCF_FUNCTIONS:="${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs"} . "${OCF_FUNCTIONS}" : ${__OCF_ACTION:="$1"} # Explicitly list all environment variables used, to make static analysis happy : ${OCF_RESKEY_CRM_meta_interval:=0} : ${OCF_RESKEY_CRM_meta_globally_unique:="false"} : ${OCF_RESKEY_notify_delay:=0} : ${OCF_RESKEY_envfile:=""} : ${OCF_RESKEY_state:=""} # Until we can assume the new name is available ... : ${OCF_RUNNING_PROMOTED:=$OCF_RUNNING_MASTER} SCORE_UNPROMOTED=5 SCORE_PROMOTED=10 ####################################################################### meta_data() { cat < 1.1 This is an example resource agent that implements Promoted and Unpromoted roles Example stateful resource agent Location to store the resource state in State file If this is set, the environment will be dumped to this file for every call. Environment dump file The notify action will sleep for this many seconds before returning, to simulate a long-running notify. Notify delay in seconds END exit $OCF_SUCCESS } ####################################################################### stateful_usage() { cat < where is one of: meta-data validate-all start stop monitor promote demote notify reload-agent This conforms to the OCF Resource Agent API version 1.1, and expects to have OCF-compliant environment variables provided. END exit $1 } stateful_update() { echo $1 > "${OCF_RESKEY_state}" } stateful_check_state() { target="$1" if [ -f "${OCF_RESKEY_state}" ]; then state=$(cat "${OCF_RESKEY_state}") if [ "$target" = "$state" ]; then return 0 fi else if [ -z "$target" ]; then return 0 fi fi return 1 } dump_env() { if [ "${OCF_RESKEY_envfile}" != "" ]; then echo "### ${__OCF_ACTION} @ $(date) ### $(env | sort) ###" >> "${OCF_RESKEY_envfile}" fi } set_promotion_score() { "${HA_SBIN_DIR}/crm_attribute" --promotion -v "$1" } stateful_start() { stateful_check_state Promoted if [ $? -eq 0 ]; then # CRM Error - Should never happen return $OCF_RUNNING_PROMOTED fi stateful_update Unpromoted set_promotion_score $SCORE_UNPROMOTED return 0 } stateful_demote() { stateful_check_state if [ $? -eq 0 ]; then # CRM Error - Should never happen return $OCF_NOT_RUNNING fi stateful_update Unpromoted set_promotion_score $SCORE_UNPROMOTED return 0 } stateful_promote() { stateful_check_state if [ $? -eq 0 ]; then return $OCF_NOT_RUNNING fi stateful_update Promoted set_promotion_score $SCORE_PROMOTED return 0 } stateful_stop() { "${HA_SBIN_DIR}/crm_attribute" --promotion -D stateful_check_state Promoted if [ $? -eq 0 ]; then # CRM Error - Should never happen return $OCF_RUNNING_PROMOTED fi if [ -f "${OCF_RESKEY_state}" ]; then rm "${OCF_RESKEY_state}" fi return 0 } stateful_monitor() { # for testing if [ -f "${OCF_RESKEY_state}.rc" ]; then rc=$(cat "${OCF_RESKEY_state}.rc") ocf_exit_reason "$rc GB redirected to /dev/null" exit $rc fi stateful_check_state Promoted if [ $? -eq 0 ]; then if [ $OCF_RESKEY_CRM_meta_interval -eq 0 ]; then # Restore the promotion score during probes set_promotion_score $SCORE_PROMOTED fi return $OCF_RUNNING_PROMOTED fi stateful_check_state Unpromoted if [ $? -eq 0 ]; then if [ $OCF_RESKEY_CRM_meta_interval -eq 0 ]; then # Restore the promotion score during probes set_promotion_score $SCORE_UNPROMOTED fi return $OCF_SUCCESS fi if [ -f "${OCF_RESKEY_state}" ]; then echo "File '${OCF_RESKEY_state}' exists but contains unexpected contents" cat "${OCF_RESKEY_state}" return $OCF_ERR_GENERIC fi return 7 } stateful_notify() { if [ "${OCF_RESKEY_notify_delay}" != "0" ]; then sleep "${OCF_RESKEY_notify_delay}" fi return $OCF_SUCCESS } stateful_validate() { exit $OCF_SUCCESS } stateful_reload_agent() { return $OCF_SUCCESS } if [ -z "$OCF_RESKEY_state" ]; then if [ "${OCF_RESKEY_CRM_meta_globally_unique}" = "false" ]; then state="${HA_VARRUN%%/}/Stateful-${OCF_RESOURCE_INSTANCE}.state" # Strip off the trailing clone marker OCF_RESKEY_state=$(echo $state | sed s/:[0-9][0-9]*\.state/.state/) else OCF_RESKEY_state="${HA_VARRUN%%/}/Stateful-${OCF_RESOURCE_INSTANCE}.state" fi fi dump_env case "$__OCF_ACTION" in meta-data) meta_data;; start) stateful_start;; promote) stateful_promote;; demote) stateful_demote;; notify) stateful_notify ;; stop) stateful_stop;; monitor) stateful_monitor;; validate-all) stateful_validate;; reload-agent) stateful_reload_agent;; usage|help) stateful_usage $OCF_SUCCESS;; *) stateful_usage $OCF_ERR_UNIMPLEMENTED;; esac exit $? # vim: set filetype=sh expandtab tabstop=4 softtabstop=4 shiftwidth=4 textwidth=80: