ctdb-tools: Drop support for setting and viewing NAT gateway capability
[ambi/samba-autobuild/.git] / ctdb / tests / eventscripts / stubs / ctdb
1 #!/bin/sh
2
3 prog="ctdb"
4
5 # Print a message and exit.
6 die ()
7 {
8     echo "$1" >&2 ; exit ${2:-1}
9 }
10
11 not_implemented_exit_code=1
12
13 usage ()
14 {
15     cat >&2 <<EOF
16 Usage: $prog [-X] cmd
17
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
22 }
23
24 not_implemented ()
25 {
26     echo "${prog}: command \"$1\" not implemented in stub" >&2
27     exit $not_implemented_exit_code
28 }
29
30 # Don't set $POSIXLY_CORRECT here.
31 _temp=$(getopt -n "$prog" -o "Xvhn:" -l help -- "$@") || \
32     usage
33
34 eval set -- "$_temp"
35
36 verbose=false
37 machine_readable=false
38 nodespec=""
39
40 args="$*"
41
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
51
52 [ $# -ge 1 ] || usage
53
54 setup_tickles ()
55 {
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"
60 }
61
62 ctdb_killtcp ()
63 {
64     while read _src _dst ; do
65         sed -i -e "/^$_dst $_src\$/d" "$FAKE_NETSTAT_TCP_ESTABLISHED_FILE"
66     done
67 }
68
69 parse_nodespec ()
70 {
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:}"
78     fi
79 }
80
81 # For testing backward compatibility...
82 for i in $CTDB_NOT_IMPLEMENTED ; do
83     if [ "$i" = "$1" ] ; then
84         not_implemented "$i"
85     fi
86 done
87
88 ctdb_pnn ()
89 {
90     # Defaults to 0
91     echo "PNN:${FAKE_CTDB_PNN:-0}"
92 }
93
94 ######################################################################
95
96 FAKE_CTDB_NODE_STATE="$FAKE_CTDB_STATE/node-state"
97 FAKE_CTDB_NODES_DISABLED="$FAKE_CTDB_NODE_STATE/0x4"
98
99 ######################################################################
100
101 # NOTE: all nodes share $CTDB_PUBLIC_ADDRESSES
102
103 FAKE_CTDB_IP_LAYOUT="$FAKE_CTDB_STATE/ip-layout"
104
105 ip_reallocate ()
106 {
107     touch "$FAKE_CTDB_IP_LAYOUT"
108
109     (
110         flock 0
111
112         _pa="${CTDB_PUBLIC_ADDRESSES:-${CTDB_BASE}/public_addresses}"
113
114         if [ ! -s "$FAKE_CTDB_IP_LAYOUT" ] ; then
115             sed -n -e 's@^\([^#][^/]*\)/.*@\1 -1@p' \
116                 "$_pa" >"$FAKE_CTDB_IP_LAYOUT"
117         fi
118
119         _t="${FAKE_CTDB_IP_LAYOUT}.new"
120
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"
133             fi
134             _flags="${_flags}${_flags:+,}${_this}"
135         done
136         CTDB_TEST_LOGLEVEL=2 \
137             "ctdb_takeover_tests" \
138             "ipalloc" "$_flags" <"$FAKE_CTDB_IP_LAYOUT" |
139             sort >"$_t"
140         mv "$_t" "$FAKE_CTDB_IP_LAYOUT"
141     ) <"$FAKE_CTDB_IP_LAYOUT"
142 }
143
144 ctdb_ip ()
145 {
146     # If nobody has done any IP-fu then generate a layout.
147     [ -f "$FAKE_CTDB_IP_LAYOUT" ] || ip_reallocate
148
149     _mypnn=$(ctdb_pnn | sed -e 's@PNN:@@')
150
151     if $machine_readable ; then
152         if $verbose ; then
153             echo "|Public IP|Node|ActiveInterface|AvailableInterfaces|ConfiguredInterfaces|"
154         else
155             echo "|Public IP|Node|"
156         fi
157     else
158         echo "Public IPs on node ${_mypnn}"
159     fi
160
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"
173             fi
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}]"
178             fi
179         else
180             if $machine_readable ; then
181                 echo "|${_ip}|${_pnn}|"
182             else
183                 echo "${_ip} ${_pnn}"
184             fi
185         fi
186     done
187 }
188
189 ctdb_moveip ()
190 {
191     _ip="$1"
192     _target="$2"
193
194     ip_reallocate  # should be harmless and ensures we have good state
195
196     (
197         flock 0
198
199         _t="${FAKE_CTDB_IP_LAYOUT}.new"
200
201         while read _i _pnn ; do
202             if [ "$_ip" = "$_i" ] ; then
203                 echo "$_ip $_target"
204             else
205                 echo "$_ip $_pnn"
206             fi
207         done | sort >"$_t"
208         mv "$_t" "$FAKE_CTDB_IP_LAYOUT"
209     ) <"$FAKE_CTDB_IP_LAYOUT"
210 }
211
212 ######################################################################
213
214 ctdb_enable ()
215 {
216     parse_nodespec
217     
218     for _i in $nodes ; do
219         rm -f "${FAKE_CTDB_NODES_DISABLED}/${_i}"
220     done
221
222     ip_reallocate
223 }
224
225 ctdb_disable ()
226 {
227     parse_nodespec
228
229     for _i in $nodes ; do
230         mkdir -p "$FAKE_CTDB_NODES_DISABLED"
231         touch "${FAKE_CTDB_NODES_DISABLED}/${_i}"
232     done
233
234     ip_reallocate
235 }
236
237 ######################################################################
238
239 ctdb_shutdown ()
240 {
241     echo "CTDB says BYE!"
242 }
243
244 ######################################################################
245
246 # This is only used by the NAT gateway code at the moment, so use a
247 # hack.  Assume that $CTDB_NATGW_NODES contains all nodes in the
248 # cluster (which is what current tests assume).  Use the PNN to find
249 # the address from this file.  The NAT gateway code only used the
250 # address, so just mark the node healthy.
251 ctdb_nodestatus ()
252 {
253     echo '|Node|IP|Disconnected|Banned|Disabled|Unhealthy|Stopped|Inactive|PartiallyOnline|ThisNode|'
254     _line=$(( $FAKE_CTDB_PNN + 1 ))
255     _ip=$(sed -e "${_line}p" "$CTDB_NATGW_NODES")
256     echo "|${FAKE_CTDB_PNN}|${_ip}|0|0|0|0|0|0|0|Y|"
257 }
258
259 ######################################################################
260
261 ctdb_setvar ()
262 {
263     shift
264     _var="$1"
265
266     for _i in $FAKE_CTDB_TUNABLES_OK ; do
267         if [ "$_var" = "$_i" ] ; then
268             return 0
269         fi
270     done
271
272     for _i in $FAKE_CTDB_TUNABLES_OBSOLETE ; do
273         if [ "$_var" = "$_i" ] ; then
274             echo "Setting obsolete tunable variable '${_var}'"
275             return 0
276         fi
277     done
278
279     echo "Unable to set tunable variable '${_var}'"
280     return 1
281 }
282
283 ######################################################################
284
285 _t_setup ()
286 {
287     _t_dir="$EVENTSCRIPTS_TESTS_VAR_DIR/fake-ctdb/fake-tdb/$1"
288     mkdir -p "$_t_dir"
289 }
290
291 _t_put ()
292 {
293     echo "$2" >"${_t_dir}/$1"
294 }
295
296 _t_get ()
297 {
298     cat "${_t_dir}/$1"
299 }
300
301 _t_del ()
302 {
303     rm -f "${_t_dir}/$1"
304 }
305
306 ctdb_pstore ()
307 {
308     _t_setup "$2"
309     _t_put "$3" "$4"
310 }
311
312 ctdb_pdelete ()
313 {
314     _t_setup "$2"
315     _t_del "$3"
316 }
317
318 ctdb_pfetch ()
319 {
320     _t_setup "$2"
321     _t_get "$3" >"$4" 2>/dev/null
322 }
323
324 ctdb_ptrans ()
325 {
326     _t_setup "$2"
327
328     while IFS="" read _line ; do
329         _k=$(echo "$_line" | sed -n -e 's@^"\([^"]*\)" "[^"]*"$@\1@p')
330         _v=$(echo "$_line" | sed -e 's@^"[^"]*" "\([^"]*\)"$@\1@')
331         [ -n "$_k" ] || die "ctdb ptrans: bad line \"${line}\""
332         if [ -n "$_v" ] ; then
333             _t_put "$_k" "$_v"
334         else
335             _t_del "$_k"
336         fi
337     done
338 }
339
340 ctdb_catdb ()
341 {
342     _t_setup "$2"
343
344     # This will break on keys with spaces but we don't have any of
345     # those yet.
346     _count=0
347     for _i in "${_t_dir}/"* ; do
348         [ -r "$_i" ] || continue
349         _k="${_i##*/}" # basename
350         _v=$(_t_get "$_k")
351         _kn=$(echo -n "$_k" | wc -c)
352         _vn=$(echo -n "$_v" | wc -c)
353         cat <<EOF
354 key(${_kn}) = "${_k}"
355 dmaster: 0
356 rsn: 1
357 data(${_vn}) = "${_v}"
358
359 EOF
360         _count=$(($_count + 1))
361     done
362
363     echo "Dumped ${_count} records"
364 }
365
366 ######################################################################
367
368 case "$1" in
369     gettickles)
370         setup_tickles
371         echo "|source ip|port|destination ip|port|"
372         while read src dst ; do
373             echo "|${src}|${dst}|"
374         done <"$tickles_file"
375         ;;
376     addtickle)
377         setup_tickles
378         echo "$2 $3" >>"$tickles_file"
379         ;;
380     deltickle)
381         setup_tickles
382         _t=$(grep -F -v "$2 $3" "$tickles_file")
383         echo "$_t" >"$tickles_file"
384         ;;
385     pstore)  ctdb_pstore  "$@" ;;
386     pdelete) ctdb_pdelete "$@" ;;
387     pfetch)  ctdb_pfetch  "$@" ;;
388     ptrans)  ctdb_ptrans  "$@" ;;
389     catdb)   ctdb_catdb   "$@" ;;
390     ifaces)
391         # Assume -Y.
392         echo "|Name|LinkStatus|References|"
393         _f="${CTDB_PUBLIC_ADDRESSES:-${CTDB_BASE}/public_addresses}"
394         if [ -r "$_f" ] ; then
395             while read _ip _iface ; do
396                 case "_$ip" in
397                     \#*) : ;;
398                     *)
399                         _status=1
400                         # For now assume _iface contains only 1.
401                         if [ -f "{FAKE_CTDB_IFACES_DOWN}/${_iface}" ] ; then
402                             _status=0
403                         fi
404                         # Nobody looks at references
405                         echo "|${_iface}|${_status}|0|"
406                 esac
407             done <"$_f" |
408             sort -u
409         fi
410         ;;
411     setifacelink)
412         # Existence of file means CTDB thinks interface is down.
413         _f="${FAKE_CTDB_IFACES_DOWN}/$2"
414         case "$3" in
415             up)   rm -f "$_f" ;;
416             down) touch "$_f" ;;
417             *)
418                 echo "ctdb setifacelink: unsupported interface status $3"
419                 exit 1
420         esac
421         ;;
422     checktcpport)
423         for _i in $FAKE_TCP_LISTEN ; do
424             if [ "$2" = "${_i##*:}" ] ; then
425                 exit 98
426             fi
427         done
428
429         exit 0
430         ;;
431     scriptstatus)
432         $machine_readable || not_implemented "$1, without -X"
433         [ "$2" != "all" ] || not_implemented "scriptstatus all"
434         # For now just assume everything is good.
435         echo "|Type|Name|Code|Status|Start|End|Error Output...|"
436         for _i in "$CTDB_BASE/events.d/"*.* ; do
437             _d1=$(date '+%s.%N')
438             _b="${_i##*/}" # basename
439
440             _f="$FAKE_CTDB_SCRIPTSTATUS/$_b"
441             if [ -r "$_f" ] ; then
442                 read _code _status _err_out <"$_f"
443             else
444                 _code="0"
445                 _status="OK"
446                 if [ ! -x "$_i" ] ; then
447                     _status="DISABLED"
448                     _code="-8"
449                 fi
450                 _err_out=""
451             fi
452             _d2=$(date '+%s.%N')
453             echo "|${2:-monitor}|${_b}|${_code}|${_status}|${_d1}|${_d2}|${_err_out}|"
454         done
455         ;;
456     gratiousarp) : ;;  # Do nothing for now
457     killtcp)       ctdb_killtcp "$@" ;;
458     ip)            ctdb_ip "$@" ;;
459     pnn|xpnn)      ctdb_pnn ;;
460     enable)        ctdb_enable "$@";;
461     disable)       ctdb_disable "$@";;
462     moveip)        ctdb_moveip "$@";;
463     shutdown)      ctdb_shutdown "$@";;
464     setvar)        ctdb_setvar "$@" ;;
465     nodestatus)    ctdb_nodestatus "$@" ;;
466     *) not_implemented "$1" ;;
467 esac