Skip to content
This repository

Little tweaks to redis RA #32

Open
wants to merge 17 commits into from

5 participants

José de Paula E. Júnior Dejan Muhamedagic ChadScott Florian Haas michael-dev
José de Paula E. Júnior

Got the work from the previous developer and did some tweaking.

and others added some commits July 15, 2011
The deletion of the primary IP via the ip command will also remove th…
…e secondary IP. Thus, trying to delete the secondary IP after the primary IP was deleted will result in an error. This fix assures that delete_interface() will only result in an error if ' addr delete' has failed and the ip is still listed in addr show.
2c6d3bc
Adds the RA for the redis service, based on that of mysql. Supports m…
…aster/slave configurations of a depth of 1.
d0b3870
José de Paula E. Júnior Redis resource agent, now fully functional a4a5b6b
Florian Haas

Please consider rephrasing this, and escape (or omit) "$". Name of the redis binary. Use an absolute path if the binary is not resolvable via \$PATH perhaps.

Florian Haas

Useless error message.

I was using it for testing and forgot to remove.

Florian Haas

Are you sure you need to filter on the output? Would it be possible to act on the exit code instead?

Unfortunately not. When redis is loading or starting up and you try to set it as slave to someone it returns that it can't do it because of the loading, but the exit status is 0. This was the main bug on the RA.

Collaborator

Fair enough, just checking.

This hangs on redis version 1.2.0 (used on Ubuntu Lucid)... it doesn't appear that the "loading:" parameter is available. A better logic might be to determine if the line is there or not, then 'cut' the value out and compare, otherwise just continue.

Dejan Muhamedagic
Collaborator

Is #37 superseding this one?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 17 unique commits by 6 authors.

Jul 15, 2011
The deletion of the primary IP via the ip command will also remove th…
…e secondary IP. Thus, trying to delete the secondary IP after the primary IP was deleted will result in an error. This fix assures that delete_interface() will only result in an error if ' addr delete' has failed and the ip is still listed in addr show.
2c6d3bc
Adds the RA for the redis service, based on that of mysql. Supports m…
…aster/slave configurations of a depth of 1.
d0b3870
Nov 23, 2011
José de Paula E. Júnior Redis resource agent, now fully functional a4a5b6b
Nov 28, 2011
José de Paula E. Júnior Minor fixes on text and error messages 5b8a4a2
Aug 30, 2012
michael-dev fix bringing up if no master has already been promoted (but two maste…
…rs are already running)
8358cd1
michael-dev fix typo 1950a8f
michael-dev fix start command: needs full path 93f86fa
Sep 02, 2012
michael-dev redis: get port and password from config file 5e407dc
michael-dev fix port in slaveof command fd43b12
Sep 03, 2012
michael-dev check and repair AOF file automatically 73d3c07
Sep 04, 2012
michael-dev wait and test for redis to accept connections before returning OK in …
…start
3f38e86
Sep 11, 2012
michael-dev redis: fix stop command not stopping e1d3f37
Sep 18, 2012
michael-dev fix typo 4b4a6ec
Jan 22, 2013
detect crashed redis instance 9912a84
Jan 23, 2013
add IPv6addr script which does not ping 4685082
Jan 29, 2013
michael-dev fix ms/state detection 0711296
Feb 13, 2014
José de Paula E. Júnior Merge pull request #1 from michael-dev/master
redis: bring up in slave mode
9ab2c63
This page is out of date. Refresh to see the latest.
10  heartbeat/IPaddr2
@@ -417,8 +417,16 @@ delete_interface () {
417 417
 	netmask="$3"
418 418
 
419 419
 	CMD="$IP2UTIL -f inet addr delete $ipaddr/$netmask dev $iface"
  420
+	ocf_run $CMD
420 421
 
421  
-	ocf_run $CMD || return $OCF_ERR_GENERIC
  422
+	if [ $? -ne 0 ]; then
  423
+		CMD="$IP2UTIL -f inet addr show dev $iface | grep '$ipaddr\/$netmask'"
  424
+		ocf_run $CMD
  425
+
  426
+		if [ $? -eq 0 ]; then
  427
+			return $OCF_ERR_GENERIC
  428
+		fi
  429
+	fi
422 430
 
423 431
 	if ocf_is_true $OCF_RESKEY_flush_routes; then
424 432
 	    ocf_run $IP2UTIL route flush cache
271  heartbeat/IPv6addr2
... ...
@@ -0,0 +1,271 @@
  1
+#!/bin/bash
  2
+#
  3
+#       OCF Resource Agent compliant resource script.
  4
+#	Arturo Borrero <aborrero@cica.es> <cer.inet@gmail.com> || October 2011
  5
+#
  6
+#	Based on the anything RA.
  7
+#
  8
+# 	GPLv3 Licensed. You can read the license in
  9
+# 	http://www.gnu.org/licenses/gpl-3.0.html
  10
+#
  11
+#	Use this RA if you want an IPv6 address in
  12
+#	the main loopback interface (for example usign LVS for loadbalancing)
  13
+#
  14
+# Initialization:
  15
+
  16
+: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/resource.d/heartbeat}
  17
+. ${OCF_FUNCTIONS_DIR}/.ocf-shellfuncs
  18
+
  19
+# Custom vars:
  20
+IFCONFIG_BIN="/sbin/ifconfig"
  21
+GREP_BIN="grep"
  22
+SED_BIN="sed"
  23
+process=$OCF_RESOURCE_INSTANCE
  24
