Page MenuHomeClusterLabs Projects

attribute
No OneTemporary

attribute

#!/bin/sh
#
# ocf:pacemaker:attribute resource agent
#
# Copyright (C) 2016 Andrew Beekhof <andrew@beekhof.net>
#
# This source code is licensed under GNU General Public License version 2 or
# later (GPLv2+) WITHOUT ANY WARRANTY.
#
USAGE="Usage: $0 {start|stop|monitor|migrate_to|migrate_from|validate-all|meta-data}
Expects to have a fully populated OCF RA-compliant environment set."
# Load OCF helper functions
: ${OCF_FUNCTIONS=${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs}
. ${OCF_FUNCTIONS}
: ${__OCF_ACTION=$1}
# Ensure certain variables are set and not empty
: ${HA_VARRUN:="/var/run"}
: ${OCF_RESKEY_CRM_meta_globally_unique:="false"}
: ${OCF_RESOURCE_INSTANCE:="undef"}
DEFAULT_STATE_FILE="${HA_VARRUN%%/}/opa-${OCF_RESOURCE_INSTANCE}.state"
if [ ${OCF_RESKEY_CRM_meta_globally_unique} = "false" ]; then
# Strip off any trailing clone marker (note + is not portable in sed)
DEFAULT_STATE_FILE=$(echo "$DEFAULT_STATE_FILE" | sed s/:[0-9][0-9]*\.state/.state/)
fi
DEFAULT_ATTR_NAME="opa-${OCF_RESOURCE_INSTANCE}"
DEFAULT_ACTIVE_VALUE="1"
DEFAULT_INACTIVE_VALUE="0"
: ${OCF_RESKEY_state:="$DEFAULT_STATE_FILE"}
: ${OCF_RESKEY_name:="$DEFAULT_ATTR_NAME"}
# Values may be empty string
if [ -z ${OCF_RESKEY_active_value+x} ]; then
OCF_RESKEY_active_value="$DEFAULT_ACTIVE_VALUE"
fi
if [ -z ${OCF_RESKEY_inactive_value+x} ]; then
OCF_RESKEY_inactive_value="$DEFAULT_INACTIVE_VALUE"
fi
usage() {
USAGE_RC=$1
cat <<END
$USAGE
END
return $USAGE_RC
}
meta_data() {
cat <<END
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="attribute" version="1.0">
<version>1.0</version>
<shortdesc lang="en">Manages a node attribute</shortdesc>
<longdesc lang="en">
This resource agent controls a node attribute for the node it's running on.
It sets the attribute one way when started, and another way when stopped,
according to the configuration parameters.
</longdesc>
<parameters>
<parameter name="state" unique="1">
<longdesc lang="en">
Full path of a temporary file to store the resource state in
</longdesc>
<shortdesc lang="en">State file</shortdesc>
<content type="string" default="${DEFAULT_STATE_FILE}" />
</parameter>
<parameter name="name" unique="1">
<longdesc lang="en">
Name of node attribute to manage
</longdesc>
<shortdesc lang="en">Attribute name</shortdesc>
<content type="string" default="${DEFAULT_ATTR_NAME}" />
</parameter>
<parameter name="active_value" unique="0">
<longdesc lang="en">
Value to use for node attribute when resource becomes active (empty string is
discouraged, because monitor cannot distinguish it from a query error)
</longdesc>
<shortdesc lang="en">Attribute value when active</shortdesc>
<content type="string" default="$DEFAULT_ACTIVE_VALUE" />
</parameter>
<parameter name="inactive_value" unique="0">
<longdesc lang="en">
Value to use for node attribute when resource becomes inactive
</longdesc>
<shortdesc lang="en">Attribute value when inactive</shortdesc>
<content type="string" default="$DEFAULT_INACTIVE_VALUE" />
</parameter>
</parameters>
<actions>
<action name="start" timeout="20" />
<action name="stop" timeout="20" />
<action name="monitor" timeout="20" interval="10" depth="0"/>
<action name="reload" timeout="20" />
<action name="migrate_to" timeout="20" />
<action name="migrate_from" timeout="20" />
<action name="validate-all" timeout="20" />
<action name="meta-data" timeout="5" />
</actions>
</resource-agent>
END
return $OCF_SUCCESS
}
validate() {
if [ "$OCF_RESKEY_active_value" = "$OCF_RESKEY_inactive_value" ]; then
ocf_exit_reason "active value '%s' must be different from inactive value '%s'" \
"$OCF_RESKEY_active_value" "$OCF_RESKEY_inactive_value"
return $OCF_ERR_CONFIGURED
fi
VALIDATE_DIR=$(dirname "${OCF_RESKEY_state}")
if [ ! -d "$VALIDATE_DIR" ]; then
ocf_exit_reason "state file '$OCF_RESKEY_state' does not have a valid directory"
return $OCF_ERR_PERM
fi
if [ ! -w "$VALIDATE_DIR" -o ! -x "$VALIDATE_DIR" ]; then
ocf_exit_reason "insufficient privileges on directory of state file '$OCF_RESKEY_state'"
return $OCF_ERR_PERM
fi
return $OCF_SUCCESS
}
get_attribute() {
GET_LINE=$(attrd_updater -n "$OCF_RESKEY_name" -Q 2>/dev/null)
if [ $? -ne 0 ]; then
echo ""
else
echo "$GET_LINE" | sed -e "s/.* value=\"\(.*\)\"$/\1/"
fi
}
set_attribute() {
attrd_updater -n "$OCF_RESKEY_name" -U "$1" 2>/dev/null
# TODO if above call is async, loop until get_attribute returns expected value
}
check_attribute() {
CHECK_VALUE=$(get_attribute)
CHECK_REASON=""
if [ ! -f "$OCF_RESKEY_state" ]; then
if [ "$CHECK_VALUE" != "" -a "$CHECK_VALUE" != "$OCF_RESKEY_inactive_value" ]; then
CHECK_REASON="Node attribute $OCF_RESKEY_name='$CHECK_VALUE' differs from expected value '$OCF_RESKEY_inactive_value'"
return $OCF_ERR_GENERIC
fi
return $OCF_NOT_RUNNING
fi
if [ "$CHECK_VALUE" != "$OCF_RESKEY_active_value" ]; then
CHECK_REASON="Node attribute $OCF_RESKEY_name='$CHECK_VALUE' differs from expected value '$OCF_RESKEY_active_value'"
return $OCF_ERR_GENERIC
fi
return $OCF_SUCCESS
}
monitor() {
check_attribute
MONITOR_RC=$?
if [ $MONITOR_RC -eq $OCF_ERR_GENERIC ]; then
ocf_exit_reason "$CHECK_REASON"
fi
return $MONITOR_RC
}
start() {
check_attribute
if [ $? -eq $OCF_SUCCESS ]; then
return $OCF_SUCCESS
fi
touch "${OCF_RESKEY_state}" 2>/dev/null
if [ $? -ne 0 ]; then
ocf_exit_reason "Unable to manage state file $OCF_RESKEY_state"
return $OCF_ERR_GENERIC
fi
set_attribute "${OCF_RESKEY_active_value}"
if [ $? -ne 0 ]; then
rm -f "${OCF_RESKEY_state}"
ocf_exit_reason "Unable to set node attribute $OCF_RESKEY_name='$OCF_RESKEY_active_value'"
return $OCF_ERR_GENERIC
fi
return $OCF_SUCCESS
}
stop() {
check_attribute
if [ $? -eq $OCF_NOT_RUNNING ]; then
return $OCF_SUCCESS
fi
rm -f ${OCF_RESKEY_state}
set_attribute "${OCF_RESKEY_inactive_value}"
if [ $? -ne 0 ]; then
ocf_exit_reason "Unable to set node attribute $OCF_RESKEY_name='$OCF_RESKEY_inactive_value'"
return $OCF_ERR_GENERIC
fi
return $OCF_SUCCESS
}
case $__OCF_ACTION in
meta-data) meta_data ;;
start) start ;;
stop) stop ;;
monitor) monitor ;;
# We don't do anything special for live migration, but we support it so that
# other resources that live migrate can depend on this one.
migrate_to) stop ;;
migrate_from) start ;;
reload) start ;;
validate-all) validate ;;
usage|help) usage $OCF_SUCCESS ;;
*) usage $OCF_ERR_UNIMPLEMENTED ;;
esac
exit $?
# vim: expandtab:tabstop=4:softtabstop=4:shiftwidth=4:textwidth=80

File Metadata

Mime Type
text/x-shellscript
Expires
Tue, Oct 29, 8:51 PM (1 d, 14 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
934293
Default Alt Text
attribute (6 KB)

Event Timeline