diff --git a/extra/resources/attribute b/extra/resources/attribute index 7444ec607e..80679d1d96 100755 --- a/extra/resources/attribute +++ b/extra/resources/attribute @@ -1,233 +1,233 @@ #!/bin/sh # # ocf:pacemaker:attribute resource agent # -# Copyright (C) 2016 Andrew Beekhof +# Copyright 2016-2018 Andrew Beekhof # # 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 < 1.0 Manages a node attribute 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. Full path of a temporary file to store the resource state in State file Name of node attribute to manage Attribute name Value to use for node attribute when resource becomes active (empty string is discouraged, because monitor cannot distinguish it from a query error) Attribute value when active Value to use for node attribute when resource becomes inactive Attribute value when inactive 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 + if [ ! -w "$VALIDATE_DIR" ] || [ ! -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 + if [ "$CHECK_VALUE" != "" ] && [ "$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