+ipv6addr=$OCF_RESKEY_ipv6addr
  25
+cidr_netmask=$OCF_RESKEY_cidr_netmask
  26
+IFACE=$OCF_RESKEY_nic
  27
+
  28
+ipv6addr=$(echo "$ipv6addr" | $SED_BIN 's/:0*/:/g')
  29
+
  30
+validate_ipv6(){
  31
+	ocf_log debug "Validating IPv6 addr: [\"$1\"]."
  32
+
  33
+	echo "$1" | $GREP_BIN -E "^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:)))(%.+)?\s*$" > /dev/null
  34
+	if [ $? -eq 0 ]
  35
+	then
  36
+		ocf_log debug "IPv6 addr: [\"$1\"] is valid."
  37
+		return 1
  38
+	fi
  39
+	# the ipv6 is invalid
  40
+	ocf_log err "IPv6 addr: [\"$1\"] is not valid."
  41
+	return 0
  42
+}
  43
+validate_cidr(){
  44
+	ocf_log debug "Validating cidr: \"$1\"."
  45
+
  46
+	if [ $1 -lt 129 ]
  47
+	then
  48
+		if [ $1 -gt 0 ]
  49
+		then
  50
+			# the cidr is valid
  51
+			ocf_log debug "Cidr: \"$1\" is valid."
  52
+			return 1
  53
+		fi
  54
+	fi
  55
+	ocf_log err "Cidr: \"$1\" is not valid."
  56
+	return 0
  57
+}
  58
+
  59
+iface_has_ipv6()
  60
+{
  61
+	ocf_log debug "Checking if iface \"$IFACE\" has the ipv6 [\"$ipv6addr\"]."
  62
+	if [ ! -z $1 ]
  63
+	then
  64
+		$IFCONFIG_BIN $IFACE | $GREP_BIN $1 2> /dev/null > /dev/null
  65
+		if [ $? -eq 0 ]
  66
+		then
  67
+			# the iface has the IPv6
  68
+			ocf_log debug "The iface \"$IFACE\" has the ipv6 [\"$ipv6addr\"]."
  69
+			return 1
  70
+		fi
  71
+		ocf_log debug "The iface \"$IFACE\" does not have the ipv6 [\"$ipv6addr\"]."
  72
+	fi
  73
+	return 0
  74
+}
  75
+
  76
+IPv6addr2_status() {
  77
+	iface_has_ipv6 $ipv6addr
  78
+	if [ $? -eq 1 ]
  79
+	then
  80
+		return $OCF_RUNNING
  81
+	else
  82
+		return $OCF_NOT_RUNNING
  83
+	fi
  84
+}
  85
+
  86
+IPv6addr2_start() {
  87
+	if ! IPv6addr2_status
  88
+	then
  89
+		# First, validate the input parameteres, ipv6addr and cidr_netmaks
  90
+		validate_ipv6 $ipv6addr
  91
+		if [ $? -ne 1 ]
  92
+		then
  93
+			ocf_log err "$process: The ipv6 addr: \"$ipv6addr\" is not a valid one."
  94
+			return $OCF_ERR_GENERIC
  95
+		fi
  96
+		validate_cidr $cidr_netmask
  97
+		if [ $? -ne 1 ]
  98
+		then
  99
+			ocf_log err "$process: The cidr netmask \"$cidr_netmask\" is not valid."
  100
+			return $OCF_ERR_GENERIC
  101
+		fi
  102
+
  103
+
  104
+		# Before assign the ip, check if we already have that ip
  105
+		iface_has_ipv6 $ipv6addr
  106
+		if [ $? -ne 1 ]
  107
+		then
  108
+			ocf_run $IFCONFIG_BIN $IFACE add $ipv6addr/$cidr_netmask
  109
+		fi
  110
+
  111
+		# Check what happened here.
  112
+		if IPv6addr2_status
  113
+		then
  114
+			ocf_log debug "$process: Started successfully."
  115
+			return $OCF_SUCCESS
  116
+		else
  117
+			ocf_log err "$process: Could not be started: ipv6addr[\"$ipv6addr\"] cidr_netmask[\"$cidr_netmask\"] all_args[\"$*\"]."
  118
+			return $OCF_ERR_GENERIC
  119
+		fi
  120
+	else
  121
+		# If already running, consider start successful
  122
+		ocf_log debug "$process: is already running"
  123
+		return $OCF_SUCCESS
  124
+	fi
  125
+}
  126
+
  127
