6 Verify that adding/deleting IPs using 'ctdb reloadips' works
8 Checks that when IPs are added to and deleted from a single node then
9 those IPs are actually assigned and unassigned from the specified
14 * An active CTDB cluster with public IP addresses configured
18 * When IPs are added to a single node then they are assigned to an
21 * When IPs are deleted from a single node then they disappear from an
26 .
"${TEST_SCRIPTS_DIR}/integration.bash"
32 ctdb_test_check_real_cluster
37 ctdb_restart_when_done
39 select_test_node_and_ips
43 # Search for an unused 10.B.1.0/24 network on which to add public IP
46 # The initial search is for a 10.B.0.0/16 network since some
47 # configurations may use a whole class B for the private network.
48 # Check that there are no public IP addresses (as reported by "ctdb ip
49 # all") or other IP addresses (as reported by "ip addr show") with
50 # the provided prefix. Note that this is an IPv4-specific test.
52 echo "Getting public IP information from CTDB..."
53 try_command_on_node any
"$CTDB ip -X -v all"
54 ctdb_ip_info
=$
(echo "$out" |
awk -F'|' 'NR > 1 { print $2, $3, $5 }')
56 echo "Getting IP information from interfaces..."
57 try_command_on_node all
"ip addr show"
58 ip_addr_info
=$
(echo "$out" | \
59 awk '$1 == "inet" { ip = $2; sub(/\/.*/, "", ip); print ip }')
62 for b
in $
(seq 0 255) ; do
65 # Does the prefix match any IP address returned by "ip addr info"?
67 if [ "${ip#${prefix}.}" != "$ip" ] ; then
71 done <<<"$ip_addr_info"
73 # Does the prefix match any public IP address "ctdb ip all"?
74 while read ip pnn iface
; do
75 if [ "${ip#${prefix}.}" != "$ip" ] ; then
79 done <<<"$ctdb_ip_info"
81 # Got through the IPs without matching prefix - done!
85 [ -n "$prefix" ] || die
"Unable to find a usable IP address prefix"
87 # We really want a class C: 10.B.1.0/24
92 iface
=$
(echo "$ctdb_ip_info" |
awk -v pnn
=$test_node '$2 == pnn { print $3 ; exit }')
96 # This needs to be set only on the recmaster. All nodes should do the trick.
97 new_takeover_timeout
=90
98 echo "Setting TakeoverTimeout=${new_takeover_timeout} to avoid potential bans"
99 try_command_on_node all
"$CTDB setvar TakeoverTimeout ${new_takeover_timeout}"
103 addresses
=$
(get_ctdbd_command_line_option
$test_node "public-addresses")
104 echo "Public addresses file on node $test_node is \"$addresses\""
105 backup
="${addresses}.$$"
107 backup_public_addresses
()
109 try_command_on_node
$test_node "cp -a $addresses $backup"
112 restore_public_addresses
()
114 try_command_on_node
$test_node "mv $backup $addresses >/dev/null 2>&1 || true"
116 ctdb_test_exit_hook_add restore_public_addresses
118 # Now create that backup
119 backup_public_addresses
123 add_ips_to_original_config
()
132 echo "Adding new public IPs to original config on node ${test_node}..."
133 echo "IPs will be ${prefix}.${first}/24..${prefix}.${last}/24"
135 # Implement this by completely rebuilding the public_addresses
136 # file. This is easier than deleting entries on a remote node.
137 restore_public_addresses
138 backup_public_addresses
140 # Note that tee is a safe way of creating a file on a remote node.
141 # This avoids potential fragility with quoting or redirection.
142 for i
in $
(seq $first $last) ; do
143 echo "${prefix}.${i}/24 ${iface}"
145 try_command_on_node
-i $test_node "tee -a $addresses"
156 # If just 0 specified then this is an empty range
157 local public_ips_file
=$
(mktemp
)
158 if [ "$first" = 0 -a -z "$last" ] ; then
159 echo "Checking that there are no IPs in ${prefix}.0/24"
161 local prefix_regexp
="inet *${prefix//./\.}"
163 echo "Checking IPs in range ${prefix}.${first}/24..${prefix}.${last}/24"
166 for i
in $
(seq $first $last) ; do
167 echo "${prefix}.${i}"
168 done |
sort >"$public_ips_file"
171 try_command_on_node
$test_node "ip addr show dev ${iface}"
172 local ip_addrs_file
=$
(mktemp
)
174 sed -n -e "s@.*inet * \(${prefix//./\.}\.[0-9]*\)/.*@\1@p" | \
175 sort >"$ip_addrs_file"
177 local diffs
=$
(diff "$public_ips_file" "$ip_addrs_file") || true
178 rm -f "$ip_addrs_file" "$public_ips_file"
180 if [ -z "$diffs" ] ; then
181 echo "GOOD: IP addresses are as expected"
183 echo "BAD: IP addresses are incorrect:"
195 add_ips_to_original_config \
196 $test_node "$addresses" "$iface" "$prefix" 1 $new_ip_max
198 try_command_on_node
$test_node "$CTDB reloadips"
200 check_ips
$test_node "$iface" "$prefix" 1 $new_ip_max
202 try_command_on_node any
$CTDB sync
206 # This should be the primary. Ensure that no other IPs are lost
207 echo "Using 'ctdb reloadips' to remove the 1st address just added..."
209 add_ips_to_original_config \
210 $test_node "$addresses" "$iface" "$prefix" 2 $new_ip_max
212 try_command_on_node
$test_node "$CTDB reloadips"
214 check_ips
$test_node "$iface" "$prefix" 2 $new_ip_max
216 try_command_on_node any
$CTDB sync
220 # Get rid of about 1/2 the IPs
221 start
=$
(($new_ip_max / 2 + 1))
222 echo "Updating to include only about 1/2 of the new IPs..."
224 add_ips_to_original_config \
225 $test_node "$addresses" "$iface" "$prefix" $start $new_ip_max
227 try_command_on_node
$test_node "$CTDB reloadips"
229 check_ips
$test_node "$iface" "$prefix" $start $new_ip_max
231 try_command_on_node any
$CTDB sync
236 echo "Restoring original IP configuration..."
237 restore_public_addresses
239 try_command_on_node
$test_node "$CTDB reloadips"
241 check_ips
$test_node "$iface" "$prefix" 0