Blame SOURCES/bz1328018-garbd-Introduces-garbd-resource-agent.patch

581d9d
From beb8dd713fa3a15ca01738de33f2031d1e5925d9 Mon Sep 17 00:00:00 2001
581d9d
From: Damien Ciabrini <dciabrin@redhat.com>
581d9d
Date: Wed, 1 Jun 2016 17:14:04 +0200
581d9d
Subject: [PATCH 1/2] garbd: Introduces garbd resource-agent
581d9d
581d9d
---
581d9d
 heartbeat/garbd | 417 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
581d9d
 1 file changed, 417 insertions(+)
581d9d
 create mode 100755 heartbeat/garbd
581d9d
581d9d
diff --git a/heartbeat/garbd b/heartbeat/garbd
581d9d
new file mode 100755
581d9d
index 0000000..950df76
581d9d
--- /dev/null
581d9d
+++ b/heartbeat/garbd
581d9d
@@ -0,0 +1,417 @@
581d9d
+#!/bin/sh
581d9d
+#
581d9d
+# Copyright (c) 2015 Damien Ciabrini <dciabrin@redhat.com>
581d9d
+#                    All Rights Reserved.
581d9d
+#
581d9d
+# This program is free software; you can redistribute it and/or modify
581d9d
+# it under the terms of version 2 of the GNU General Public License as
581d9d
+# published by the Free Software Foundation.
581d9d
+#
581d9d
+# This program is distributed in the hope that it would be useful, but
581d9d
+# WITHOUT ANY WARRANTY; without even the implied warranty of
581d9d
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
581d9d
+#
581d9d
+# Further, this software is distributed without any warranty that it is
581d9d
+# free of the rightful claim of any third person regarding infringement
581d9d
+# or the like.  Any license provided herein, whether implied or
581d9d
+# otherwise, applies only to this software file.  Patent licenses, if
581d9d
+# any, provided herein do not apply to combinations of this program with
581d9d
+# other software, or any other product whatsoever.
581d9d
+#
581d9d
+# You should have received a copy of the GNU General Public License
581d9d
+# along with this program; if not, write the Free Software Foundation,
581d9d
+# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
581d9d
+#
581d9d
+
581d9d
+##
581d9d
+# README.
581d9d
+#
581d9d
+# Resource agent for garbd, the Galera arbitrator
581d9d
+#
581d9d
+# You can use this agent if you run an even number of galera nodes,
581d9d
+# and you want an additional node to avoid split-brain situations.
581d9d
+#
581d9d
+# garbd requires that a Galera cluster is running, so make sure to
581d9d
+# add a proper ordering constraint to the cluster, e.g.:
581d9d
+#
581d9d
+#   pcs constraint order galera-master then garbd
581d9d
+#
581d9d
+# If you add garbd to the cluster while Galera is not running, you
581d9d
+# might want to disable it before setting up ordering constraint, e.g.:
581d9d
+#
581d9d
+#   pcs resource create garbd garbd \
581d9d
+#      wsrep_cluster_address=gcomm://node1:4567,node2:4567 \
581d9d
+#      meta target-role=stopped
581d9d
+#
581d9d
+# Use location constraints to avoid running galera and garbd on
581d9d
+# the same node, e.g.:
581d9d
+#
581d9d
+#   pcs constraint colocation add garbd with galera-master -INFINITY
581d9d
+#   pcs constraint location garbd prefers node3=INFINITY
581d9d
+#
581d9d
+##
581d9d
+
581d9d
+#######################################################################
581d9d
+# Initialization:
581d9d
+
581d9d
+: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
581d9d
+. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
581d9d
+
581d9d
+#######################################################################
581d9d
+# Set default paramenter values
581d9d
+
581d9d
+OCF_RESKEY_binary_default="/usr/sbin/garbd"
581d9d
+OCF_RESKEY_log_default="/var/log/garbd.log"
581d9d
+OCF_RESKEY_pid_default="/var/run/garbd.pid"
581d9d
+OCF_RESKEY_user_default="mysql"
581d9d
+if [ "X${HOSTOS}" = "XOpenBSD" ];then
581d9d
+    OCF_RESKEY_group_default="_mysql"
581d9d
+else
581d9d
+    OCF_RESKEY_group_default="mysql"
581d9d
+fi
581d9d
+
581d9d
+: ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}}
581d9d
+: ${OCF_RESKEY_log=${OCF_RESKEY_log_default}}
581d9d
+: ${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}}
581d9d
+: ${OCF_RESKEY_user=${OCF_RESKEY_user_default}}
581d9d
+: ${OCF_RESKEY_group=${OCF_RESKEY_group_default}}
581d9d
+
581d9d
+usage() {
581d9d
+  cat <
581d9d
+usage: $0 (start|stop|validate-all|meta-data|status|monitor)
581d9d
+
581d9d
+$0 manages a Galera arbitrator.
581d9d
+
581d9d
+The 'start' operation starts the arbitrator.
581d9d
+The 'stop' operation stops the arbitrator.
581d9d
+The 'status' operation reports whether the arbitrator is running
581d9d
+The 'monitor' operation reports whether the arbitrator seems to be working
581d9d
+The 'validate-all' operation reports whether the parameters are valid
581d9d
+
581d9d
+UEND
581d9d
+}
581d9d
+
581d9d
+meta_data() {
581d9d
+   cat <
581d9d
+
581d9d
+
581d9d
+<resource-agent name="garbd">
581d9d
+<version>1.0</version>
581d9d
+
581d9d
+<longdesc lang="en">
581d9d
+Resource script for managing Galera arbitrator.
581d9d
+</longdesc>
581d9d
+<shortdesc lang="en">Manages a galera arbitrator instance</shortdesc>
581d9d
+<parameters>
581d9d
+
581d9d
+<parameter name="binary" unique="0" required="0">
581d9d
+<longdesc lang="en">
581d9d
+Location of the Galera arbitrator binary
581d9d
+</longdesc>
581d9d
+<shortdesc lang="en">garbd server binary</shortdesc>
581d9d
+<content type="string" default="${OCF_RESKEY_binary_default}" />
581d9d
+</parameter>
581d9d
+
581d9d
+<parameter name="user" unique="0" required="0">
581d9d
+<longdesc lang="en">
581d9d
+User running the garbd process
581d9d
+</longdesc>
581d9d
+<shortdesc lang="en">garbd user</shortdesc>
581d9d
+<content type="string" default="${OCF_RESKEY_user_default}" />
581d9d
+</parameter>
581d9d
+
581d9d
+<parameter name="group" unique="0" required="0">
581d9d
+<longdesc lang="en">
581d9d
+Group running garbd (for logfile permissions)
581d9d
+</longdesc>
581d9d
+<shortdesc lang="en">garbd group</shortdesc>
581d9d
+<content type="string" default="${OCF_RESKEY_group_default}"/>
581d9d
+</parameter>
581d9d
+
581d9d
+<parameter name="log" unique="0" required="0">
581d9d
+<longdesc lang="en">
581d9d
+The logfile to be used for garbd.
581d9d
+</longdesc>
581d9d
+<shortdesc lang="en">Galera arbitrator log file</shortdesc>
581d9d
+<content type="string" default="${OCF_RESKEY_log_default}"/>
581d9d
+</parameter>
581d9d
+
581d9d
+<parameter name="pid" unique="0" required="0">
581d9d
+<longdesc lang="en">
581d9d
+The pidfile to be used for garbd.
581d9d
+</longdesc>
581d9d
+<shortdesc lang="en">Galera arbitrator pidfile</shortdesc>
581d9d
+<content type="string" default="${OCF_RESKEY_pid_default}"/>
581d9d
+</parameter>
581d9d
+
581d9d
+<parameter name="options" unique="0" required="0">
581d9d
+<longdesc lang="en">
581d9d
+Additional parameters which are passed to garbd on startup.
581d9d
+</longdesc>
581d9d
+<shortdesc lang="en">Additional parameters to pass to garbd</shortdesc>
581d9d
+<content type="string" default=""/>
581d9d
+</parameter>
581d9d
+
581d9d
+<parameter name="wsrep_cluster_address" unique="0" required="1">
581d9d
+<longdesc lang="en">
581d9d
+The galera cluster address. This takes the form of:
581d9d
+gcomm://node:port,node:port,node:port
581d9d
+
581d9d
+Unlike Galera servers, port is mandatory for garbd.
581d9d
+</longdesc>
581d9d
+<shortdesc lang="en">Galera cluster address</shortdesc>
581d9d
+<content type="string" default=""/>
581d9d
+</parameter>
581d9d
+
581d9d
+<parameter name="wsrep_cluster_name" unique="0" required="1">
581d9d
+<longdesc lang="en">
581d9d
+The group name of the Galera cluster to connect to.
581d9d
+</longdesc>
581d9d
+<shortdesc lang="en">Galera cluster name</shortdesc>
581d9d
+<content type="string" default=""/>
581d9d
+</parameter>
581d9d
+
581d9d
+</parameters>
581d9d
+
581d9d
+<actions>
581d9d
+<action name="start" timeout="20" />
581d9d
+<action name="stop" timeout="20" />
581d9d
+<action name="monitor" depth="0" timeout="20" interval="20" />
581d9d
+<action name="validate-all" timeout="5" />
581d9d
+<action name="meta-data" timeout="5" />
581d9d
+</actions>
581d9d
+</resource-agent>
581d9d
+END
581d9d
+}
581d9d
+
581d9d
+
581d9d
+garbd_start()
581d9d
+{
581d9d
+    local rc
581d9d
+    local pid
581d9d
+    local start_wait
581d9d
+    local garbd_params
581d9d
+
581d9d
+    garbd_status info
581d9d
+    rc=$?
581d9d
+    if [ $rc -eq $OCF_SUCCESS ]; then
581d9d
+        ocf_exit_reason "garbd started outside of the cluster's control"
581d9d
+        return $OCF_ERR_GENERIC;
581d9d
+    fi
581d9d
+
581d9d
+    touch $OCF_RESKEY_log
581d9d
+    chown $OCF_RESKEY_user:$OCF_RESKEY_group $OCF_RESKEY_log
581d9d
+    chmod 0640 $OCF_RESKEY_log
581d9d
+    [ -x /sbin/restorecon ] && /sbin/restorecon $OCF_RESKEY_log
581d9d
+
581d9d
+    garbd_params="--address=${OCF_RESKEY_wsrep_cluster_address} \
581d9d
+                  --group ${OCF_RESKEY_wsrep_cluster_name} \
581d9d
+                  --log ${OCF_RESKEY_log}"
581d9d
+
581d9d
+    if [ ! -z "${OCF_RESKEY_options}" ]; then
581d9d
+        garbd_params="${garbd_params} --options=${OCF_RESKEY_options}"
581d9d
+    fi
581d9d
+
581d9d
+    # garbd has no parameter to run as a specific user,
581d9d
+    # so we need to start it by our own means
581d9d
+    pid=$(su - -s /bin/sh $OCF_RESKEY_user -c "${OCF_RESKEY_binary} ${garbd_params} >/dev/null 2>&1 & echo \$!")
581d9d
+
581d9d
+    # garbd doesn't create a pidfile either, so we create our own
581d9d
+    echo $pid > $OCF_RESKEY_pid
581d9d
+    if [ $? -ne 0 ]; then
581d9d
+        ocf_exit_reason "Cannot create pidfile for garbd at $OCF_RESKEY_pid (rc=$?), please check your installation"
581d9d
+        return $OCF_ERR_GENERIC
581d9d
+    fi
581d9d
+
581d9d
+    # Spin waiting for garbd to connect to the cluster.
581d9d
+    # Let the CRM/LRM time us out if required.
581d9d
+    start_wait=1
581d9d
+    while [ $start_wait -eq 1 ]; do
581d9d
+        garbd_monitor info
581d9d
+        rc=$?
581d9d
+        if [ $rc -eq $OCF_NOT_RUNNING ]; then
581d9d
+            ocf_exit_reason "garbd failed to start (pid=$pid), check logs in ${OCF_RESKEY_log}"
581d9d
+            return $OCF_ERR_GENERIC
581d9d
+        elif [ $rc -eq $OCF_SUCCESS ]; then
581d9d
+            start_wait=0
581d9d
+        fi
581d9d
+        sleep 2
581d9d
+    done
581d9d
+
581d9d
+    ocf_log info "garbd connected to cluster \"${OCF_RESKEY_wsrep_cluster_name}\""
581d9d
+    return $OCF_SUCCESS
581d9d
+}
581d9d
+
581d9d
+garbd_status()
581d9d
+{
581d9d
+    local loglevel=$1
581d9d
+    local rc
581d9d
+    ocf_pidfile_status $OCF_RESKEY_pid
581d9d
+    rc=$?
581d9d
+
581d9d
+    if [ $rc -eq 0 ]; then
581d9d
+        return $OCF_SUCCESS
581d9d
+    elif [ $rc -eq 2 ]; then
581d9d
+        return $OCF_NOT_RUNNING
581d9d
+    else
581d9d
+        # clean up if pidfile is stale
581d9d
+        if [ $rc -eq 1 ]; then
581d9d
+            ocf_log $loglevel "garbd not running: removing old PID file"
581d9d
+            rm -f $OCF_RESKEY_pid
581d9d
+        fi
581d9d
+        return $OCF_ERR_GENERIC
581d9d
+    fi
581d9d
+}
581d9d
+
581d9d
+garbd_monitor()
581d9d
+{
581d9d
+    local rc
581d9d
+    local pid
581d9d
+    local loglevel=$1
581d9d
+
581d9d
+    # Set loglevel to info during probe
581d9d
+    if ocf_is_probe; then
581d9d
+        loglevel="info"
581d9d
+    fi
581d9d
+
581d9d
+    garbd_status $loglevel
581d9d
+    rc=$?
581d9d
+
581d9d
+    # probe just wants to know if garbd is running or not
581d9d
+    if [ ocf_is_probe -a $rc -ne $OCF_SUCCESS ]; then
581d9d
+        rc=$OCF_NOT_RUNNING
581d9d
+    fi
581d9d
+
581d9d
+    # Consider garbd is working if it's connected to at least
581d9d
+    # one node in the galera cluster.
581d9d
+    # Note: a Galera node in Non-Primary state will be
581d9d
+    # stopped by the galera RA. So we can assume that
581d9d
+    # garbd will always be connected to the right partition
581d9d
+    if [ $rc -eq $OCF_SUCCESS ]; then
581d9d
+        pid=`cat $OCF_RESKEY_pid 2> /dev/null `
581d9d
+        netstat -tnp 2>/dev/null | grep -s -q "ESTABLISHED.*${pid}/"
581d9d
+        if [ $? -ne 0 ]; then
581d9d
+            ocf_log $loglevel "garbd disconnected from cluster \"${OCF_RESKEY_wsrep_cluster_name}\""
581d9d
+            rc=$OCF_ERR_GENERIC
581d9d
+        fi
581d9d
+    fi
581d9d
+
581d9d
+    return $rc
581d9d
+}
581d9d
+
581d9d
+garbd_stop()
581d9d
+{
581d9d
+    local rc
581d9d
+    local pid
581d9d
+
581d9d
+    if [ ! -f $OCF_RESKEY_pid ]; then
581d9d
+        ocf_log info "garbd is not running"
581d9d
+        return $OCF_SUCCESS
581d9d
+    fi
581d9d
+
581d9d
+    pid=`cat $OCF_RESKEY_pid 2> /dev/null `
581d9d
+
581d9d
+    ocf_log info "stopping garbd"
581d9d
+
581d9d
+    # make sure the process is stopped
581d9d
+    ocf_stop_processes TERM 10 $pid
581d9d
+    rc=$?
581d9d
+
581d9d
+    if [ $rc -ne 0 ]; then
581d9d
+        return $OCF_ERR_GENERIC
581d9d
+    else
581d9d
+        rm -f $OCF_RESKEY_pid
581d9d
+        ocf_log info "garbd stopped"
581d9d
+        return $OCF_SUCCESS
581d9d
+    fi
581d9d
+}
581d9d
+
581d9d
+garbd_validate()
581d9d
+{
581d9d
+    if ! have_binary "$OCF_RESKEY_binary"; then
581d9d
+        ocf_exit_reason "Setup problem: couldn't find command: $OCF_RESKEY_binary"
581d9d
+        return $OCF_ERR_INSTALLED;
581d9d
+    fi
581d9d
+
581d9d
+    if ! have_binary "netstat"; then
581d9d
+        ocf_exit_reason "Setup problem: couldn't find command: netstat"
581d9d
+        return $OCF_ERR_INSTALLED;
581d9d
+    fi
581d9d
+
581d9d
+    if [ -z "$OCF_RESKEY_wsrep_cluster_address" ]; then
581d9d
+        ocf_exit_reason "garbd must be configured with a wsrep_cluster_address value."
581d9d
+        return $OCF_ERR_CONFIGURED
581d9d
+    fi
581d9d
+
581d9d
+    # unlike galera RA, ports must be set in cluster address for garbd
581d9d
+    # https://github.com/codership/galera/issues/98
581d9d
+    for node in $(echo "$OCF_RESKEY_wsrep_cluster_address" | sed 's/gcomm:\/\///g' | tr -d ' ' | tr -s ',' ' '); do
581d9d
+        echo $node | grep -s -q ':[1-9][0-9]*$'
581d9d
+        if [ $? -ne 0 ]; then
581d9d
+            ocf_exit_reason "wsrep_cluster_address must specify ports (gcomm://node1:port,node2:port)."
581d9d
+            return $OCF_ERR_CONFIGURED
581d9d
+        fi
581d9d
+    done
581d9d
+
581d9d
+    # Ensure that the encryption method is set if garbd is configured
581d9d
+    # to use SSL.
581d9d
+    echo $OCF_RESKEY_options | grep -s -q -i -E '\bsocket.ssl_(key|cert)='
581d9d
+    if [ $? -eq 0 ]; then
581d9d
+        echo $OCF_RESKEY_options | grep -s -q -i -E '\bsocket.ssl_cipher='
581d9d
+        if [ $? -ne 0 ]; then
581d9d
+            ocf_exit_reason "option socket.ssl_cipher must be set if SSL is enabled."
581d9d
+            return $OCF_ERR_CONFIGURED
581d9d
+        fi
581d9d
+    fi
581d9d
+
581d9d
+    if [ -z "$OCF_RESKEY_wsrep_cluster_name" ]; then
581d9d
+        ocf_exit_reason "garbd must be configured with a wsrep_cluster_name value."
581d9d
+        return $OCF_ERR_CONFIGURED
581d9d
+    fi
581d9d
+
581d9d
+    if ! getent passwd $OCF_RESKEY_user >/dev/null 2>&1; then
581d9d
+        ocf_exit_reason "User $OCF_RESKEY_user doesn't exist"
581d9d
+        return $OCF_ERR_INSTALLED
581d9d
+    fi
581d9d
+
581d9d
+    if ! getent group $OCF_RESKEY_group >/dev/null 2>&1; then
581d9d
+        ocf_exit_reason "Group $OCF_RESKEY_group doesn't exist"
581d9d
+        return $OCF_ERR_INSTALLED
581d9d
+    fi
581d9d
+
581d9d
+    return $OCF_SUCCESS
581d9d
+}
581d9d
+
581d9d
+case "$1" in
581d9d
+  meta-data)    meta_data
581d9d
+        exit $OCF_SUCCESS;;
581d9d
+  usage|help)   usage
581d9d
+        exit $OCF_SUCCESS;;
581d9d
+esac
581d9d
+
581d9d
+garbd_validate
581d9d
+rc=$?
581d9d
+
581d9d
+# trap configuration errors early, but don't block stop in such cases
581d9d
+LSB_STATUS_STOPPED=3
581d9d
+if [ $rc -ne 0 ]; then
581d9d
+    case "$1" in
581d9d
+        stop) exit $OCF_SUCCESS;;
581d9d
+        status) exit $LSB_STATUS_STOPPED;;
581d9d
+        *) exit $rc;;
581d9d
+    esac
581d9d
+fi
581d9d
+
581d9d
+# What kind of method was invoked?
581d9d
+case "$1" in
581d9d
+  start)    garbd_start;;
581d9d
+  stop)     garbd_stop;;
581d9d
+  status)   garbd_status err;;
581d9d
+  monitor)  garbd_monitor err;;
581d9d
+  promote)  garbd_promote;;
581d9d
+  demote)   garbd_demote;;
581d9d
+  validate-all) exit $OCF_SUCCESS;;
581d9d
+
581d9d
+ *)     usage
581d9d
+        exit $OCF_ERR_UNIMPLEMENTED;;
581d9d
+esac
581d9d
-- 
581d9d
2.5.5
581d9d
581d9d
581d9d
From f36298aa97fc4cbed3e2eff28d6821f4314becbe Mon Sep 17 00:00:00 2001
581d9d
From: Damien Ciabrini <dciabrin@redhat.com>
581d9d
Date: Fri, 3 Jun 2016 18:27:38 +0200
581d9d
Subject: [PATCH 2/2] garbd: fix install and man page
581d9d
581d9d
---
581d9d
 doc/man/Makefile.am   | 1 +