+IPv6addr2_stop() {
  128
+
  129
+	ocf_log debug "$process: Running STOP function."
  130
+
  131
+        if [ -n "$OCF_RESKEY_stop_timeout" ]
  132
+        then
  133
+                stop_timeout=$OCF_RESKEY_stop_timeout
  134
+        elif [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then
  135
+                # Allow 2/3 of the action timeout for the orderly shutdown
  136
+                # (The origin unit is ms, hence the conversion)
  137
+                stop_timeout=$((OCF_RESKEY_CRM_meta_timeout/1500))
  138
+        else
  139
+                stop_timeout=10
  140
+        fi
  141
+	if IPv6addr2_status
  142
+	then
  143
+		ocf_run $IFCONFIG_BIN $IFACE del $ipv6addr/$cidr_netmask
  144
+                i=0
  145
+                while [ $i -lt $stop_timeout ]
  146
+                do
  147
+                        if ! IPv6addr2_status
  148
+                        then
  149
+                                return $OCF_SUCCESS
  150
+                        fi
  151
+                        sleep 1
  152
+                        i=`expr $i + 1`
  153
+                done
  154
+                ocf_log warn "Stop failed. Trying again."
  155
+                ocf_run $IFCONFIG_BIN $IFACE del $ipv6addr
  156
+                if ! IPv6addr2_status
  157
+                then
  158
+                        ocf_log warn "Stop success."
  159
+                        return $OCF_SUCCESS
  160
+                else
  161
+                        ocf_log err "Failed to stop."
  162
+                        return $OCF_ERR_GENERIC
  163
+                fi
  164
+	else
  165
+		return $OCF_SUCCESS
  166
+	fi
  167
+}
  168
+
  169
+IPv6addr2_monitor() {
  170
+	IPv6addr2_status
  171
+	ret=$?
  172
+	if [ $ret -eq $OCF_SUCCESS ]
  173
+	then
  174
+		if [ -n "$OCF_RESKEY_monitor_hook" ]; then
  175
+			eval "$OCF_RESKEY_monitor_hook"
  176
+                        if [ $? -ne $OCF_SUCCESS ]; then
  177
+                                return ${OCF_ERR_GENERIC}
  178
+                        fi
  179
+			return $OCF_SUCCESS
  180
+		else
  181
+			true
  182
+		fi
  183
+	else
  184
+		return $ret
  185
+	fi
  186
+}
  187
+
  188
+
  189
+IPv6addr2_validate() {
  190
+
  191
+	ocf_log debug "IPv6addr2 validating: args:[\"$*\"]"
  192
+
  193
+	if [ -x $IFCONFIG_BIN ]
  194
+	then
  195
+		ocf_log debug "Binary \"$IFCONFIG_BIN\" exist and is executable."
  196
+		return $OCF_SUCCESS
  197
+	else
  198
+		ocf_log err "Binary \"$IFCONFIG_BIN\" does not exist or isn't executable."
  199
+		return $OCF_ERR_INSTALLED
  200
+	fi
  201
+	ocf_log err "Error while validating."
  202
+	return $OCF_ERR_GENERIC
  203
+}
  204
+
  205
+IPv6addr2_meta(){
  206
+cat <<END
  207
+<?xml version="1.0"?>
  208
+<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
  209
+<resource-agent name="IPv6addr2">
  210
+<version>0.1</version>
  211
+<longdesc lang="en">
  212
+OCF RA to manage IPv6addr on loopback interface Linux
  213
+</longdesc>
  214
+<shortdesc lang="en">IPv6 addr on loopback linux</shortdesc>
  215
+
  216
+<parameters>
  217
+<parameter name="ipv6addr" required="1">
  218
+<longdesc lang="en">
  219
+The ipv6 addr to asign to the loopback interface.
  220
+</longdesc>
  221
+<shortdesc lang="en">Ipv6 addr to the loopback interface.</shortdesc>
  222
+<content type="string" default=""/>
  223
+</parameter>
  224
+<parameter name="cidr_netmask" required="1">
  225
+<longdesc lang="en">
  226
+The cidr netmask of the ipv6 addr.
  227
+</longdesc>
  228
+<shortdesc lang="en">netmask of the ipv6 addr.</shortdesc>
  229
+<content type="string" default="128"/>
  230
+</parameter>
  231
+<parameter name="nic" required="1">
  232
+<longdesc lang="en">
  233
+iface
  234
+</longdesc>
  235
+<shortdesc lang="en">IFACE</shortdesc>
  236
+<content type="string" />
  237
+</parameter>
  238
+</parameters>
  239
+<actions>
  240
+<action name="start"   timeout="20s" />
  241
+<action name="stop"    timeout="20s" />
  242
+<action name="monitor" depth="0"  timeout="20s" interval="10" />
  243
+<action name="meta-data"  timeout="5" />
  244
+<action name="validate-all"  timeout="5" />
  245
+</actions>
  246
+</resource-agent>
  247
+END
  248
+exit 0
  249
+}
  250
+
  251
+case "$1" in
  252
+	meta-data|metadata|meta_data|meta)
  253
+		IPv6addr2_meta
  254
+	;;
  255
+	start)
  256
+		IPv6addr2_start
  257
+	;;
  258
+	stop)
  259
+		IPv6addr2_stop
  260
+	;;
  261
+	monitor)
  262
+		IPv6addr2_monitor
  263
+	;;
  264
+	validate-all)
  265
+		IPv6addr2_validate
  266
+	;;
  267
+	*)
  268
+		ocf_log err "$0 was called with unsupported arguments:"
  269
+		exit $OCF_ERR_UNIMPLEMENTED
  270
+	;;
  271
+esac
669  heartbeat/redis
... ...
@@ -0,0 +1,669 @@
  1
+#!/bin/bash
  2
+#
  3
+#
  4
+# redis
  5
+#
  6
+# Description:  Manages redis as Linux-HA resource
  7
+#
  8
+# Authors:  Alan Robertson,
  9
+#       Jakub Janczak,
  10
+#       Andrew Beekhof,
  11
+#       Sebastian Reitenbach,
  12
+#       Narayan Newton,
  13
+#       Marian Marinov,
  14
+#       Florian Haas:                 MySQL script
  15
+#       Martin Walter:                rewrite as redis
  16
+#       Jose Junior:                  tweaks to the redis version
  17
+#       Michael Braun:                properly bringup as slave (even if no master has already been promoted)
  18
+#
  19
+# Support:  linux-ha@lists.linux-ha.org
  20
