HighAvailability
Availability classes
Wiki EN Percentage calculation
HA mit Corosync and Pacemaker
Resource Agents
Debugging mit Commandline Wrapper
1 #!/bin/bash
2
3 AGENT=/usr/lib/ocf/resource.d/glusterfs/volume_new
4 [ -n $2 ] && AGENT="$2"
5
6 ACTION="$1"
7
8 #set -vx
9 [ -n "$ACTION" ] || exit 1
10
11
12 # /usr/lib/ocf/lib/heartbeat/ocf-shellfuncs
13 # /usr/lib/ocf/resource.d/heartbeat/.ocf-shellfuncs -> ../../lib/heartbeat/ocf-shellfuncs
14 # /usr/share/cluster/ocf-shellfuncs*
15
16
17 export OCF_ROOT="/usr/lib/ocf"
18 export OCF_RESKEY_binary="gluster"
19 export OCF_RESKEY_volname="ftp"
20 echo "LIST of return codes:"
21 grep '^OCF_' ${OCF_ROOT}/lib/heartbeat/ocf-returncodes
22
23 $AGENT $ACTION
GlusterFS
volume
Der resource-agent "ocf:glusterfs:volume" kann * nicht mit IP-Adressen umgehen * nicht mit geƤnderten Konfigurationsverzeichnissen des glusterd umgehen. (Ein workaround ist ein symlink - wer mag.)
Darum habe ich eine eigene Implementation des Skriptes geschrieben.
1 primitive p_glusterd ocf:glusterfs:glusterd \
2 params binary="glusterd" pid="/var/run/glusterd.pid"
3 primitive p_glusterfs_ftp ocf:glusterfs:volume_new \
4 params volname="ftp" glusterd_confdir="/var/lib/glusterd" \
5 op start timeout="20s" interval="0" \
6 op stop timeout="20s" interval="0" \
7 op monitor timeout="20s" interval="10s"
8 clone c_glusterd p_glusterd \
9 meta target-role="Started"
10 clone c_glusterfs_ftp p_glusterfs_ftp \
11 meta interleave="true" ordered="true" target-role="Started"
1 #!/bin/sh
2 #
3 # glusterd
4 #
5 # Description: Manages a glusterd server as a (typically cloned)
6 # HA resource
7 #
8 # Authors: Florian Haas (hastexo Professional Services GmbH)
9 #
10 # License: GNU General Public License (GPL)
11
12 #######################################################################
13 # Initialization:
14
15 : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
16 . ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
17
18 # Convenience variables
19 # When sysconfdir and localstatedir aren't passed in as
20 # configure flags, they're defined in terms of prefix
21 prefix=/usr
22 SHORTHOSTNAME=$(hostname -s)
23 IP_ADDRESSES="$(ip a show | grep inet | sed -r 's/^\s+inet6? //'|\
24 cut -f1 -d\ | grep -v -e '^127.0' -e '^::1/128'|\
25 sed -r 's#/.*$##'|tr '\n' ' ')"
26 #######################################################################
27
28 readonly OCF_RESKEY_binary_default="gluster"
29 #readonly OCF_RESKEY_glusterd_confdir_default="/etc/glusterd"
30 readonly OCF_RESKEY_glusterd_confdir_default="/var/lib/glusterd"
31
32 : ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}}
33 : ${OCF_RESKEY_glusterd_confdir=${OCF_RESKEY_glusterd_confdir_default}}
34
35 volume_meta_data() {
36 cat <<-EOF
37 <?xml version="1.0"?>
38 <!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
39 <resource-agent name="volume" version="0.1">
40 <version>0.1</version>
41 <longdesc lang="en">
42 Manages a GlusterFS volume and monitors its bricks. When a resource of
43 this type is configured as a clone (as is commonly the case), then it
44 must have clone ordering enabled.
45 </longdesc>
46 <shortdesc lang="en">Manages a GlusterFS volume</shortdesc>
47 <parameters>
48 <parameter name="binary">
49 <longdesc lang="en">
50 Name of the gluster executable. Specify a full absolute
51 path if the binary is not in your \$PATH.
52 </longdesc>
53 <shortdesc lang="en">gluster executable</shortdesc>
54 <content type="string" default="${OCF_RESKEY_binary_default}"/>
55 </parameter>
56 <parameter name="glusterd_confdir">
57 <longdesc lang="en">
58 Path to the configuration directory of glusterd.
59 </longdesc>
60 <shortdesc lang="en">glusterd config dir</shortdesc>
61 <content type="string" default="${OCF_RESKEY_glusterd_confdir_default}"/>
62 </parameter>
63 <parameter name="volname" required="1">
64 <longdesc lang="en">
65 The name of the volume to manage.
66 </longdesc>
67 <shortdesc lang="en">volume name</shortdesc>
68 <content type="string"/>
69 </parameter>
70 </parameters>
71 <actions>
72 <action name="meta-data" timeout="5" />
73 <action name="monitor" timeout="20" interval="10" />
74 <action name="reload" timeout="20" />
75 <action name="start" timeout="20" />
76 <action name="stop" timeout="20" />
77 <action name="validate-all" timeout="20" />
78 </actions>
79 </resource-agent>
80 EOF
81 }
82
83 volume_getdir() {
84 local VOLDIR
85 VOLDIR="${OCF_RESKEY_glusterd_confdir}/vols/${OCF_RESKEY_volname}"
86 ocf_log debug "VOLDIR \"$VOLDIR\""
87
88 [ -d ${VOLDIR} ] || return 1
89
90 echo "${VOLDIR}"
91 return 0
92 }
93
94 volume_getbricks() {
95 local BRICKS
96 local BRICKS_LOCAL
97 local INFOFILE
98 local VOLDIR
99
100 VOLDIR=$(volume_getdir)
101 INFOFILE="${VOLDIR}/info"
102
103 [ -e ${INFOFILE} ] || return 1
104
105 BRICKS=$(grep brick ${INFOFILE}|cut -f2 -d=)
106
107 for BRICK in $BRICKS; do
108 for ADDRESS in $SHORTHOSTNAME echo $IP_ADDRESSES; do
109 BRICK_LOCAL=$(echo $BRICK| grep "$ADDRESS")
110 if [ -n "$BRICK_LOCAL" ]; then
111 if [ -z "$BRICKS_LOCAL" ]; then
112 BRICKS_LOCAL="$BRICK_LOCAL"
113 else
114 BRICKS_LOCAL="$BRICKS_LOCAL $BRICK_LOCAL"
115 fi
116 fi
117 unset BRICK_LOCAL
118 done
119 done
120
121 ocf_log debug "BRICKS_LOCAL \"$BRICKS_LOCAL\""
122 echo $BRICKS_LOCAL
123
124 return 0
125 }
126
127 volume_getpids() {
128 local BRICK
129 local BRICKS
130 local PIDDIR
131 local PIDFILE
132 local VOLDIR
133
134 VOLDIR=$(volume_getdir)
135 BRICKS=$(volume_getbricks)
136 PIDDIR="${VOLDIR}/run"
137
138 ocf_log debug "BRICKS in getpids \"$BRICKS\""
139 for BRICK in ${BRICKS}; do
140 PIDFILE="$(echo "${PIDDIR}/${BRICK}.pid"|sed -r 's/://g')"
141 [ -e $PIDFILE ] || return 1
142 ocf_log debug "BRICK in getpids \"$BRICK\""
143 ocf_log debug "$(ls -l $PIDFILE)"
144 cat $PIDFILE
145 done
146
147 return 0
148 }
149
150 volume_start() {
151 # exit immediately if configuration is not valid
152 volume_validate_all || exit $?
153
154 # if resource is already running, bail out early
155 if volume_monitor; then
156 ocf_log info "Resource is already running"
157 return $OCF_SUCCESS
158 fi
159
160 # actually start up the resource here
161 ocf_run "$OCF_RESKEY_binary" \
162 volume start "$OCF_RESKEY_volname" force || exit $OCF_ERR_GENERIC
163
164 # After the resource has been started, check whether it started up
165 # correctly. If the resource starts asynchronously, the agent may
166 # spin on the monitor function here -- if the resource does not
167 # start up within the defined timeout, the cluster manager will
168 # consider the start action failed
169
170 while ! volume_monitor; do
171 ocf_log debug "Resource has not started yet, waiting"
172 sleep 1
173 done
174
175 # only return $OCF_SUCCESS if _everything_ succeeded as expected
176 return $OCF_SUCCESS
177 }
178
179 volume_stop() {
180 local RC
181 local PID
182
183 # exit immediately if configuration is not valid
184 volume_validate_all || exit $?
185
186 volume_monitor
187 RC=$?
188 case "$RC" in
189 "$OCF_SUCCESS")
190 # Currently running. Normal, expected behavior.
191 ocf_log debug "Resource is currently running" ;;
192 "$OCF_NOT_RUNNING")
193 # Currently not running. Nothing to do.
194 ocf_log info "Resource is already stopped"
195 return $OCF_SUCCESS ;;
196 esac
197
198 # actually shut down the resource here (make sure to immediately
199 # exit with an $OCF_ERR_ error code if anything goes seriously
200 # wrong)
201 PIDS=$(volume_getpids)
202 for PID in $PIDS; do
203 #echo -e 'y\n' | ocf_run "$OCF_RESKEY_binary" \
204 #volume stop "$OCF_RESKEY_volname" || exit $OCF_ERR_GENERIC
205 ocf_run kill -s TERM $PID
206 done
207
208 # After the resource has been stopped, check whether it shut down
209 # correctly. If the resource stops asynchronously, the agent may
210 # spin on the monitor function here -- if the resource does not
211 # shut down within the defined timeout, the cluster manager will
212 # consider the stop action failed
213 while volume_monitor; do
214 ocf_log debug "Resource has not stopped yet, waiting"
215 sleep 1
216 done
217
218 # only return $OCF_SUCCESS if _everything_ succeeded as expected
219 return $OCF_SUCCESS
220 }
221
222 volume_monitor() {
223 local PID
224
225 PIDS=$(volume_getpids) || return $OCF_NOT_RUNNING
226
227 for PID in $PIDS; do
228 ocf_run kill -s 0 $PID || return $OCF_NOT_RUNNING
229 done
230
231 ocf_log debug "Local bricks for volume \"${OCF_RESKEY_volname}\""\
232 " running with PIDs $PIDS"
233 return $OCF_SUCCESS
234 }
235
236 volume_validate_all() {
237 # Test for configuration errors first
238 if [ -z "${OCF_RESKEY_volname}" ]; then
239 ocf_log err 'Missing required parameter "volname"'
240 return $OCF_ERR_CONFIGURED
241 fi
242
243 # Test for required binaries
244 check_binary $OCF_RESKEY_binary
245
246 return $OCF_SUCCESS
247 }
248
249
250 # Make sure meta-data and usage always succeed
251 case $__OCF_ACTION in
252 meta-data) volume_meta_data
253 exit $OCF_SUCCESS ;;
254 usage|help) volume_usage
255 exit $OCF_SUCCESS ;;
256 esac
257
258 # Anything other than meta-data and usage must pass validation
259 volume_validate_all || exit $?
260
261 # Translate each action into the appropriate function call
262 case $__OCF_ACTION in
263 start) volume_start;;
264 stop) volume_stop;;
265 status|monitor) volume_monitor;;
266 reload) ocf_log info "Reloading..."
267 volume_start
268 ;;
269 validate-all) ;;
270 notify) exit $OCF_SUCCESS;;
271 *) volume_usage
272 exit $OCF_ERR_UNIMPLEMENTED
273 ;;
274 esac
275 RC=$?
276
277 # The resource agent may optionally log a debug message
278 ocf_log debug "${OCF_RESOURCE_INSTANCE} $__OCF_ACTION returned $RC"
279 exit $RC
280
281 # vim: tabstop=8:
282