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