+# License:  GNU General Public License (GPL)
  21
+#
  22
+# (c) 2002-2005 International Business Machines, Inc.
  23
+#     2005-2010 Linux-HA contributors
  24
+#
  25
+# An example usage in /etc/ha.d/haresources:
  26
+#       node1  10.0.0.170 redis
  27
+#
  28
+# See usage() function below for more details...
  29
+#
  30
+# OCF instance parameters:
  31
+#   OCF_RESKEY_binary
  32
+#   OCF_RESKEY_client_binary
  33
+#   OCF_RESKEY_aof_check_binary
  34
+#   OCF_RESKEY_config
  35
+#   OCF_RESKEY_user
  36
+#   OCF_RESKEY_group
  37
+#   OCF_RESKEY_log
  38
+#   OCF_RESKEY_pid
  39
+#   OCF_RESKEY_tmp
  40
+#######################################################################
  41
+# Initialization:
  42
+
  43
+: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
  44
+. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
  45
+
  46
+#######################################################################
  47
+PATH=$PATH:/usr/local/bin:/usr/local/sbin
  48
+
  49
+# Fill in some defaults if no values are specified
  50
+OCF_RESKEY_binary_default=redis-server
  51
+OCF_RESKEY_client_binary_default=redis-cli
  52
+OCF_RESKEY_aof_check_binary_default=redis-check-aof
  53
+OCF_RESKEY_config_default=/etc/redis/redis.conf
  54
+OCF_RESKEY_user_default=redis
  55
+OCF_RESKEY_group_default=redis
  56
+OCF_RESKEY_log_default=/var/log/redis/redis-server.log
  57
+OCF_RESKEY_pid_default=/var/run/redis.pid
  58
+OCF_RESKEY_tmp_default=/var/run/
  59
+
  60
+: ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}}
  61
+: ${OCF_RESKEY_client_binary=${OCF_RESKEY_client_binary_default}}
  62
+: ${OCF_RESKEY_aof_check_binary=${OCF_RESKEY_aof_check_binary_default}}
  63
+: ${OCF_RESKEY_config=${OCF_RESKEY_config_default}}
  64
+: ${OCF_RESKEY_user=${OCF_RESKEY_user_default}}
  65
+: ${OCF_RESKEY_group=${OCF_RESKEY_group_default}}
  66
+: ${OCF_RESKEY_log=${OCF_RESKEY_log_default}}
  67
+: ${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}}
  68
+: ${OCF_RESKEY_tmp=${OCF_RESKEY_tmp_default}}
  69
+
  70
+REDIS_SERVER_NAME=${OCF_RESOURCE_INSTANCE}
  71
+: ${REDIS_SERVER_NAME=${OCF_RESKEY_binary}}
  72
+
  73
+#######################################################################
  74
+
  75
+usage() {
  76
+  cat <<UEND
  77
+    usage: $0 (start|stop|validate-all|meta-data|monitor|promote|demote|notify)
  78
+
  79
+    $0 manages redis as an HA resource.
  80
+
  81
+    The 'start' operation starts redis.
  82
+    The 'stop' operation stops redis.
  83
+    The 'status' operation reports whether redis is running
  84
+    The 'monitor' operation reports whether redis seems to be working
  85
+    The 'promote' operation makes this redis instance run as master
  86
+    The 'demote' operation makes this redis instance run as slave
  87
+    The 'validate-all' operation reports whether the parameters are valid
  88
+
  89
+UEND
  90
+}
  91
+
  92
