Skip to content

Commit

Permalink
Merge pull request #1159 from kgaillot/fixes
Browse files Browse the repository at this point in the history
New resource agent for node attributes, with other minor updates
  • Loading branch information
kgaillot committed Oct 18, 2016
2 parents 191d19b + 582e886 commit 722276c
Show file tree
Hide file tree
Showing 5 changed files with 248 additions and 16 deletions.
18 changes: 5 additions & 13 deletions GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,12 @@ RPM_OPTS = --define "_sourcedir $(RPM_ROOT)" \

MOCK_OPTIONS ?= --resultdir=$(RPM_ROOT)/mock --no-cleanup-after

# Default to fedora compliant spec files
# Default to building Fedora-compliant spec files
# SLES: /etc/SuSE-release
# openSUSE: /etc/SuSE-release
# RHEL: /etc/redhat-release
# RHEL: /etc/redhat-release, /etc/system-release
# Fedora: /etc/fedora-release, /etc/redhat-release, /etc/system-release
# CentOS: /etc/centos-release, /etc/redhat-release, /etc/system-release
F ?= $(shell test ! -e /etc/fedora-release && echo 0; test -e /etc/fedora-release && rpm --eval %{fedora})
ARCH ?= $(shell test -e /etc/fedora-release && rpm --eval %{_arch})
MOCK_CFG ?= $(shell test -e /etc/fedora-release && echo fedora-$(F)-$(ARCH))
Expand Down Expand Up @@ -150,24 +151,15 @@ $(PACKAGE)-suse.spec: $(PACKAGE).spec.in GNUmakefile
sed -i s:libexecdir}/lcrso:libdir}/lcrso:g $@
sed -i 's:%{name}-libs:lib%{name}3:g' $@
sed -i s:cluster-glue-libs:libglue:g $@
sed -i s:lm_sensors-devel:automake:g $@
sed -i s:bzip2-devel:libbz2-devel:g $@
sed -i s:bcond_without\ publican:bcond_with\ publican:g $@
sed -i s:docbook-style-xsl:docbook-xsl-stylesheets:g $@
sed -i s:libtool-ltdl-devel::g $@
sed -i s:publican::g $@
sed -i s:byacc::g $@
sed -i s:gnutls-devel:libgnutls-devel:g $@
sed -i s:189:90:g $@
sed -i 's@python-devel@python-devel python-curses python-xml@' $@
sed -i 's@Requires: python@Requires: python python-curses python-xml@' $@
sed -i 's@%systemd_post pacemaker.service@if [ ZZZ -eq 1 ]; then systemctl preset pacemaker.service || : ; fi@' $@
sed -i 's@%systemd_postun_with_restart pacemaker.service@systemctl daemon-reload || : ; if [ ZZZ -ge 1 ]; then systemctl try-restart pacemaker.service || : ; fi@' $@
sed -i 's@%systemd_preun pacemaker.service@if [ ZZZ -eq 0 ]; then systemctl --no-reload disable pacemaker.service || : ; systemctl stop pacemaker.service || : ; fi@' $@
sed -i 's@%systemd_post pacemaker_remote.service@if [ ZZZ -eq 1 ]; then systemctl preset pacemaker_remote.service || : ; fi@' $@
sed -i 's@%systemd_postun_with_restart pacemaker_remote.service@systemctl daemon-reload || : ; if [ ZZZ -ge 1 ]; then systemctl try-restart pacemaker_remote.service || : ; fi@' $@
sed -i 's@%systemd_preun pacemaker_remote.service@if [ ZZZ -eq 0 ]; then systemctl --no-reload disable pacemaker_remote.service || : ; systemctl stop pacemaker_remote.service || : ; fi@' $@
sed -i "s@ZZZ@\o0441@g" $@
sed -i 's:python-devel:python-curses python-xml python-devel:' $@
sed -i 's@Requires: python@Requires: python-curses python-xml python@' $@
@echo "Applied SUSE-specific modifications"


Expand Down
1 change: 1 addition & 0 deletions extra/resources/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ ocf_SCRIPTS = ClusterMon \
Stateful \
SysInfo \
SystemHealth \
attribute \
remote

isolationtech_SCRIPTS = docker-wrapper
Expand Down
233 changes: 233 additions & 0 deletions extra/resources/attribute
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
#!/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
10 changes: 8 additions & 2 deletions include/crm/crm.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@
# include <glib.h>
# include <stdbool.h>

# undef MIN
# undef MAX
# include <string.h>

# include <libxml/tree.h>
Expand Down Expand Up @@ -71,6 +69,14 @@ extern char *crm_system_name;
# define DOT_ALL_FSA_INPUTS 1
/* #define FSA_TRACE 1 */

/* This header defines INFINITY, but it might be defined elsewhere as well
* (e.g. math.h), so undefine it first. This, of course, complicates any attempt
* to use the other definition in any code that includes this header.
*
* @TODO: Rename our constant (which will break API backward compatibility).
*/
# undef INFINITY

# define INFINITY_S "INFINITY"
# define MINUS_INFINITY_S "-INFINITY"

Expand Down
2 changes: 1 addition & 1 deletion tools/crm_report.in
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ while true; do
-u|--user) ssh_user="$2"; shift; shift;;
-D|--max-depth) maxdepth="$2"; shift; shift;;
-M) search_logs=0; shift;;
--sos-mode) search_logs=0; extra_logs="/var/log/pacemaker.log /var/log/cluster/corosync.log"; nodes="$host"; shift;;
--sos-mode) search_logs=0; nodes="$host"; shift;;
--dest) DESTDIR=$2; shift; shift;;
--) if [ ! -z $2 ]; then DESTDIR=$2; fi; break;;
-h|--help) usage; exit 0;;
Expand Down

0 comments on commit 722276c

Please sign in to comment.