ctdb-tests: New function ctdb_set_pnn() to change PNN
[Samba.git] / ctdb / tests / eventscripts / stubs / ctdb
blobaa3ac730ddf8039fe38460725007c6946934db44
1 #!/bin/sh
3 prog="ctdb"
5 # Print a message and exit.
6 die ()
8 echo "$1" >&2 ; exit ${2:-1}
11 not_implemented_exit_code=1
13 usage ()
15 cat >&2 <<EOF
16 Usage: $prog [-X] cmd
18 A fake CTDB stub that prints items depending on the variables
19 FAKE_CTDB_PNN (default 0) depending on command-line options.
20 EOF
21 exit 1
24 not_implemented ()
26 echo "${prog}: command \"$1\" not implemented in stub" >&2
27 exit $not_implemented_exit_code
30 # Don't set $POSIXLY_CORRECT here.
31 _temp=$(getopt -n "$prog" -o "Xvhn:" -l help -- "$@") || \
32 usage
34 eval set -- "$_temp"
36 verbose=false
37 machine_readable=false
38 nodespec=""
40 args="$*"
42 while true ; do
43 case "$1" in
44 -X) machine_readable=true ; shift ;;
45 -v) verbose=true ; shift ;;
46 -n) nodespec="$2" ; shift 2 ;;
47 --) shift ; break ;;
48 -h|--help|*) usage ;; # * shouldn't happen, so this is reasonable.
49 esac
50 done
52 [ $# -ge 1 ] || usage
54 setup_tickles ()
56 # Make sure tickles file exists.
57 tickles_file="$EVENTSCRIPTS_TESTS_VAR_DIR/fake-ctdb/tickles"
58 mkdir -p $(dirname "$tickles_file")
59 touch "$tickles_file"
62 ctdb_killtcp ()
64 while read _src _dst ; do
65 sed -i -e "/^$_dst $_src\$/d" "$FAKE_NETSTAT_TCP_ESTABLISHED_FILE"
66 done
69 parse_nodespec ()
71 if [ "$nodespec" = "all" ] ; then
72 nodes="$(seq 0 $((FAKE_CTDB_NUMNODES - 1)) )"
73 elif [ -n "$nodespec" ] ; then
74 nodes="$(echo $nodespec | sed -e 's@,@ @g')"
75 else
76 _t=$(ctdb_pnn)
77 nodes="${_t#PNN:}"
81 # For testing backward compatibility...
82 for i in $CTDB_NOT_IMPLEMENTED ; do
83 if [ "$i" = "$1" ] ; then
84 not_implemented "$i"
86 done
88 ctdb_pnn ()
90 # Defaults to 0
91 echo "PNN:${FAKE_CTDB_PNN:-0}"
94 ######################################################################
96 FAKE_CTDB_NODE_STATE="$FAKE_CTDB_STATE/node-state"
97 FAKE_CTDB_NODES_DISABLED="$FAKE_CTDB_NODE_STATE/0x4"
99 ######################################################################
101 # NOTE: all nodes share $CTDB_PUBLIC_ADDRESSES
103 FAKE_CTDB_IP_LAYOUT="$FAKE_CTDB_STATE/ip-layout"
105 ip_reallocate ()
107 touch "$FAKE_CTDB_IP_LAYOUT"
110 flock 0
112 _pa="${CTDB_PUBLIC_ADDRESSES:-${CTDB_BASE}/public_addresses}"
114 if [ ! -s "$FAKE_CTDB_IP_LAYOUT" ] ; then
115 sed -n -e 's@^\([^#][^/]*\)/.*@\1 -1@p' \
116 "$_pa" >"$FAKE_CTDB_IP_LAYOUT"
119 _t="${FAKE_CTDB_IP_LAYOUT}.new"
121 _flags=""
122 for _i in $(seq 0 $((FAKE_CTDB_NUMNODES - 1)) ) ; do
123 if ls "$FAKE_CTDB_STATE/node-state/"*"/$_i" >/dev/null 2>&1 ; then
124 # Have non-zero flags
125 _this=0
126 for _j in "$FAKE_CTDB_STATE/node-state/"*"/$_i" ; do
127 _tf="${_j%/*}" # dirname
128 _f="${_tf##*/}" # basename
129 _this=$(( $_this | $_f ))
130 done
131 else
132 _this="0"
134 _flags="${_flags}${_flags:+,}${_this}"
135 done
136 CTDB_TEST_LOGLEVEL=2 \
137 "ctdb_takeover_tests" \
138 "ctdb_takeover_run_core" "$_flags" <"$FAKE_CTDB_IP_LAYOUT" |
139 sort >"$_t"
140 mv "$_t" "$FAKE_CTDB_IP_LAYOUT"
141 ) <"$FAKE_CTDB_IP_LAYOUT"
144 ctdb_ip ()
146 # If nobody has done any IP-fu then generate a layout.
147 [ -f "$FAKE_CTDB_IP_LAYOUT" ] || ip_reallocate
149 _mypnn=$(ctdb_pnn | sed -e 's@PNN:@@')
151 if $machine_readable ; then
152 if $verbose ; then
153 echo "|Public IP|Node|ActiveInterface|AvailableInterfaces|ConfiguredInterfaces|"
154 else
155 echo "|Public IP|Node|"
157 else
158 echo "Public IPs on node ${_mypnn}"
161 # Join public addresses file with $FAKE_CTDB_IP_LAYOUT, and
162 # process output line by line...
163 _pa="${CTDB_PUBLIC_ADDRESSES:-${CTDB_BASE}/public_addresses}"
164 sed -e 's@/@ @' "$_pa" | sort | join - "$FAKE_CTDB_IP_LAYOUT" |
165 while read _ip _bit _ifaces _pnn ; do
166 if $verbose ; then
167 # If more than 1 interface, assume all addresses are on the 1st.
168 _first_iface="${_ifaces%%,*}"
169 # Only show interface if address is on this node.
170 _my_iface=""
171 if [ "$_pnn" = "$_mypnn" ]; then
172 _my_iface="$_first_iface"
174 if $machine_readable ; then
175 echo "|${_ip}|${_pnn}|${_my_iface}|${_first_iface}|${_ifaces}|"
176 else
177 echo "${_ip} node[${_pnn}] active[${_my_iface}] available[${_first_iface}] configured[[${_ifaces}]"
179 else
180 if $machine_readable ; then
181 echo "|${_ip}|${_pnn}|"
182 else
183 echo "${_ip} ${_pnn}"
186 done
189 ctdb_moveip ()
191 _ip="$1"
192 _target="$2"
194 ip_reallocate # should be harmless and ensures we have good state
197 flock 0
199 _t="${FAKE_CTDB_IP_LAYOUT}.new"
201 while read _i _pnn ; do
202 if [ "$_ip" = "$_i" ] ; then
203 echo "$_ip $_target"
204 else
205 echo "$_ip $_pnn"
207 done | sort >"$_t"
208 mv "$_t" "$FAKE_CTDB_IP_LAYOUT"
209 ) <"$FAKE_CTDB_IP_LAYOUT"
212 ######################################################################
214 ctdb_enable ()
216 parse_nodespec
218 for _i in $nodes ; do
219 rm -f "${FAKE_CTDB_NODES_DISABLED}/${_i}"
220 done
222 ip_reallocate
225 ctdb_disable ()
227 parse_nodespec
229 for _i in $nodes ; do
230 mkdir -p "$FAKE_CTDB_NODES_DISABLED"
231 touch "${FAKE_CTDB_NODES_DISABLED}/${_i}"
232 done
234 ip_reallocate
237 ######################################################################
239 ctdb_shutdown ()
241 echo "CTDB says BYE!"
244 ######################################################################
246 FAKE_CTDB_NATGW_STATE="${FAKE_CTDB_STATE}/natgw_state"
248 ctdb_setnatgwstate ()
250 echo "$2" >"$FAKE_CTDB_NATGW_STATE"
253 ctdb_natgwlist ()
255 [ -r "$CTDB_NATGW_NODES" ] || \
256 die "error: missing CTDB_NATGW_NODES=${CTDB_NATGW_NODES}"
258 # Determine if the current node has the (fake) NAT gateway
259 # capability. This is only used to make sure tests are sane and
260 # don't try to use inconsistent setup.
261 if [ -r "$FAKE_CTDB_NATGW_STATE" ] ; then
262 read _state <"$FAKE_CTDB_NATGW_STATE"
263 else
264 _state="off"
267 # Determine the master node
268 _master="-1 0.0.0.0"
269 _pnn=0
270 while read _ip ; do
271 if [ "$FAKE_CTDB_NATGW_MASTER" = "$_ip" ] ; then
272 _master="${_pnn} ${_ip}"
273 if [ "$_pnn" = "$FAKE_CTDB_PNN" -a "$_state" = "off" ] ; then
274 die "Inconsistent test configuration - master node is slave-only"
276 break
278 _pnn=$(($_pnn + 1))
279 done <"$CTDB_NATGW_NODES"
280 echo "$_master"
282 # Now print the node information - it is clearer to do this in a
283 # second pass. Any nodes before the master that have state not
284 # "off" are tagged as unhealthy, just so the output makes some
285 # sense.
286 _pnn=0
287 _found_master=false
288 while read _ip ; do
289 if [ "$FAKE_CTDB_NATGW_MASTER" = "$_ip" ] ; then
290 _found_master=true
292 if $_found_master ; then
293 _outstate="HEALTHY"
294 else
295 if [ $FAKE_CTDB_PNN -eq $_pnn -a "$_state" = "off" ] ; then
296 _outstate="HEALTHY"
297 else
298 _outstate="UNHEALTHY"
301 if [ $FAKE_CTDB_PNN -eq $_pnn ] ; then
302 _outstate="${_outstate} (THIS NODE)"
304 printf "pnn:%d %-16s ${_outstate}\n" $_pnn "$_ip"
306 _pnn=$(($_pnn + 1))
307 done <"$CTDB_NATGW_NODES"
311 ######################################################################
313 ctdb_setvar ()
315 shift
316 _var="$1"
318 for _i in $FAKE_CTDB_TUNABLES_OK ; do
319 if [ "$_var" = "$_i" ] ; then
320 return 0
322 done
324 for _i in $FAKE_CTDB_TUNABLES_OBSOLETE ; do
325 if [ "$_var" = "$_i" ] ; then
326 echo "Setting obsolete tunable variable '${_var}'"
327 return 0
329 done
331 echo "Unable to set tunable variable '${_var}'"
332 return 1
335 ######################################################################
337 _t_setup ()
339 _t_dir="$EVENTSCRIPTS_TESTS_VAR_DIR/fake-ctdb/fake-tdb/$1"
340 mkdir -p "$_t_dir"
343 _t_put ()
345 echo "$2" >"${_t_dir}/$1"
348 _t_get ()
350 cat "${_t_dir}/$1"
353 _t_del ()
355 rm -f "${_t_dir}/$1"
358 ctdb_pstore ()
360 _t_setup "$2"
361 _t_put "$3" "$4"
364 ctdb_pdelete ()
366 _t_setup "$2"
367 _t_del "$3"
370 ctdb_pfetch ()
372 _t_setup "$2"
373 _t_get "$3" >"$4" 2>/dev/null
376 ctdb_ptrans ()
378 _t_setup "$2"
380 while IFS="" read _line ; do
381 _k=$(echo "$_line" | sed -n -e 's@^"\([^"]*\)" "[^"]*"$@\1@p')
382 _v=$(echo "$_line" | sed -e 's@^"[^"]*" "\([^"]*\)"$@\1@')
383 [ -n "$_k" ] || die "ctdb ptrans: bad line \"${line}\""
384 if [ -n "$_v" ] ; then
385 _t_put "$_k" "$_v"
386 else
387 _t_del "$_k"
389 done
392 ctdb_catdb ()
394 _t_setup "$2"
396 # This will break on keys with spaces but we don't have any of
397 # those yet.
398 _count=0
399 for _i in "${_t_dir}/"* ; do
400 [ -r "$_i" ] || continue
401 _k="${_i##*/}" # basename
402 _v=$(_t_get "$_k")
403 _kn=$(echo -n "$_k" | wc -c)
404 _vn=$(echo -n "$_v" | wc -c)
405 cat <<EOF
406 key(${_kn}) = "${_k}"
407 dmaster: 0
408 rsn: 1
409 data(${_vn}) = "${_v}"
412 _count=$(($_count + 1))
413 done
415 echo "Dumped ${_count} records"
418 ######################################################################
420 case "$1" in
421 gettickles)
422 setup_tickles
423 echo "|source ip|port|destination ip|port|"
424 while read src dst ; do
425 echo "|${src}|${dst}|"
426 done <"$tickles_file"
428 addtickle)
429 setup_tickles
430 echo "$2 $3" >>"$tickles_file"
432 deltickle)
433 setup_tickles
434 _t=$(grep -F -v "$2 $3" "$tickles_file")
435 echo "$_t" >"$tickles_file"
437 pstore) ctdb_pstore "$@" ;;
438 pdelete) ctdb_pdelete "$@" ;;
439 pfetch) ctdb_pfetch "$@" ;;
440 ptrans) ctdb_ptrans "$@" ;;
441 catdb) ctdb_catdb "$@" ;;
442 ifaces)
443 # Assume -Y.
444 echo "|Name|LinkStatus|References|"
445 _f="${CTDB_PUBLIC_ADDRESSES:-${CTDB_BASE}/public_addresses}"
446 if [ -r "$_f" ] ; then
447 while read _ip _iface ; do
448 case "_$ip" in
449 \#*) : ;;
451 _status=1
452 # For now assume _iface contains only 1.
453 if [ -f "{FAKE_CTDB_IFACES_DOWN}/${_iface}" ] ; then
454 _status=0
456 # Nobody looks at references
457 echo "|${_iface}|${_status}|0|"
458 esac
459 done <"$_f" |
460 sort -u
463 setifacelink)
464 # Existence of file means CTDB thinks interface is down.
465 _f="${FAKE_CTDB_IFACES_DOWN}/$2"
466 case "$3" in
467 up) rm -f "$_f" ;;
468 down) touch "$_f" ;;
470 echo "ctdb setifacelink: unsupported interface status $3"
471 exit 1
472 esac
474 checktcpport)
475 for _i in $FAKE_TCP_LISTEN ; do
476 if [ "$2" = "${_i##*:}" ] ; then
477 exit 98
479 done
481 exit 0
483 scriptstatus)
484 $machine_readable || not_implemented "$1, without -X"
485 [ "$2" != "all" ] || not_implemented "scriptstatus all"
486 # For now just assume everything is good.
487 echo "|Type|Name|Code|Status|Start|End|Error Output...|"
488 for _i in "$CTDB_BASE/events.d/"*.* ; do
489 _d1=$(date '+%s.%N')
490 _b="${_i##*/}" # basename
492 _f="$FAKE_CTDB_SCRIPTSTATUS/$_b"
493 if [ -r "$_f" ] ; then
494 read _code _status _err_out <"$_f"
495 else
496 _code="0"
497 _status="OK"
498 if [ ! -x "$_i" ] ; then
499 _status="DISABLED"
500 _code="-8"
502 _err_out=""
504 _d2=$(date '+%s.%N')
505 echo "|${2:-monitor}|${_b}|${_code}|${_status}|${_d1}|${_d2}|${_err_out}|"
506 done
508 gratiousarp) : ;; # Do nothing for now
509 killtcp) ctdb_killtcp "$@" ;;
510 ip) ctdb_ip "$@" ;;
511 pnn|xpnn) ctdb_pnn ;;
512 enable) ctdb_enable "$@";;
513 disable) ctdb_disable "$@";;
514 moveip) ctdb_moveip "$@";;
515 shutdown) ctdb_shutdown "$@";;
516 setnatgwstate) ctdb_setnatgwstate "$@" ;;
517 natgwlist) ctdb_natgwlist "$@" ;;
518 setvar) ctdb_setvar "$@" ;;
519 *) not_implemented "$1" ;;
520 esac