+meta_data() {
  93
+    cat <<END
  94
+<?xml version="1.0"?>
  95
+<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
  96
+<resource-agent name="redis">
  97
+<version>1.0</version>
  98
+
  99
+<longdesc lang="en">
  100
+Resource script for redis. 
  101
+It manages a redis instance as an HA resource.
  102
+</longdesc>
  103
+<shortdesc lang="en">Manages a redis instance</shortdesc>
  104
+
  105
+<parameters>
  106
+
  107
+<parameter name="binary" unique="0" required="0">
  108
+<longdesc lang="en">
  109
+Name of the redis server binary. Use an absolute path if the binary is not resolvable via \$PATH
  110
+</longdesc>
  111
+<shortdesc lang="en">redis binary</shortdesc>
  112
+<content type="string" default="${OCF_RESKEY_binary_default}" />
  113
+</parameter>
  114
+
  115
+<parameter name="client_binary" unique="0" required="0">
  116
+<longdesc lang="en">
  117
+Name of the redis client binary. Use an absolute path if the binary is not resolvable via \$PATH
  118
+</longdesc>
  119
+<shortdesc lang="en">redis client binary</shortdesc>
  120
+<content type="string" default="${OCF_RESKEY_client_binary_default}" />
  121
+</parameter>
  122
+
  123
+<parameter name="aof_check_binary" unique="0" required="0">
  124
+<longdesc lang="en">
  125
+Name of the redis aof-check binary. Use an absolute path if the binary is not resolvable via \$PATH
  126
+</longdesc>
  127
+<shortdesc lang="en">redis aof-check binary</shortdesc>
  128
+<content type="string" default="${OCF_RESKEY_aof_check_binary_default}" />
  129
+</parameter>
  130
+
  131
+<parameter name="config" unique="0" required="0">
  132
+<longdesc lang="en">
  133
+Location of the Redis configuration file
  134
+</longdesc>
  135
+<shortdesc lang="en">redis config</shortdesc>
  136
+<content type="string" default="${OCF_RESKEY_config_default}" />
  137
+</parameter>
  138
+
  139
+<parameter name="user" unique="0" required="0">
  140
+<longdesc lang="en">
  141
+User running redis
  142
+</longdesc>
  143
+<shortdesc lang="en">redis user</shortdesc>
  144
+<content type="string" default="${OCF_RESKEY_user_default}" />
  145
+</parameter>
  146
+
  147
+<parameter name="group" unique="0" required="0">
  148
+<longdesc lang="en">
  149
+Group running redis (for logfile and directory permissions)
  150
+</longdesc>
  151
+<shortdesc lang="en">redis group</shortdesc>
  152
+<content type="string" default="${OCF_RESKEY_group_default}"/>
  153
+</parameter>
  154
+
  155
+<parameter name="log" unique="0" required="0">
  156
+<longdesc lang="en">
  157
+The logfile to be used for redis-server.
  158
+</longdesc>
  159
+<shortdesc lang="en">$REDIS_SERVER_NAME log file</shortdesc>
  160
+<content type="string" default="${OCF_RESKEY_log_default}"/>
  161
+</parameter>
  162
+
  163
+<parameter name="pid" unique="0" required="0">
  164
+<longdesc lang="en">
  165
+The pidfile to be used for redis-server.
  166
+</longdesc>
  167
+<shortdesc lang="en">$REDIS_SERVER_NAME pid file</shortdesc>
  168
+<content type="string" default="${OCF_RESKEY_pid_default}"/>
  169
+</parameter>
  170
+
  171
+<parameter name="tmp" unique="0" required="0">
  172
+<longdesc lang="en">
  173
+The tmpdir to be used for pacemaker managing.
  174
+</longdesc>
  175
+<shortdesc lang="en">pacemaker redis tmp file</shortdesc>
  176
+<content type="string" default="${OCF_RESKEY_tmp_default}"/>
  177
+</parameter>
  178
+
  179
+</parameters>
  180
+
  181
+<actions>
  182
+<action name="start" timeout="120" />
  183
+<action name="stop" timeout="120" />
  184
+<action name="status" timeout="60" />
  185
+<action name="monitor" depth="0" timeout="30" interval="20" />
  186
+<action name="monitor" role="Master" depth="0" timeout="30" interval="10" />
  187
+<action name="monitor" role="Slave" depth="0" timeout="30" interval="30" />
  188
+<action name="promote" timeout="120" />
  189
+<action name="demote" timeout="120" />
  190
+<action name="notify" timeout="90" />
  191
+<action name="validate-all" timeout="5" />
  192
+<action name="meta-data" timeout="5" />
  193
+</actions>
  194
+</resource-agent>
  195
+END
  196
+}
  197
+
  198
+#######################################################################
  199
+# Convenience variables
  200
+
  201
+CRM_MASTER="${HA_SBIN_DIR}/crm_master -l reboot "
  202
+
  203
+#######################################################################
  204
+
  205
+# Convenience functions
  206
+
  207
+config_get() {
  208
+    grep "^\s*$1\s" $OCF_RESKEY_config | awk '{print $2}' | tail -n1
  209
+}
  210
+
  211
+redis_cmd() {
  212
+    local userun
  213
+    local port
  214
+    local password
  215
+    userun=$1
  216
+    shift
  217
+    port=$(config_get port)
  218
+    password=$(config_get requirepass)
  219
+    if [ $userun -eq 0 ]; then
  220
+      $OCF_RESKEY_client_binary -p "$port" -a "$password" "$@"
  221
+      return $?
  222
+    else
  223
+      ocf_run -q $OCF_RESKEY_client_binary -p "$port" -a "$password" "$@"
  224
+      return $?
  225
+    fi
  226
+}
  227
+
  228
+read_ms_status() {
  229
+    local tmp
  230
+    local has_slave_role
  231
+    local master_host
  232
+    local master_host_value
  233
+    local should_be_slave
  234
+
  235
+    tmp=$(mktemp -p $HA_RSCTMP)
  236
+    redis_cmd 0 info >$tmp
  237
+    if [ $? -ne 0 ]; then
  238
+        ocf_log info "Could not determine master/slave status";
  239
+        rm -f $tmp
  240
+        return $OCF_ERR_GENERIC;
  241
+    fi
  242
+
  243
+    grep -e "role:slave" $tmp >/dev/null 2>&1
  244
+    has_slave_role=$?
  245
+
  246
+    master_host_value=""
  247
+    master_host=$(grep -e "master_host:" $tmp)
  248
+    if [ $? -eq 0 ]; then
  249
+        master_host_value=$(echo $master_host | cut -d':' -f2 | tr -d " ")
  250
+    fi
  251
+
  252
+    test_slave
  253
+    should_be_slave=$?
  254
+
  255
+    rm -f $tmp
  256
+
  257
+    if [ $has_slave_role -eq 0 -a "x$master_host_value" != "x"  ]; then
  258
+        ocf_log info "$REDIS_SERVER_NAME is running (as slave)";
  259
+        return $OCF_SUCCESS;
  260
+    elif [ $should_be_slave -eq 0 ]; then
  261
+        ocf_log info "$REDIS_SERVER_NAME is running (as master, becoming slave when possible)";
  262
+        return $OCF_SUCCESS;
  263
+    else
  264
+        ocf_log info "$REDIS_SERVER_NAME is running (as master)";
  265
+        return $OCF_RUNNING_MASTER;
  266
+    fi
  267
+}
  268
