summaryrefslogtreecommitdiffstats
path: root/ctdb/tests/UNIT/eventscripts/stubs/ctdb
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 17:20:00 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 17:20:00 +0000
commit8daa83a594a2e98f39d764422bfbdbc62c9efd44 (patch)
tree4099e8021376c7d8c05bdf8503093d80e9c7bad0 /ctdb/tests/UNIT/eventscripts/stubs/ctdb
parentInitial commit. (diff)
downloadsamba-8daa83a594a2e98f39d764422bfbdbc62c9efd44.tar.xz
samba-8daa83a594a2e98f39d764422bfbdbc62c9efd44.zip
Adding upstream version 2:4.20.0+dfsg.upstream/2%4.20.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ctdb/tests/UNIT/eventscripts/stubs/ctdb')
-rwxr-xr-xctdb/tests/UNIT/eventscripts/stubs/ctdb481
1 files changed, 481 insertions, 0 deletions
diff --git a/ctdb/tests/UNIT/eventscripts/stubs/ctdb b/ctdb/tests/UNIT/eventscripts/stubs/ctdb
new file mode 100755
index 0000000..20135eb
--- /dev/null
+++ b/ctdb/tests/UNIT/eventscripts/stubs/ctdb
@@ -0,0 +1,481 @@
+#!/bin/sh
+
+prog="ctdb"
+
+# Print a message and exit.
+die()
+{
+ echo "$1" >&2
+ exit "${2:-1}"
+}
+
+not_implemented_exit_code=1
+
+usage()
+{
+ cat >&2 <<EOF
+Usage: $prog [-X] cmd
+
+A fake CTDB stub that prints items depending on the variables
+FAKE_CTDB_PNN (default 0) depending on command-line options.
+EOF
+ exit 1
+}
+
+not_implemented()
+{
+ echo "${prog}: command \"$1\" not implemented in stub" >&2
+ exit $not_implemented_exit_code
+}
+
+verbose=false
+machine_readable=false
+nodespec=""
+
+args=""
+
+# Options and command argument can appear in any order, so when
+# getopts thinks it is done, process any non-option arguments and go
+# around again.
+while [ $# -gt 0 ]; do
+ while getopts "Xvhn:?" opt; do
+ case "$opt" in
+ X) machine_readable=true ;;
+ v) verbose=true ;;
+ n) nodespec="$OPTARG" ;;
+ \? | *) usage ;;
+ esac
+ done
+ shift $((OPTIND - 1))
+
+ # Anything left over must be a non-option arg
+ if [ $# -gt 0 ]; then
+ args="${args}${args:+ }${1}"
+ shift
+ fi
+done
+
+[ -n "$args" ] || usage
+# Want word splitting
+# shellcheck disable=SC2086
+set -- $args
+
+setup_tickles()
+{
+ # Make sure tickles file exists.
+ tickles_file="${CTDB_TEST_TMP_DIR}/fake-ctdb/tickles"
+ mkdir -p "$(dirname "$tickles_file")"
+ touch "$tickles_file"
+}
+
+ctdb_gettickles()
+{
+ _ip="$1"
+ _port="$2"
+
+ setup_tickles
+
+ echo "|source ip|port|destination ip|port|"
+ while read -r _src _dst; do
+ if [ -z "$_ip" ] || [ "$_ip" = "${_dst%:*}" ]; then
+ if [ -z "$_port" ] || [ "$_port" = "${_dst##*:}" ]; then
+ echo "|${_src%:*}|${_src##*:}|${_dst%:*}|${_dst##*:}|"
+ fi
+ fi
+ done <"$tickles_file"
+}
+
+ctdb_addtickle()
+{
+ _src="$1"
+ _dst="$2"
+
+ setup_tickles
+
+ if [ -n "$_dst" ]; then
+ echo "${_src} ${_dst}" >>"$tickles_file"
+ else
+ cat >>"$tickles_file"
+ fi
+}
+
+ctdb_deltickle()
+{
+ _src="$1"
+ _dst="$2"
+
+ setup_tickles
+
+ if [ -n "$_dst" ]; then
+ _t=$(grep -F -v "${_src} $${_dst}" "$tickles_file")
+ else
+ _t=$(cat "$tickles_file")
+ while read -r _src _dst; do
+ _t=$(echo "$_t" | grep -F -v "${_src} ${_dst}")
+ done
+ fi
+ echo "$_t" >"$tickles_file"
+}
+
+parse_nodespec()
+{
+ if [ "$nodespec" = "all" ]; then
+ nodes="$(seq 0 $((FAKE_CTDB_NUMNODES - 1)))"
+ elif [ -n "$nodespec" ]; then
+ nodes="$(echo "$nodespec" | sed -e 's@,@ @g')"
+ else
+ nodes=$(ctdb_pnn)
+ fi
+}
+
+# For testing backward compatibility...
+for i in $CTDB_NOT_IMPLEMENTED; do
+ if [ "$i" = "$1" ]; then
+ not_implemented "$i"
+ fi
+done
+
+ctdb_pnn()
+{
+ # Defaults to 0
+ echo "${FAKE_CTDB_PNN:-0}"
+}
+
+######################################################################
+
+FAKE_CTDB_NODE_STATE="$FAKE_CTDB_STATE/node-state"
+FAKE_CTDB_NODES_DISABLED="$FAKE_CTDB_NODE_STATE/0x4"
+
+######################################################################
+
+# NOTE: all nodes share public addresses file
+
+FAKE_CTDB_IP_LAYOUT="$FAKE_CTDB_STATE/ip-layout"
+
+ip_reallocate()
+{
+ touch "$FAKE_CTDB_IP_LAYOUT"
+
+ # ShellCheck doesn't understand this flock pattern
+ # shellcheck disable=SC2094
+ (
+ flock 0
+
+ _pa="${CTDB_BASE}/public_addresses"
+
+ if [ ! -s "$FAKE_CTDB_IP_LAYOUT" ]; then
+ sed -n -e 's@^\([^#][^/]*\)/.*@\1 -1@p' \
+ "$_pa" >"$FAKE_CTDB_IP_LAYOUT"
+ fi
+
+ _t="${FAKE_CTDB_IP_LAYOUT}.new"
+
+ _flags=""
+ for _i in $(seq 0 $((FAKE_CTDB_NUMNODES - 1))); do
+ if ls "$FAKE_CTDB_STATE/node-state/"*"/$_i" >/dev/null 2>&1; then
+ # Have non-zero flags
+ _this=0
+ for _j in "$FAKE_CTDB_STATE/node-state/"*"/$_i"; do
+ _tf="${_j%/*}" # dirname
+ _f="${_tf##*/}" # basename
+ _this=$((_this | _f))
+ done
+ else
+ _this="0"
+ fi
+ _flags="${_flags}${_flags:+,}${_this}"
+ done
+ CTDB_TEST_LOGLEVEL=NOTICE \
+ "ctdb_takeover_tests" \
+ "ipalloc" "$_flags" <"$FAKE_CTDB_IP_LAYOUT" |
+ sort >"$_t"
+ mv "$_t" "$FAKE_CTDB_IP_LAYOUT"
+ ) <"$FAKE_CTDB_IP_LAYOUT"
+}
+
+ctdb_ip()
+{
+ # If nobody has done any IP-fu then generate a layout.
+ [ -f "$FAKE_CTDB_IP_LAYOUT" ] || ip_reallocate
+
+ _mypnn=$(ctdb_pnn)
+
+ if $machine_readable; then
+ if $verbose; then
+ echo "|Public IP|Node|ActiveInterface|AvailableInterfaces|ConfiguredInterfaces|"
+ else
+ echo "|Public IP|Node|"
+ fi
+ else
+ echo "Public IPs on node ${_mypnn}"
+ fi
+
+ # Join public addresses file with $FAKE_CTDB_IP_LAYOUT, and
+ # process output line by line...
+ _pa="${CTDB_BASE}/public_addresses"
+ sed -e 's@/@ @' "$_pa" | sort | join - "$FAKE_CTDB_IP_LAYOUT" |
+ while read -r _ip _ _ifaces _pnn; do
+ if $verbose; then
+ # If more than 1 interface, assume all addresses are on the 1st.
+ _first_iface="${_ifaces%%,*}"
+ # Only show interface if address is on this node.
+ _my_iface=""
+ if [ "$_pnn" = "$_mypnn" ]; then
+ _my_iface="$_first_iface"
+ fi
+ if $machine_readable; then
+ echo "|${_ip}|${_pnn}|${_my_iface}|${_first_iface}|${_ifaces}|"
+ else
+ echo "${_ip} node[${_pnn}] active[${_my_iface}] available[${_first_iface}] configured[[${_ifaces}]"
+ fi
+ else
+ if $machine_readable; then
+ echo "|${_ip}|${_pnn}|"
+ else
+ echo "${_ip} ${_pnn}"
+ fi
+ fi
+ done
+}
+
+ctdb_moveip()
+{
+ _ip="$1"
+ _target="$2"
+
+ ip_reallocate # should be harmless and ensures we have good state
+
+ # ShellCheck doesn't understand this flock pattern
+ # shellcheck disable=SC2094
+ (
+ flock 0
+
+ _t="${FAKE_CTDB_IP_LAYOUT}.new"
+
+ while read -r _i _pnn; do
+ if [ "$_ip" = "$_i" ]; then
+ echo "$_i $_target"
+ else
+ echo "$_i $_pnn"
+ fi
+ done | sort >"$_t"
+ mv "$_t" "$FAKE_CTDB_IP_LAYOUT"
+ ) <"$FAKE_CTDB_IP_LAYOUT"
+}
+
+######################################################################
+
+ctdb_enable()
+{
+ parse_nodespec
+
+ for _i in $nodes; do
+ rm -f "${FAKE_CTDB_NODES_DISABLED}/${_i}"
+ done
+
+ ip_reallocate
+}
+
+ctdb_disable()
+{
+ parse_nodespec
+
+ for _i in $nodes; do
+ mkdir -p "$FAKE_CTDB_NODES_DISABLED"
+ touch "${FAKE_CTDB_NODES_DISABLED}/${_i}"
+ done
+
+ ip_reallocate
+}
+
+######################################################################
+
+ctdb_shutdown()
+{
+ echo "CTDB says BYE!"
+}
+
+######################################################################
+
+# This is only used by the NAT and LVS gateway code at the moment, so
+# use a hack. Assume that $CTDB_NATGW_NODES or $CTDB_LVS_NODES
+# contains all nodes in the cluster (which is what current tests
+# assume). Use the PNN to find the address from this file. The NAT
+# gateway code only used the address, so just mark the node healthy.
+ctdb_nodestatus()
+{
+ echo '|Node|IP|Disconnected|Banned|Disabled|Unhealthy|Stopped|Inactive|PartiallyOnline|ThisNode|'
+ _line=$((FAKE_CTDB_PNN + 1))
+ _ip=$(sed -e "${_line}p" "${CTDB_NATGW_NODES:-${CTDB_LVS_NODES}}")
+ echo "|${FAKE_CTDB_PNN}|${_ip}|0|0|0|0|0|0|0|Y|"
+}
+
+######################################################################
+
+_t_setup()
+{
+ _t_dir="${CTDB_TEST_TMP_DIR}/fake-ctdb/fake-tdb/$1"
+ mkdir -p "$_t_dir"
+}
+
+_t_put()
+{
+ echo "$2" >"${_t_dir}/$1"
+}
+
+_t_get()
+{
+ cat "${_t_dir}/$1"
+}
+
+_t_del()
+{
+ rm -f "${_t_dir}/$1"
+}
+
+ctdb_pstore()
+{
+ _t_setup "$1"
+ _t_put "$2" "$3"
+}
+
+ctdb_pdelete()
+{
+ _t_setup "$1"
+ _t_del "$2"
+}
+
+ctdb_pfetch()
+{
+ _t_setup "$1"
+ _t_get "$2" >"$3" 2>/dev/null
+}
+
+ctdb_ptrans()
+{
+ _t_setup "$1"
+
+ while IFS="" read -r _line; do
+ _k=$(echo "$_line" | sed -n -e 's@^"\([^"]*\)" "[^"]*"$@\1@p')
+ _v=$(echo "$_line" | sed -e 's@^"[^"]*" "\([^"]*\)"$@\1@')
+ [ -n "$_k" ] || die "ctdb ptrans: bad line \"${_line}\""
+ if [ -n "$_v" ]; then
+ _t_put "$_k" "$_v"
+ else
+ _t_del "$_k"
+ fi
+ done
+}
+
+ctdb_catdb()
+{
+ _t_setup "$1"
+
+ # This will break on keys with spaces but we don't have any of
+ # those yet.
+ _count=0
+ for _i in "${_t_dir}/"*; do
+ [ -r "$_i" ] || continue
+ _k="${_i##*/}" # basename
+ _v=$(_t_get "$_k")
+ _kn=$(printf '%s' "$_k" | wc -c)
+ _vn=$(printf '%s' "$_v" | wc -c)
+ cat <<EOF
+key(${_kn}) = "${_k}"
+dmaster: 0
+rsn: 1
+data(${_vn}) = "${_v}"
+
+EOF
+ _count=$((_count + 1))
+ done
+
+ echo "Dumped ${_count} records"
+}
+
+######################################################################
+
+FAKE_CTDB_IFACES_DOWN="${FAKE_CTDB_STATE}/ifaces-down"
+rm -f "${FAKE_CTDB_IFACES_DOWN}"/*
+
+ctdb_ifaces()
+{
+ _f="${CTDB_BASE}/public_addresses"
+
+ if [ ! -f "$_f" ]; then
+ die "Public addresses file \"${_f}\" not found"
+ fi
+
+ # Assume -Y.
+ echo "|Name|LinkStatus|References|"
+ while read -r _ip _iface; do
+ case "$_ip" in
+ \#*) : ;;
+ *)
+ _status=1
+ # For now assume _iface contains only 1.
+ if [ -f "{FAKE_CTDB_IFACES_DOWN}/${_iface}" ]; then
+ _status=0
+ fi
+ # Nobody looks at references
+ echo "|${_iface}|${_status}|0|"
+ ;;
+ esac
+ done <"$_f" |
+ sort -u
+}
+
+ctdb_setifacelink()
+{
+ _iface="$1"
+ _state="$2"
+
+ mkdir -p "$FAKE_CTDB_IFACES_DOWN"
+
+ # Existence of file means CTDB thinks interface is down.
+ _f="${FAKE_CTDB_IFACES_DOWN}/${_iface}"
+
+ case "$_state" in
+ up) rm -f "$_f" ;;
+ down) touch "$_f" ;;
+ *) die "ctdb setifacelink: unsupported interface status ${_state}" ;;
+ esac
+}
+
+######################################################################
+
+ctdb_checktcpport()
+{
+ _port="$1"
+
+ for _i in $FAKE_TCP_LISTEN; do
+ if [ "$_port" = "$_i" ]; then
+ exit 98
+ fi
+ done
+
+ exit 0
+}
+
+ctdb_gratarp()
+{
+ # Do nothing for now
+ :
+}
+
+######################################################################
+
+cmd="$1"
+shift
+
+func="ctdb_${cmd}"
+
+# This could inadvertently run an external function instead of a local
+# function. However, this can only happen if testing a script
+# containing a new ctdb command that is not implemented, so this is
+# unlikely to do harm.
+if type "$func" >/dev/null 2>&1; then
+ "$func" "$@"
+else
+ not_implemented "$cmd"
+fi