mirror of
https://github.com/samba-team/samba.git
synced 2025-01-06 13:18:07 +03:00
41ff58338a
It would be nice to get rid of "onnode any". There's no use making tests nondeterministic. If covering different cases matters then they should be explicitly handled. In most places "any" is replaced by "$test_node". In some cases, where $test_node is not set, a fixed node that is already used elsewhere can be reused. Signed-off-by: Martin Schwenke <martin@meltin.net> Reviewed-by: Amitay Isaacs <amitay@gmail.com>
258 lines
6.4 KiB
Bash
Executable File
258 lines
6.4 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Verify that adding/deleting IPs using 'ctdb reloadips' works
|
|
|
|
# Checks that when IPs are added to and deleted from a single node then
|
|
# those IPs are actually assigned and unassigned from the specified
|
|
# interface.
|
|
|
|
# Prerequisites:
|
|
|
|
# * An active CTDB cluster with public IP addresses configured
|
|
|
|
# Expected results:
|
|
|
|
# * When IPs are added to a single node then they are assigned to an
|
|
# interface.
|
|
|
|
# * When IPs are deleted from a single node then they disappear from an
|
|
# interface.
|
|
|
|
. "${TEST_SCRIPTS_DIR}/cluster.bash"
|
|
|
|
set -e
|
|
|
|
ctdb_test_init
|
|
|
|
select_test_node_and_ips
|
|
|
|
####################
|
|
|
|
# Search for an unused 10.B.1.0/24 network on which to add public IP
|
|
# addresses.
|
|
|
|
# The initial search is for a 10.B.0.0/16 network since some
|
|
# configurations may use a whole class B for the private network.
|
|
# Check that there are no public IP addresses (as reported by "ctdb ip
|
|
# all") or other IP addresses (as reported by "ip addr show") with
|
|
# the provided prefix. Note that this is an IPv4-specific test.
|
|
|
|
echo "Getting public IP information from CTDB..."
|
|
ctdb_onnode "$test_node" "ip -X -v all"
|
|
ctdb_ip_info=$(awk -F'|' 'NR > 1 { print $2, $3, $5 }' "$outfile")
|
|
|
|
echo "Getting IP information from interfaces..."
|
|
try_command_on_node all "ip addr show"
|
|
ip_addr_info=$(awk '$1 == "inet" { ip = $2; sub(/\/.*/, "", ip); print ip }' \
|
|
"$outfile")
|
|
|
|
prefix=""
|
|
for b in $(seq 0 255) ; do
|
|
prefix="10.${b}"
|
|
|
|
# Does the prefix match any IP address returned by "ip addr info"?
|
|
while read ip ; do
|
|
if [ "${ip#${prefix}.}" != "$ip" ] ; then
|
|
prefix=""
|
|
continue 2
|
|
fi
|
|
done <<<"$ip_addr_info"
|
|
|
|
# Does the prefix match any public IP address "ctdb ip all"?
|
|
while read ip pnn iface ; do
|
|
if [ "${ip#${prefix}.}" != "$ip" ] ; then
|
|
prefix=""
|
|
continue 2
|
|
fi
|
|
done <<<"$ctdb_ip_info"
|
|
|
|
# Got through the IPs without matching prefix - done!
|
|
break
|
|
done
|
|
|
|
[ -n "$prefix" ] || die "Unable to find a usable IP address prefix"
|
|
|
|
# We really want a class C: 10.B.1.0/24
|
|
prefix="${prefix}.1"
|
|
|
|
####################
|
|
|
|
iface=$(echo "$ctdb_ip_info" | awk -v pnn=$test_node '$2 == pnn { print $3 ; exit }')
|
|
|
|
####################
|
|
|
|
# This needs to be set only on the recmaster. All nodes should do the trick.
|
|
new_takeover_timeout=90
|
|
echo "Setting TakeoverTimeout=${new_takeover_timeout} to avoid potential bans"
|
|
try_command_on_node all "$CTDB setvar TakeoverTimeout ${new_takeover_timeout}"
|
|
|
|
####################
|
|
|
|
try_command_on_node $test_node $CTDB_TEST_WRAPPER ctdb_base_show
|
|
addresses="${out}/public_addresses"
|
|
echo "Public addresses file on node $test_node is \"$addresses\""
|
|
backup="${addresses}.$$"
|
|
|
|
backup_public_addresses ()
|
|
{
|
|
try_command_on_node $test_node "cp -a $addresses $backup"
|
|
}
|
|
|
|
restore_public_addresses ()
|
|
{
|
|
try_command_on_node $test_node "mv $backup $addresses >/dev/null 2>&1 || true"
|
|
}
|
|
ctdb_test_exit_hook_add restore_public_addresses
|
|
|
|
# Now create that backup
|
|
backup_public_addresses
|
|
|
|
####################
|
|
|
|
add_ips_to_original_config ()
|
|
{
|
|
local test_node="$1"
|
|
local addresses="$2"
|
|
local iface="$3"
|
|
local prefix="$4"
|
|
local first="$5"
|
|
local last="$6"
|
|
|
|
echo "Adding new public IPs to original config on node ${test_node}..."
|
|
echo "IPs will be ${prefix}.${first}/24..${prefix}.${last}/24"
|
|
|
|
# Implement this by completely rebuilding the public_addresses
|
|
# file. This is easier than deleting entries on a remote node.
|
|
restore_public_addresses
|
|
backup_public_addresses
|
|
|
|
# Note that tee is a safe way of creating a file on a remote node.
|
|
# This avoids potential fragility with quoting or redirection.
|
|
for i in $(seq $first $last) ; do
|
|
echo "${prefix}.${i}/24 ${iface}"
|
|
done |
|
|
try_command_on_node -i $test_node "tee -a $addresses"
|
|
}
|
|
|
|
check_ips ()
|
|
{
|
|
local test_node="$1"
|
|
local iface="$2"
|
|
local prefix="$3"
|
|
local first="$4"
|
|
local last="$5"
|
|
|
|
# If just 0 specified then this is an empty range
|
|
local public_ips_file=$(mktemp)
|
|
if [ "$first" = 0 -a -z "$last" ] ; then
|
|
echo "Checking that there are no IPs in ${prefix}.0/24"
|
|
else
|
|
local prefix_regexp="inet *${prefix//./\.}"
|
|
|
|
echo "Checking IPs in range ${prefix}.${first}/24..${prefix}.${last}/24"
|
|
|
|
local i
|
|
for i in $(seq $first $last) ; do
|
|
echo "${prefix}.${i}"
|
|
done | sort >"$public_ips_file"
|
|
fi
|
|
|
|
try_command_on_node $test_node "ip addr show dev ${iface}"
|
|
local ip_addrs_file=$(mktemp)
|
|
cat "$outfile" | \
|
|
sed -n -e "s@.*inet * \(${prefix//./\.}\.[0-9]*\)/.*@\1@p" | \
|
|
sort >"$ip_addrs_file"
|
|
|
|
local diffs=$(diff "$public_ips_file" "$ip_addrs_file") || true
|
|
rm -f "$ip_addrs_file" "$public_ips_file"
|
|
|
|
if [ -z "$diffs" ] ; then
|
|
echo "GOOD: IP addresses are as expected"
|
|
else
|
|
echo "BAD: IP addresses are incorrect:"
|
|
echo "$diffs"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# ctdb reloadips will fail if it can't disable takover runs. The most
|
|
# likely reason for this is that there is already a takeover run in
|
|
# progress. We can't predict when this will happen, so retry if this
|
|
# occurs.
|
|
do_ctdb_reloadips ()
|
|
{
|
|
local retry_max=10
|
|
local retry_count=0
|
|
while : ; do
|
|
if try_command_on_node "$test_node" "$CTDB reloadips" ; then
|
|
return 0
|
|
fi
|
|
|
|
if [ "$out" != "Failed to disable takeover runs" ] ; then
|
|
return 1
|
|
fi
|
|
|
|
if [ $retry_count -ge $retry_max ] ; then
|
|
return 1
|
|
fi
|
|
|
|
retry_count=$((retry_count + 1))
|
|
echo "Retrying..."
|
|
sleep_for 1
|
|
done
|
|
}
|
|
|
|
####################
|
|
|
|
new_ip_max=100
|
|
|
|
####################
|
|
|
|
add_ips_to_original_config \
|
|
$test_node "$addresses" "$iface" "$prefix" 1 $new_ip_max
|
|
|
|
do_ctdb_reloadips
|
|
|
|
check_ips $test_node "$iface" "$prefix" 1 $new_ip_max
|
|
|
|
ctdb_onnode "$test_node" sync
|
|
|
|
####################
|
|
|
|
# This should be the primary. Ensure that no other IPs are lost
|
|
echo "Using 'ctdb reloadips' to remove the 1st address just added..."
|
|
|
|
add_ips_to_original_config \
|
|
$test_node "$addresses" "$iface" "$prefix" 2 $new_ip_max
|
|
|
|
do_ctdb_reloadips
|
|
|
|
check_ips $test_node "$iface" "$prefix" 2 $new_ip_max
|
|
|
|
ctdb_onnode "$test_node" sync
|
|
|
|
####################
|
|
|
|
# Get rid of about 1/2 the IPs
|
|
start=$(($new_ip_max / 2 + 1))
|
|
echo "Updating to include only about 1/2 of the new IPs..."
|
|
|
|
add_ips_to_original_config \
|
|
$test_node "$addresses" "$iface" "$prefix" $start $new_ip_max
|
|
|
|
do_ctdb_reloadips
|
|
|
|
check_ips $test_node "$iface" "$prefix" $start $new_ip_max
|
|
|
|
ctdb_onnode "$test_node" sync
|
|
|
|
####################
|
|
|
|
# Delete the rest
|
|
echo "Restoring original IP configuration..."
|
|
restore_public_addresses
|
|
|
|
do_ctdb_reloadips
|
|
|
|
check_ips $test_node "$iface" "$prefix" 0
|