+
  269
+read_pid() {
  270
+    pid=""
  271
+
  272
+    if [ -e $OCF_RESKEY_pid ]; then
  273
+        pid=$(cat $OCF_RESKEY_pid);
  274
+    fi
  275
+
  276
+    if [ $? -ne 0 -o "x$pid" = "x" ]; then
  277
+        pid=$(pidof -s $OCF_RESKEY_binary)
  278
+    fi
  279
+
  280
+    if [ $? -eq 0 -a "x$pid" != "x" ]; then
  281
+        kill -0 $pid
  282
+    fi
  283
+
  284
+    if [ $? -ne 0 -o "x$pid" = "x" ]; then
  285
+        ocf_log info "Could not read PID, $REDIS_SERVER_NAME is not running";
  286
+        return $OCF_NOT_RUNNING
  287
+    else
  288
+        ocf_log info "$REDIS_SERVER_NAME is running (PID $pid)";
  289
+        return $OCF_SUCCESS
  290
+    fi
  291
+}
  292
+
  293
+remove_pid() {
  294
+    ocf_log debug "Removing PID file $OCF_RESKEY_pid"
  295
+    rm -f $OCF_RESKEY_pid
  296
+}
  297
+
  298
+mark_slave() {
  299
+    ocf_log info "Mark $OCF_RESOURCE_INSTANCE to be a slave";
  300
+    touch $OCF_RESKEY_tmp/$OCF_RESOURCE_INSTANCE.slave
  301
+}
  302
+
  303
+unmark_slave() {
  304
+    ocf_log info "Mark $OCF_RESOURCE_INSTANCE to be a master";
  305
+    rm -f $OCF_RESKEY_tmp/$OCF_RESOURCE_INSTANCE.slave
  306
+}
  307
+
  308
+test_slave() {
  309
+    [ -e $OCF_RESKEY_tmp/$OCF_RESOURCE_INSTANCE.slave ]
  310
+    return $?
  311
+}
  312
+
  313
+set_master() {
  314
+    local master_host=$1
  315
+    local port
  316
+    port=$(config_get port)
  317
+
  318
+    ocf_log info "Set $REDIS_SERVER_NAME to be a slave of $master_host";
  319
+    redis_cmd 1 slaveof $master_host $port
  320
+    return $?
  321
+}
  322
+
  323
+unset_master() {
  324
+    ocf_log info "Set $REDIS_SERVER_NAME to become a slave of no one";
  325
+    redis_cmd 1 slaveof no one
  326
+    return $?
  327
+}
  328
+
  329
+#######################################################################
  330
+
  331
+# Functions invoked by resource manager actions
  332
+
  333
+redis_validate() {
  334
+    check_binary $OCF_RESKEY_binary
  335
+    check_binary $OCF_RESKEY_client_binary
  336
+    check_binary start-stop-daemon
  337
+
  338
+    if [ ! -f $OCF_RESKEY_config ]; then
  339
+        ocf_log err "Config $OCF_RESKEY_config doesn't exist";
  340
+        return $OCF_ERR_INSTALLED;
  341
+    fi
  342
+
  343
+    getent passwd $OCF_RESKEY_user >/dev/null 2>&1
  344
+    if [ $? -ne 0 ]; then
  345
+        ocf_log err "User $OCF_RESKEY_user doesn't exit";
  346
+        return $OCF_ERR_INSTALLED;
  347
+    fi
  348
+
  349
+    getent group $OCF_RESKEY_group >/dev/null 2>&1
  350
+    if [ $? -ne 0 ]; then
  351
+        ocf_log err "Group $OCF_RESKEY_group doesn't exist";
  352
+        return $OCF_ERR_INSTALLED;
  353
+    fi
  354
+
  355
+    true
  356
+}
  357
+
  358
+redis_status() {
  359
+    local rc
  360
+
  361
+    read_pid
  362
+    rc=$?
  363
+    
  364
+    if [ $rc -ne $OCF_SUCCESS ]; then
  365
+        ocf_log err "Removing PID"
  366
+        remove_pid
  367
+        return $rc
  368
+    fi
  369
+
  370
+    read_ms_status
  371
+    rc=$?
  372
+    if ocf_is_ms; then
  373
+        return $rc
  374
+    else
  375
+        if [ $rc -eq $OCF_SUCCESS -o $rc -eq $OCF_RUNNING_MASTER ]; then
  376
+            ocf_log info "Redis is running"
  377
+            return $OCF_SUCCESS
  378
+        else
  379
+            return $OCF_ERR_GENERIC
  380
+        fi
  381
+    fi
  382
+}
  383
+
  384
