Permalink
Browse files

Plugin for running Bird route damon

This agnet supports running Bird route daemon with master-slave
architecture for managing IP failover using static routes
  • Loading branch information...
1 parent 6f7b7b9 commit 52241bc8257a5c03d5537e67765c3f39868ebb18 @rafaltrojniak committed Oct 30, 2012
Showing with 298 additions and 0 deletions.
  1. +1 −0 doc/man/Makefile.am
  2. +296 −0 heartbeat/Bird
  3. +1 −0 heartbeat/Makefile.am
View
1 doc/man/Makefile.am
@@ -57,6 +57,7 @@ metadata-IPv6addr.xml: ../../heartbeat/IPv6addr
if BUILD_DOC
man_MANS = ocf_heartbeat_AoEtarget.7 \
ocf_heartbeat_AudibleAlarm.7 \
+ ocf_heartbeat_Bird.7 \
ocf_heartbeat_ClusterMon.7 \
ocf_heartbeat_CTDB.7 \
ocf_heartbeat_Delay.7 \
View
296 heartbeat/Bird
@@ -0,0 +1,296 @@
+#!/bin/sh
+#
+# OCF Resource Agent compliant resource script.
+#
+# Copyright (c) 2009 IN-telegence GmbH & Co. KG, Dominik Klein
@fghaas
fghaas Nov 6, 2012

Cut and paste error? Please update with a correct copyright notice.

