From: Martin Schwenke Date: Thu, 11 Oct 2018 08:32:09 +0000 (+1100) Subject: ctdb-tests: Add local_daemons.sh X-Git-Tag: tdb-1.3.17~872 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=46fd4f144e7c881887db0deca0ae3b340e19afb3;p=thirdparty%2Fsamba.git ctdb-tests: Add local_daemons.sh This provides a separate script for handling local daemons. It can be used for testing outside of the CTDB simple test suite. It is installed as ctdb_local_daemons. The logic is copied from ctdb/tests/simple/scripts/local_daemons.bash. Signed-off-by: Martin Schwenke Reviewed-by: Amitay Isaacs --- diff --git a/ctdb/packaging/RPM/ctdb.spec.in b/ctdb/packaging/RPM/ctdb.spec.in index 4c9cae486fd..537f158b2d1 100644 --- a/ctdb/packaging/RPM/ctdb.spec.in +++ b/ctdb/packaging/RPM/ctdb.spec.in @@ -270,6 +270,7 @@ test suite for ctdb %{_libexecdir}/%{name}/tests/* %{_bindir}/ctdb_run_tests %{_bindir}/ctdb_run_cluster_tests +%{_bindir}/ctdb_local_daemons %doc tests/README %if %with_pcp_pmda diff --git a/ctdb/tests/local_daemons.sh b/ctdb/tests/local_daemons.sh new file mode 100755 index 00000000000..a48e166bfe2 --- /dev/null +++ b/ctdb/tests/local_daemons.sh @@ -0,0 +1,385 @@ +#!/bin/sh + +set -u + +export CTDB_TEST_MODE="yes" + +# Following 2 lines may be modified by installation script +export CTDB_TESTS_ARE_INSTALLED=false +export CTDB_TEST_DIR=$(dirname "$0") + +export TEST_SCRIPTS_DIR="${CTDB_TEST_DIR}/scripts" + +. "${TEST_SCRIPTS_DIR}/common.sh" + +# common.sh will set TEST_SUBDIR to a stupid value when installed +# because common.sh is usually sourced by a test. TEST_SUBDIR needs +# to be correctly set so setup_ctdb_base() finds the etc-ctdb/ +# subdirectory and the test event script is correctly installed, so +# fix it. +TEST_SUBDIR="$CTDB_TEST_DIR" + +if ! $CTDB_TESTS_ARE_INSTALLED ; then + hdir="$CTDB_SCRIPTS_HELPER_BINDIR" + export CTDB_EVENTD="${hdir}/ctdb-eventd" + export CTDB_EVENT_HELPER="${hdir}/ctdb-event" + export CTDB_LOCK_HELPER="${hdir}/ctdb_lock_helper" + export CTDB_RECOVERY_HELPER="${hdir}/ctdb_recovery_helper" + export CTDB_TAKEOVER_HELPER="${hdir}/ctdb_takeover_helper" + export CTDB_CLUSTER_MUTEX_HELPER="${hdir}/ctdb_mutex_fcntl_helper" +fi + +######################################## + +# If the given IP is hosted then print 2 items: maskbits and iface +have_ip () +{ + _addr="$1" + + case "$_addr" in + *:*) _bits=128 ;; + *) _bits=32 ;; + esac + + _t=$(ip addr show to "${_addr}/${_bits}") + [ -n "$_t" ] +} + +setup_nodes () +{ + _num_nodes="$1" + _use_ipv6="$2" + + _have_all_ips=true + for _i in $(seq 0 $((_num_nodes - 1)) ) ; do + if $_use_ipv6 ; then + _j=$(printf "%04x" $((0x5f00 + 1 + _i)) ) + _node_ip="fd00::5357:${_j}" + if have_ip "$_node_ip" ; then + echo "$_node_ip" + else + cat >&2 <&2 < setup [ ... ] + +Options: + -F Disable failover (default: failover enabled) + -N Nodes file (default: automatically generated) + -n Number of nodes (default: 3) + -P Public addresses file (default: automatically generated) + -S Socket wrapper shared library to preload (default: none) + -6 Generate IPv6 IPs for nodes, public addresses (default: IPv4) +EOF + + exit 1 +} + +local_daemons_setup () +{ + _disable_failover=false + _nodes_file="" + _num_nodes=3 + _public_addresses_file="" + _socket_wrapper="" + _use_ipv6=false + + set -e + + while getopts "FN:n:P:S:6h?" _opt ; do + case "$_opt" in + F) _disable_failover=true ;; + N) _nodes_file="$OPTARG" ;; + n) _num_nodes="$OPTARG" ;; + P) _public_addresses_file="$OPTARG" ;; + S) _socket_wrapper="$OPTARG" ;; + 6) _use_ipv6=true ;; + \?|h) local_daemons_setup_usage ;; + esac + done + shift $((OPTIND - 1)) + + mkdir -p "$directory" + + _nodes_all="${directory}/nodes" + if [ -n "$_nodes_file" ] ; then + cp "$_nodes_file" "$_nodes_all" + else + setup_nodes "$_num_nodes" $_use_ipv6 >"$_nodes_all" + fi + + # If there are (strictly) greater than 2 nodes then we'll + # "randomly" choose a node to have no public addresses + _node_no_ips=-1 + if [ "$_num_nodes" -gt 2 ] ; then + _node_no_ips=$(($$ % _num_nodes)) + fi + + _public_addresses_all="${directory}/public_addresses" + if [ -n "$_public_addresses_file" ] ; then + cp "$_public_addresses_file" "$_public_addresses_all" + else + setup_public_addresses "$_num_nodes" \ + $_node_no_ips \ + $_use_ipv6 >"$_public_addresses_all" + fi + + if [ -n "$_socket_wrapper" ] ; then + setup_socket_wrapper "$_socket_wrapper" + fi + + for _n in $(seq 0 $((_num_nodes - 1))) ; do + setup_ctdb_base "$directory" "node.${_n}" \ + functions notify.sh debug-hung-script.sh + + cp "$_nodes_all" "${CTDB_BASE}/nodes" + + _public_addresses="${CTDB_BASE}/public_addresses" + + if [ -z "$_public_addresses_file" ] && \ + [ $_node_no_ips -eq "$_n" ] ; then + echo "Node ${_n} will have no public IPs." + : >"$_public_addresses" + else + cp "$_public_addresses_all" "$_public_addresses" + fi + + _node_ip=$(sed -n -e "$((_n + 1))p" "$_nodes_all") + + _db_dir="${CTDB_BASE}/db" + for _d in "volatile" "persistent" "state" ; do + mkdir -p "${_db_dir}/${_d}" + done + + cat >"${CTDB_BASE}/ctdb.conf" <&2 < ssh [ -n ] +EOF + + exit 1 +} + +local_daemons_ssh () +{ + if [ $# -lt 2 ] ; then + local_daemons_ssh_usage + fi + + # Only try to respect ssh -n option, others can't be used so discard them + _close_stdin=false + while getopts "nh?" _opt ; do + case "$_opt" in + n) _close_stdin=true ;; + \?|h) local_daemons_ssh_usage ;; + *) : ;; + esac + done + shift $((OPTIND - 1)) + + if [ $# -lt 2 ] ; then + local_daemons_ssh_usage + fi + + _nodes="${directory}/nodes" + + # IP adress of node. onnode can pass hostnames but not in these tests + _ip="$1" ; shift + # "$*" is command + + + # Determine the correct CTDB base directory + _num=$(awk -v ip="$_ip" '$1 == ip { print NR }' "$_nodes") + _node=$((_num - 1)) + export CTDB_BASE="${directory}/node.${_node}" + + if [ ! -d "$CTDB_BASE" ] ; then + die "$0 ssh: Unable to find base for node ${_ip}" + fi + + if $_close_stdin ; then + exec sh -c "$*" <&- + else + exec sh -c "$*" + fi +} + +onnode_common () +{ + # onnode will execute this, which fakes ssh against local daemons + export ONNODE_SSH="${0} ${directory} ssh" + + # onnode just needs the nodes file, so use the common one + export CTDB_BASE="$directory" +} + +local_daemons_generic_usage () +{ + cat >&2 < ${1} + + can be "all", a node number or any specification supported by onnode +EOF + + exit 1 +} + +local_daemons_start_socket_wrapper () +{ + _so="${directory}/libsocket-wrapper.so" + _d="${directory}/sw" + + if [ -d "$_d" ] && [ -f "$_so" ] ; then + export SOCKET_WRAPPER_DIR="$_d" + export LD_PRELOAD="$_so" + fi +} + +local_daemons_start () +{ + if [ $# -ne 1 ] || [ "$1" = "-h" ] ; then + local_daemons_generic_usage "start" + fi + + local_daemons_start_socket_wrapper + + _nodes="$1" + + onnode_common + + onnode "$_nodes" "${VALGRIND:-} ctdbd" +} + +local_daemons_stop () +{ + if [ $# -ne 1 ] || [ "$1" = "-h" ] ; then + local_daemons_generic_usage "stop" + fi + + _nodes="$1" + + onnode_common + + onnode -p "$_nodes" "${VALGRIND:-} ${CTDB:-ctdb} shutdown" +} + +usage () +{ + cat < [ ... ] + +Commands: + setup Set up daemon configuration according to given options + start Start specified daemon(s) + stop Stop specified daemon(s) + +All commands use for daemon configuration + +Run command with -h option to see per-command usage +EOF + + exit 1 +} + +if [ $# -lt 2 ] ; then + usage +fi + +directory="$1" +command="$2" +shift 2 + +case "$command" in +setup) local_daemons_setup "$@" ;; +ssh) local_daemons_ssh "$@" ;; # Internal, not shown by usage() +start) local_daemons_start "$@" ;; +stop) local_daemons_stop "$@" ;; +*) usage ;; +esac diff --git a/ctdb/wscript b/ctdb/wscript index b59f6d5ed5d..e8e8e4d290e 100644 --- a/ctdb/wscript +++ b/ctdb/wscript @@ -1114,6 +1114,14 @@ def build(bld): bld.symlink_as(os.path.join(bld.env.BINDIR, 'ctdb_run_cluster_tests'), 'ctdb_run_tests') + bld.SAMBA_GENERATOR('ctdb-local-daemons', + source='tests/local_daemons.sh', + target='ctdb_local_daemons.sh', + rule='sed -e "%s" -e "%s" ${SRC} > ${TGT}' % ( + sed_expr1, sed_expr2)) + bld.INSTALL_FILES('${BINDIR}', 'ctdb_local_daemons.sh', + destname='ctdb_local_daemons', chmod=0o755) + def testonly(ctx): cmd = 'tests/run_tests.sh -V tests/var'