+redis_start() {
  385
+
  386
+    local master_host
  387
+    local rc
  388
+    local append
  389
+    local appendfilename
  390
+
  391
+    redis_status
  392
+    rc=$?
  393
+
  394
+    if [ $rc -eq $OCF_RUNNING_MASTER -o $rc -eq $OCF_SUCCESS ]; then
  395
+        ocf_log info "$REDIS_SERVER_NAME is already running"
  396
+    else
  397
+       touch $OCF_RESKEY_log
  398
+       chown $OCF_RESKEY_user:$OCF_RESKEY_group $OCF_RESKEY_log
  399
+       chmod 0640 $OCF_RESKEY_log
  400
+   
  401
+       touch $OCF_RESKEY_pid
  402
+       chown $OCF_RESKEY_user:$OCF_RESKEY_group $OCF_RESKEY_pid
  403
+  
  404
+       # repair AOF
  405
+       append=$(config_get appendonly)
  406
+       if [ -n "$append" -a "$append" = "yes" ]; then
  407
+         appendfilename=$(config_get appendfilename)
  408
+         if [ -z "$appendfilename" ]; then
  409
+           appendfilename="appendonly.aof"
  410
+         fi
  411
+         if [ "{$appendfilename:0:1}" != "/" ]; then
  412
+           appendfilename="$(config_get dir)/${appendfilename}"
  413
+         fi
  414
+         rc=0
  415
+         if [ -e "$appendfilename" ]; then
  416
+           ocf_log info "Redis is using $appendfilename as appendfilename"
  417
+           ocf_run -q $OCF_RESKEY_aof_check_binary "$appendfilename"
  418
+           rc=$?
  419
+         fi
  420
+         if [ $rc -ne 0 ]; then
  421
+           ocf_log warn "Redis needs to fix $appendfilename"
  422
+           echo y | $OCF_RESKEY_aof_check_binary --fix "$appendfilename"
  423
+         fi
  424
+       fi
  425
+ 
  426
+       start-stop-daemon --start --quiet --umask 007 --pidfile $OCF_RESKEY_pid --make-pidfile --chuid $OCF_RESKEY_user:$OCF_RESKEY_group --exec $(which $OCF_RESKEY_binary) -- $OCF_RESKEY_config
  427
+       rc=$?
  428
+   
  429
+       if [ $rc -ne 0 ]; then
  430
+           ocf_log err "$OCF_RESKEY_binary start command failed: $rc"
  431
+           return $OCF_NOT_RUNNING
  432
+       fi
  433
+
  434
+       ocf_log info "$REDIS_SERVER_NAME started"
  435
+    fi
  436
+
  437
+    # wait for redis to actually open the tcp port
  438
+    # as redis starts but does not open this port if db files are corrupt
  439
+    for i in $(seq 1 5); do
  440
+        redis_cmd 0 info >/dev/null
  441
+        if [ $? -eq 0 ]; then
  442
+            break
  443
+        fi
  444
+        sleep 1
  445
+    done
  446
+    redis_cmd 1 info >/dev/null
  447
+    if [ $? -ne 0 ]; then
  448
+        return $OCF_ERR_GENERIC
  449
+    fi
  450
+
  451
+    if ocf_is_ms; then
  452
+        # Now, let's see whether there is a master. We might be a new
  453
+        # node that is just joining the cluster, and the CRM may have
  454
+        # promoted a master before.
  455
+        master_host=$(echo $OCF_RESKEY_CRM_meta_notify_master_uname | tr -d " ")
  456
+        if [ ! -z "$master_host" -a "$master_host" != $(uname -n) ]; then
  457
+            ocf_log info "Changing redis configuration to replicate from host: $master_host"
  458
+            while true; do
  459
+                redis_cmd 0 info |grep 'loading:0'
  460
+                if [ $? -eq 0 ]; then
  461
+                    break
  462
+                else
  463
+                    ocf_log err "Redis still loading data, giving it a second to finish"
  464
+                    sleep 1
  465
+                fi
  466
+            done
  467
+            set_master $master_host
  468
+        fi
  469
+        mark_slave
  470
+
  471
+        # We also need to set a master preference, otherwise Pacemaker
  472
+        # won't ever promote us in the absence of any explicit
  473
+        # preference set by the administrator. We choose a low
  474
+        # greater-than-zero preference.
  475
+        $CRM_MASTER -v 1
  476
+    fi
  477
+
  478
+    return $OCF_SUCCESS
  479
+}
  480
+
  481
+redis_stop() {
  482
+    local rc
  483
+
  484
+    if ocf_is_ms; then
  485
+        # clear preference for becoming master
  486
+        $CRM_MASTER -D
  487
+    fi
  488
+
  489
+    redis_status
  490
+    rc=$?
  491
+
  492
+    if [ $rc -ne $OCF_RUNNING_MASTER -a $rc -ne $OCF_SUCCESS ]; then
  493
+        ocf_log info "$REDIS_SERVER_NAME is not running";
  494
+        return $OCF_SUCCESS
  495
+    fi
  496
+
  497
+    start-stop-daemon --stop --retry 10 --quiet --oknodo --pidfile $OCF_RESKEY_pid
  498
+    rc=$?
  499
+
  500
+    if [ $rc -ne 0 ]; then
  501
+        ocf_log err "$OCF_RESKEY_binary stop command failed: $rc"
  502
+        return $OCF_ERR_GENERIC
  503
+    fi
  504
+
  505
+    ocf_log info "$REDIS_SERVER_NAME stopped";
  506
+    remove_pid
  507
+    unmark_slave
  508
+    return $OCF_SUCCESS
  509
+}
  510
+
  511
+redis_promote() {
  512
+    local rc
  513
+
  514
+    redis_status
  515
+    rc=$?
  516
+
  517
+    if [ $rc -ne $OCF_RUNNING_MASTER -a $rc -ne $OCF_SUCCESS ]; then
  518
+        return $OCF_NOT_RUNNING
  519
+    fi
  520
+
  521
+    unmark_slave
  522
+    unset_master
  523
+
  524
+    # Existing master gets a higher-than-default master preference, so
  525
+    # the cluster manager does not shuffle the master role around
  526
+    # unnecessarily
  527
+    $CRM_MASTER -v 10000
  528
+
  529
+    return $OCF_SUCCESS
  530
+}
  531