+# All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+
+# History :
+# - Forked from anything plugin to Bird plugin
+#
+# Authors :
+# Rafał Trójniak resource-agents@trojniak.net
+# OCF instance parameters
+#
+
+# Initialization:
+: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/resource.d/heartbeat}
+. ${OCF_FUNCTIONS_DIR}/.ocf-shellfuncs
+
+bird_ping() {
+ birdc "show protocols" >/dev/null
+}
+
+bird_static_configured() {
+ ! birdc "show protocols" |
+ awk "\$1==\"$OCF_RESKEY_name\" && \$2==\"Static\" {exit 1}"
+}
+
+bird_static_status() {
+ ! birdc "show protocols" |
+ awk "\$1==\"$OCF_RESKEY_name\" && \$2==\"Static\" && \$4==\"up\" {exit 1}"
+}
+
+bird_is_ms() {
@fghaas
fghaas Nov 6, 2012

No need for this; we have ocf_is_ms.

+ [ ! -z "${OCF_RESKEY_CRM_meta_master_max}" ] && [ "${OCF_RESKEY_CRM_meta_master_max}" -gt 0 ]
+}
+
+
+# Returns:
+# OCF_RUNNING_MASTER - when bird_is_ms is true, and static route is up
+# OCF_SUCCESS - when bird_is_ms is false and bird pings, when bird_is_ms is true and static route is down
+# OCF_NOT_RUNNING - when bird doesn't pings
+# OCF_ERR_CONFIGURED - when bird pings and static route is not configured
+bird_status() {
+ if bird_ping
+ then
+ if bird_is_ms ; then
@fghaas
fghaas Nov 6, 2012

Can you explain under what circumstances this should be run as a master/slave set, and under what it shouldn't? Most RAs either only make sense as primitives, or only as M/S sets.

+ if bird_static_configured
+ then
+ if bird_static_status
+ then
+ return $OCF_RUNNING_MASTER
+ else
+ return $OCF_SUCCESS
+ fi
+ else
+ return $OCF_ERR_CONFIGURED
@dmuhamedagic
dmuhamedagic Jan 21, 2013

OCF_ERR_CONFIGURED is used when a particular RA is not well configured (usually missing parameters). This should probably return "err_generic".

+ fi
+ else
+ return $OCF_SUCCESS
+ fi
+ else
+ return $OCF_NOT_RUNNING
+ fi
+}
+
+
+bird_start() {
+ bird_status
+ ret=$?
+ [ $ret = $OCF_ERR_CONFIGURED ] && return $OCF_ERR_CONFIGURED
+ if [ $ret = $OCF_NOT_RUNNING ]
+ then
+ ocf_log info "Starting Bird"
+ # Execute the command as created above
+ ocf_run bird
+
+ # Waiting for start
+ while /bin/true ; do
+ bird_status
+ ret=$?
+ [ $ret = $OCF_ERR_CONFIGURED ] && return $OCF_ERR_CONFIGURED
+ [ $ret = $OCF_SUCCESS ] && return $OCF_SUCCESS
+ [ $ret = $OCF_RUNNING_MASTER ] && return $OCF_SUCCESS
@fghaas
fghaas Nov 6, 2012

Err, no. start shouldn't come back with $OCF_RUNNING_MASTER, only promote should.

+ [ $ret != $OCF_NOT_RUNNING ] && return $OCF_ERR_GENERIC
+ sleep 1
+ done
+ return $OCF_ERR_GENERIC
+ else
+ # If already running, consider start successful
+ ocf_log info "$process: $cmd is already running"
+ return $OCF_SUCCESS
+ fi
+}
+
+bird_stop() {
+ bird_status
+ ret=$?
+ [ $ret = $OCF_ERR_CONFIGURED ] && return $OCF_ERR_CONFIGURED
@dmuhamedagic
dmuhamedagic Jan 21, 2013

Again, OCF_ERR_CONFIGURED should be returned only in validate_all. It can be caused only by the static RA configuration, as defined by the user, not by the current system state.

+ [ $ret = $OCF_RUNNING_MASTER ] && return $OCF_RUNNING_MASTER
+ if [ $ret = $OCF_SUCCESS ]
+ then
+ ocf_log info "Stopping Bird"
+ # Execute the command as created above
@dmuhamedagic
dmuhamedagic Jan 21, 2013

This comment seems to be misplaced.

+ ocf_run birdc down
+
+ # Waiting for stopping bird
+ while /bin/true ; do
+ bird_status
+ ret=$?
+ [ $ret = $OCF_NOT_RUNNING ] && return $OCF_SUCCESS
+ [ $ret = $OCF_ERR_CONFIGURED ] && return $OCF_ERR_CONFIGURED
+ [ $ret = $OCF_RUNNING_MASTER ] && return $OCF_RUNNING_MASTER
+ [ $ret != $OCF_SUCCESS ] && return $OCF_ERR_GENERIC
+ sleep 1
+ done
+ return $OCF_ERR_GENERIC
+ else
+ # If already running, consider start successful
@dmuhamedagic
dmuhamedagic Jan 21, 2013

This is the stop action. Update comment.

+ ocf_log info "$process: $cmd is already stopped"
+ return $OCF_SUCCESS
+ fi
+}
+
+bird_promote() {
+ bird_status
+ ret=$?
+ [ $ret = $OCF_RUNNING_MASTER ] && return $OCF_SUCCESS
+ [ $ret = $OCF_NOT_RUNNING ] && return $OCF_NOT_RUNNING
+ [ $ret = $OCF_ERR_CONFIGURED ] && return $OCF_ERR_CONFIGURED
+ if [ $ret = $OCF_SUCCESS ]
+ then
+ ocf_log info "BIRD: Enabling static route '$OCF_RESKEY_name'"
+ ocf_run birdc "enable $OCF_RESKEY_name"
+
+ # Waiting for stopping bird
@dmuhamedagic
dmuhamedagic Jan 21, 2013

This comment is misleading.

+ while /bin/true ; do
+ bird_status
+ ret=$?
+ [ $ret = $OCF_NOT_RUNNING ] && return $OCF_NOT_RUNNING
+ [ $ret = $OCF_ERR_CONFIGURED ] && return $OCF_ERR_CONFIGURED
+ [ $ret = $OCF_RUNNING_MASTER ] && return $OCF_SUCCESS
+ [ $ret != $OCF_SUCCESS ] && return $OCF_ERR_GENERIC
@dmuhamedagic
dmuhamedagic Jan 21, 2013

Probably won't make any difference, but it would be correct to do "return $ret" here.

+ sleep 1
+ done
+ else
+ # If already running, consider start successful
+ ocf_log err "Unknown error - got $ret from status"
+ return $OCF_ERR_GENERIC
+ fi
+}
+
+bird_demote() {
+ bird_status
+ ret=$?
+ [ $ret = $OCF_SUCCESS ] && return $OCF_SUCCESS
+ [ $ret = $OCF_NOT_RUNNING ] && return $OCF_NOT_RUNNING
+ [ $ret = $OCF_ERR_CONFIGURED ] && return $OCF_ERR_CONFIGURED
+ if [ $ret = $OCF_RUNNING_MASTER ]
+ then
+ ocf_log info "BIRD: Disabling static route '$OCF_RESKEY_name'"
+ ocf_run birdc "disable $OCF_RESKEY_name"
+
+ # Waiting for stopping bird
+ while /bin/true ; do
+ bird_status
+ ret=$?
+ [ $ret = $OCF_NOT_RUNNING ] && return $OCF_NOT_RUNNING
+ [ $ret = $OCF_ERR_CONFIGURED ] && return $OCF_ERR_CONFIGURED
+ [ $ret = $OCF_SUCCESS ] && return $OCF_SUCCESS
+ [ $ret != $OCF_RUNNING_MASTER ] && return $OCF_ERR_GENERIC
+ sleep 1
+ done
+ else
+ # If already running, consider start successful
+ ocf_log err "Unknown error - got $ret from status"
+ return $OCF_ERR_GENERIC
+ fi
+}
+
+bird_validate() {
+
+ if ! have_binary bird ; then
+ ocf_log err "Failed to find bird"
+ return $OCF_ERR_INSTALLED
+ fi
+
+ if ! bird -p ; then
+ ocf_log err "Bird configuration file seams to be broken"
+ return $OCF_ERR_CONFIGURED
@fghaas
fghaas Nov 6, 2012

Nope. The config file may still be just fine on a different node; this has to return $OCF_ERR_INSTALLED.

+ fi
+
+ if [ -z "$OCF_RESKEY_name" ] ; then
+ ocf_log err "No name parameter configured"
+ return $OCF_ERR_CONFIGURED
@dmuhamedagic
dmuhamedagic Jan 21, 2013

This parameter is not required. It is only used iff the RA runs as ms.

+ fi
+
+ if ! have_binary birdc ; then
+ ocf_log err "Failed to find birdc"
+ return $OCF_ERR_INSTALLED
+ fi
+
+ if ! bird_ping ; then
+ ocf_log err "Failed to get status using birdc"
+ return $OCF_ERR_CONFIGURED
@dmuhamedagic
dmuhamedagic Jan 21, 2013

Hmm, why is this OCF_ERR_CONFIGURED? This check is superfluous. Isn't the RA supposed to also start the daemon?

+ fi
+
+ if ! bird_static_configured ; then
+ ocf_log err "Failed to get status of static '$OCF_RESKEY_name'"
+ return $OCF_ERR_INSTALLED
@dmuhamedagic
dmuhamedagic Jan 21, 2013

This check doesn't belong here.

+ fi
+ return $OCF_SUCCESS
+}
+
+bird_meta() {
+cat <<END
+<?xml version="1.0"?>
+<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
+<resource-agent name="Bird">
+ <version>1.0</version>
+ <longdesc lang="en">
+ This agent manages Bird routing daemon.
+ When it runs in master-slave configuration allows to set up/down static route
+ </longdesc>
+ <shortdesc lang="en">Manages Bird routing daemon</shortdesc>
+
+ <parameters>
+ <parameter name="name">
+ <longdesc lang="en">
+ Static route name as defined in bird. This route should be disabled by default.
+ It will be enabled when this resource will be started
@dmuhamedagic
dmuhamedagic Jan 21, 2013

Is this parameter supposed to be unique?

+ </longdesc>
+ <shortdesc lang="en">Static route name</shortdesc>
+ <content type="string" default=""/>
+ </parameter>
+ </parameters>
+ <actions>
+ <action name="start" timeout="20s" />
+ <action name="stop" timeout="20s" />
+ <action name="promote" timeout="20s" />
+ <action name="demote" timeout="20s" />
+ <action name="monitor" depth="0" timeout="20s" interval="10" />
+ <action name="meta-data" timeout="5" />
+ <action name="validate-all" timeout="5" />
+ </actions>
+</resource-agent>
+END
+exit 0
+}
+
+case "$1" in
+ meta-data|metadata|meta_data)
+ bird_meta
+ ;;
+ start)
+ bird_start
+ ;;
+ stop)
+ bird_stop
+ ;;
+ promote)
+ bird_promote
+ ;;
+ demote)
+ bird_demote
+ ;;
+ monitor)
+ bird_status
+ ;;
+ validate-all)
+ bird_validate
+ ;;
+ *)
+ ocf_log err "$0 was called with unsupported arguments: $*"
+ exit $OCF_ERR_UNIMPLEMENTED
+ ;;
+esac
View
1 heartbeat/Makefile.am
@@ -58,6 +58,7 @@ ocf_SCRIPTS = ClusterMon \
asterisk \
nginx \
AudibleAlarm \
+ Bird \
conntrackd \
db2 \
dhcpd \

2 comments on commit 52241bc

@fghaas

Thanks for the submission. I wonder if you have taken a look at http://www.linux-ha.org/doc/dev-guides/ra-dev-guide.html -- if you haven't, please do so now and fix up the RA accordingly.

Note that we are just nearing a release, so this new addition may not get much attention until the release is cut. In that case, we will return to the review after that.

@dmuhamedagic

Looks like you're missing the point of validate_all. Also, the meaning of the various OCF exit codes, in particular OCF_ERR_CONFIGURED.

Please read the development guide, as already suggested by fghaas. If there's anything unclear, ask on the linux-ha-dev mailing list.

Please sign in to comment.