581d9d
 heartbeat/Makefile.am | 1 +
581d9d
 2 files changed, 2 insertions(+)
581d9d
581d9d
diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am
581d9d
index 5e28895..25fb29b 100644
581d9d
--- a/doc/man/Makefile.am
581d9d
+++ b/doc/man/Makefile.am
581d9d
@@ -105,6 +105,7 @@ man_MANS	       = ocf_heartbeat_AoEtarget.7 \
581d9d
                           ocf_heartbeat_exportfs.7 \
581d9d
                           ocf_heartbeat_fio.7 \
581d9d
                           ocf_heartbeat_galera.7 \
581d9d
+                          ocf_heartbeat_garbd.7 \
581d9d
                           ocf_heartbeat_iSCSILogicalUnit.7 \
581d9d
                           ocf_heartbeat_iSCSITarget.7 \
581d9d
                           ocf_heartbeat_iface-bridge.7 \
581d9d
diff --git a/heartbeat/Makefile.am b/heartbeat/Makefile.am
581d9d
index b70c104..df0e3b8 100644
581d9d
--- a/heartbeat/Makefile.am
581d9d
+++ b/heartbeat/Makefile.am
581d9d
@@ -76,6 +76,7 @@ ocf_SCRIPTS	     =  ClusterMon		\
581d9d
 			Filesystem		\
581d9d
 			fio			\
581d9d
 			galera			\
581d9d
+			garbd			\
581d9d
 			ids			\
581d9d
 			iscsi			\
581d9d
 			ICP			\
581d9d
-- 
581d9d
2.5.5
581d9d