+
  532
+redis_demote() {
  533
+    local rc
  534
+    local master_host
  535
+
  536
+    redis_status
  537
+    rc=$?
  538
+
  539
+    if [ $rc -ne $OCF_RUNNING_MASTER -a $rc -ne $OCF_SUCCESS ]; then
  540
+        return $OCF_NOT_RUNNING
  541
+    fi
  542
+
  543
+    # Now, let's see whether there is a master. We might be a new
  544
+    # node that is just joining the cluster, and the CRM may have
  545
+    # promoted a master before.
  546
+    master_host=$(echo $OCF_RESKEY_CRM_meta_notify_master_uname | tr -d " ")
  547
+    if [ ! -z "$master_host" -a "$master_host" != $(uname -n) ]; then
  548
+        ocf_log info "Changing redis configuration to replicate from host: $master_host"
  549
+        while true; do
  550
+            redis_cmd 0 info |grep 'loading:0'
  551
+            if [ $? -eq 0 ]; then
  552
+                break
  553
+            else
  554
+                ocf_log err "Redis still loading data, giving it a second to finish"
  555
+                sleep 1
  556
+            fi
  557
+        done
  558
+        set_master $master_host
  559
+    fi
  560
+    mark_slave
  561
+
  562
+    # Return master preference to default, so the cluster manager gets
  563
+    # a chance to select a new master
  564
+    $CRM_MASTER -v 1
  565
+
  566
+    return $OCF_SUCCESS
  567
+}
  568
+
  569
+redis_notify() {
  570
+    local rc
  571
+
  572
+    local master_host
  573
+    local type_op
  574
+   
  575
+    redis_status
  576
+    rc=$?
  577
+
  578
+    if [ $rc -ne $OCF_RUNNING_MASTER -a $rc -ne $OCF_SUCCESS ]; then
  579
+        return $OCF_NOT_RUNNING
  580
+    fi
  581
+
  582
+    # If not configured as a Stateful resource, we make no sense of
  583
+    # notifications.
  584
+    if ! ocf_is_ms; then
  585
+        ocf_log info "This agent makes no use of notifications unless running in master/slave mode."
  586
+        return $OCF_SUCCESS
  587
+    fi
  588
+
  589
+    type_op="${OCF_RESKEY_CRM_meta_notify_type}-${OCF_RESKEY_CRM_meta_notify_operation}"
  590
+    ocf_log debug "Received $type_op notification."
  591
+
  592
+    case "$type_op" in
  593
+    'pre-promote')
  594
+        # A node is about to being promoted to master.
  595
+        master_host=$(echo $OCF_RESKEY_CRM_meta_notify_promote_uname | tr -d " ")
  596
+        if [ -z "$master_host" ]; then
  597
+            ocf_log err "Unable to determine host to be promoted!"
  598
+            return $OCF_ERR_GENERIC
  599
+        fi
  600
+
  601
+        if [ $master_host = $(uname -n) ]; then
  602
+            ocf_log info "We are about to being promoted."
  603
+            return $OCF_SUCCESS
  604
+        fi
  605
+
  606
+        ocf_log info "Becoming a slave of $master_host"
  607
+        set_master $master_host
  608
+        if [ $? -ne 0 ]; then
  609
+            return $OCF_ERR_GENERIC
  610
+        else
  611
+            return $OCF_SUCCESS
  612
+        fi
  613
+    ;;
  614
+    'pre-demote')
  615
+        # A master is about to being demoted.
  616
+        demote_host=$(echo $OCF_RESKEY_CRM_meta_notify_demote_uname | tr -d " ")
  617
+        if [ -z "$demote_host" ]; then
  618
+            ocf_log err "Unable to determine host to be demoted!"
  619
+            return $OCF_ERR_GENERIC
  620
+        fi
  621
+
  622
+        if [ $demote_host = $(uname -n) ]; then
  623
+            ocf_log info "We are about to being demoted."
  624
+            return $OCF_SUCCESS
  625
+        fi
  626
+        
  627
+        ocf_log info "Deslaving from $demote_host."
  628
+        unset_master
  629
+        return $OCF_SUCCESS
  630
+        ;;
  631
+    *)
  632
+        return $OCF_SUCCESS
  633
+        ;;
  634
+    esac
  635
+}
  636
+
  637
+#######################################################################
  638
+
  639
+# Make sure meta-data and usage always succeed
  640
+case $__OCF_ACTION in
  641
+meta-data) meta_data
  642
+                exit $OCF_SUCCESS
  643
+                ;;
  644
+usage|help) usage
  645
+                exit $OCF_SUCCESS
  646
+                ;;
  647
+esac
  648
+
  649
+# Anything other than meta-data and usage must pass validation
  650
+redis_validate || exit $?
  651
+
  652
+# Translate each action into the appropriate function call
  653
+case $__OCF_ACTION in
  654
+start)          redis_start;;
  655
+stop)           redis_stop;;
  656
+status|monitor) redis_status;;
  657
+promote)        redis_promote;;
  658
+demote)         redis_demote;;
  659
+notify)             redis_notify;;
  660
+validate-all)   ;;
  661
+*)             usage
  662
+                exit $OCF_ERR_UNIMPLEMENTED
  663
+                ;;
  664
+esac
  665
+rc=$?
  666
+
  667
+# The resource agent may optionally log a debug message
  668
+ocf_log debug "${OCF_RESOURCE_INSTANCE} $__OCF_ACTION returned $rc"
  669
+exit $rc
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.