[SCM] CTDB repository - branch master updated - ctdb-1.12-185-g5f660e5

Ronnie Sahlberg sahlberg at samba.org
Sun Feb 5 22:55:02 MST 2012


The branch, master has been updated
       via  5f660e5bf321ae5332bf1d32c8af36d6cc2569f4 (commit)
       via  4948f34676d5bdaaf1ddf8879df618a76013ea1e (commit)
       via  eed3f4988290bbe317a7aaa6f61826676dd8365a (commit)
       via  c378a059b35fcc9955215a0095826c919d42153c (commit)
       via  4aa4a5790ea9ad20e4d25404760c449b358b5260 (commit)
       via  48cb55aae47d11487bdf004a79df56779d1825a0 (commit)
       via  a63e603cb7e21a7334c6a07bc4415ff089dab3c1 (commit)
      from  6127515ea62173ff1574d1217129ec05a8fbeb3f (commit)

http://gitweb.samba.org/?p=ctdb.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 5f660e5bf321ae5332bf1d32c8af36d6cc2569f4
Merge: 4948f34676d5bdaaf1ddf8879df618a76013ea1e 4aa4a5790ea9ad20e4d25404760c449b358b5260
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Mon Feb 6 16:34:02 2012 +1100

    Merge remote branch 'martins/tests'

commit 4948f34676d5bdaaf1ddf8879df618a76013ea1e
Merge: 6127515ea62173ff1574d1217129ec05a8fbeb3f eed3f4988290bbe317a7aaa6f61826676dd8365a
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Mon Feb 6 16:30:49 2012 +1100

    Merge remote branch 'martins/takeover'

commit eed3f4988290bbe317a7aaa6f61826676dd8365a
Author: Martin Schwenke <martin at meltin.net>
Date:   Sun Jan 15 15:03:02 2012 +1100

    Test - IP allocation simulation - add -e option to run the daemon's algorithm
    
    A recent change in the deamon's (i.e. real) IP allocation algorithm
    uses qsort(3).  This makes it very difficult to get the same results
    in Python, since qsort's behaviour on identical keys is undefined.
    
    Add a -e option to run "../bin/ctdb_takeover_tests ctdb_takeover_run_core"
    instead of the internal Python algorithm.  We pass the current cluster
    state and read it back from the output of the test program.
    
    This is currently a rough hack.  Perhaps it'll be improved later...
    :-)
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>

commit c378a059b35fcc9955215a0095826c919d42153c
Author: Martin Schwenke <martin at meltin.net>
Date:   Sun Jan 15 15:01:27 2012 +1100

    Tests - IP allocation simulation - LCP2 => non-deterministic
    
    The default in this script is still deterministic IPs.  The LCP2
    option should really turn off deterministic IPs.
    
    Also fix a typo...
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>

commit 4aa4a5790ea9ad20e4d25404760c449b358b5260
Author: Martin Schwenke <martin at meltin.net>
Date:   Mon Nov 21 13:44:30 2011 +1100

    Tests: eventscripts - fix breakage in some NFS tests
    
    1341329f6125d491b82c873f793af819e677f714 either contains typos or
    attempts to influence the test depending on the host system.  Whatever
    the cause, a test system (e.g. my laptop) might not have
    /etc/sysconfig/nfs, so that can't be used to cause the stub
    etc/sysconfig/nfs to be loaded.
    
    We make the tests work by default again, leaving in some flexibility
    over configuration file location.
    
    If the goal is to force a Debian-style test mode then:
    
    * The tests are currently probably quite RHEL-centric anyway, so more
      work is probably needed.
    
    * Use an environment variable to indicate the distro test mode and
      make functions like setup_nfs() remove all of the various
      configuration files and create one in the distro-specific location.
    
    I won't do this now... ENOTIME...
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>

commit 48cb55aae47d11487bdf004a79df56779d1825a0
Author: Martin Schwenke <martin at meltin.net>
Date:   Mon Nov 21 13:43:07 2011 +1100

    Tests: eventscripts - make init test pass with recent change to 10.interface
    
    e646142f4d28b5401235cd5edee325f7a29f8193 changes the output on the
    init event.  This accommodates that change.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>

commit a63e603cb7e21a7334c6a07bc4415ff089dab3c1
Author: Martin Schwenke <martin at meltin.net>
Date:   Tue Oct 18 14:48:55 2011 +1100

    Tests: new test to check that "ctdb delip" removes the IP from interface.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>

-----------------------------------------------------------------------

Summary of changes:
 tests/complex/11_ctdb_delip_removes_ip.sh          |  115 ++++++++++++++++++++
 tests/eventscripts/common.sh                       |   17 ++--
 tests/eventscripts/simple/10.interface.init.001.sh |    2 +-
 tests/takeover/ctdb_takeover.py                    |   86 ++++++++++++++-
 4 files changed, 204 insertions(+), 16 deletions(-)
 create mode 100755 tests/complex/11_ctdb_delip_removes_ip.sh


Changeset truncated at 500 lines:

diff --git a/tests/complex/11_ctdb_delip_removes_ip.sh b/tests/complex/11_ctdb_delip_removes_ip.sh
new file mode 100755
index 0000000..f60b630
--- /dev/null
+++ b/tests/complex/11_ctdb_delip_removes_ip.sh
@@ -0,0 +1,115 @@
+#!/bin/bash
+
+test_info()
+{
+    cat <<EOF
+Verify that a node's public IP address can be deleted using 'ctdb deleteip'.
+
+Check that the address is actually deleted from the interface.
+
+Prerequisites:
+
+* An active CTDB cluster with at least 2 active nodes.
+
+* Test must be run on a real or virtual cluster rather than against
+  local daemons.  There is nothing intrinsic to this test that forces
+  this - it is because tests run against local daemons don't use the
+  regular eventscripts.  Local daemons put public addresses on
+  loopback, so we can't reliably test when IPs have moved between
+  nodes.
+
+Steps:
+
+1. Verify that the status on all of the ctdb nodes is 'OK'.
+2. Use 'ctdb ip' on one of the nodes to list the IP addresses being
+   served.
+3. Select an IP address being served by the node and check that it
+   actually appears on the interface it is supposed to be on.
+4. Delete the IP address using 'ctdb delip'.
+5. Verify that the deleted IP address is no longer listed using the
+   all_ips_on_node helper function.
+6. Verify that the deleted IP address no longer appears on the
+   interface it was on.
+
+Expected results:
+
+* 'ctdb delip' removes an IP address from the list of public IP
+  addresses being served by a node and from the network interface.
+EOF
+}
+
+. ctdb_test_functions.bash
+
+set -e
+
+ctdb_test_init "$@"
+
+ctdb_test_check_real_cluster
+
+cluster_is_healthy
+
+# Reset configuration
+ctdb_restart_when_done
+
+echo "Getting list of public IPs..."
+all_ips_on_node -v 0
+
+# Select an IP/node to remove.
+num_ips=$(echo "$out" | wc -l)
+num_to_remove=$(($RANDOM % $num_ips))
+
+# Find the details in the list.
+i=0
+while [ $i -le $num_to_remove ] ; do
+    read ip_to_remove test_node
+    i=$(($i + 1))
+done <<<"$out"
+
+echo "Determining interface for ${ip_to_remove} on ${test_node}."
+try_command_on_node $test_node "ctdb ip -Y -v"
+iface=$(echo "$out" | awk -F: -v ip=${ip_to_remove} -v pnn=${test_node} '$2 == ip && $3 == pnn { print $4 }')
+echo "$iface"
+[ -n "$iface" ]
+
+echo "Checking that node ${test_node} hosts ${ip_to_remove} on interface ${iface}..."
+try_command_on_node $test_node "ip addr show dev $iface | grep -E 'inet[[:space:]]*${ip_to_remove}/'"
+
+echo "Attempting to remove ${ip_to_remove} from node ${test_node}."
+try_command_on_node $test_node $CTDB delip $ip_to_remove
+
+echo "Sleeping..."
+sleep_for 1
+
+test_node_ips=""
+while read ip pnn ; do
+    [ "$pnn" = "$test_node" ] && \
+	test_node_ips="${test_node_ips}${test_node_ips:+ }${ip}"
+done <<<"$out" # bashism to avoid problem setting variable in pipeline.
+
+if [ "${test_node_ips/${ip_to_remove}}" = "$test_node_ips" ] ; then
+    echo "GOOD: That worked!"
+else
+    echo "BAD: The remove IP address is still there!"
+    testfailures=1
+fi
+
+timeout=60
+increment=5
+count=0
+echo "Waiting for ${ip_to_remove} to disappear from ${iface}..."
+while : ; do
+    try_command_on_node -v $test_node "ip addr show dev $iface"
+    if echo "$out" | grep -E 'inet[[:space:]]*${ip_to_remove}/'; then
+	echo "Still there..."
+	if [ $(($count * $increment)) -ge $timeout ] ; then
+	    echo "BAD: Timed out waiting..."
+	    exit 1
+	fi
+	sleep_for $increment
+	count=$(($count + 1))
+    else
+	break
+    fi
+done
+
+echo "GOOD: IP was successfully removed!"
diff --git a/tests/eventscripts/common.sh b/tests/eventscripts/common.sh
index a79c293..df9656b 100644
--- a/tests/eventscripts/common.sh
+++ b/tests/eventscripts/common.sh
@@ -460,16 +460,13 @@ rpc_set_service_failure_response ()
     # the flexibility to set the number of failures.
     _numfails="${2:-${iteration}}"
 
-    if [ -f /etc/sysconfig/nfs ]; then
-	_c="${CTDB_ETCDIR}/sysconfig/nfs"
-    elif [ -f /etc/default/nfs ]; then
-	_c="${CTDB_ETCDIR}/default/nfs"
-    elif [ -f /etc/ctdb/sysconfig/nfs ]; then
-	_c="${CTDB_ETCDIR}/ctdb/sysconfig/nfs"
-    fi
-    if [ -r "$_c" ] ; then
-	. "$_c"
-    fi
+    _etc="$CTDB_ETCDIR" # shortcut for readability
+    for _c in "$_etc/sysconfig/nfs" "$_etc/default/nfs" "$_etc/ctdb/sysconfig/nfs" ; do
+	if [ -r "$_c" ] ; then
+	    . "$_c"
+	    break
+	fi
+    done
 
     # A handy newline.  :-)
     _nl="
diff --git a/tests/eventscripts/simple/10.interface.init.001.sh b/tests/eventscripts/simple/10.interface.init.001.sh
index 411355f..5a61ab3 100755
--- a/tests/eventscripts/simple/10.interface.init.001.sh
+++ b/tests/eventscripts/simple/10.interface.init.001.sh
@@ -8,6 +8,6 @@ setup_ctdb
 
 export CTDB_PUBLIC_ADDRESSES="$CTDB_ETC/does/not/exist"
 
-ok_null
+ok "No public addresses file found. Nothing to do for 10.interfaces"
 
 simple_test
diff --git a/tests/takeover/ctdb_takeover.py b/tests/takeover/ctdb_takeover.py
index c8c0ed6..bc24fd4 100755
--- a/tests/takeover/ctdb_takeover.py
+++ b/tests/takeover/ctdb_takeover.py
@@ -35,6 +35,10 @@ import itertools
 import socket
 import struct
 
+# For external algorithm
+import subprocess
+import re
+
 options = None
 
 def process_args(extra_options=[]):
@@ -52,6 +56,9 @@ def process_args(extra_options=[]):
     parser.add_option("-L", "--lcp2",
                       action="store_true", dest="lcp2", default=False,
                       help="use LCP2 IP rebalancing algorithm [default: %default]")
+    parser.add_option("-e", "--external",
+                      action="store_true", dest="external", default=False,
+                      help="use external test program to implement IP allocation algorithm [default: %default]")
     parser.add_option("-b", "--balance",
                       action="store_true", dest="balance", default=False,
                       help="show (im)balance information after each event")
@@ -97,7 +104,12 @@ def process_args(extra_options=[]):
     (options, args) = parser.parse_args()
 
     if len(args) != 0:
-        parser.error("too many argumentss")
+        parser.error("too many arguments")
+
+    # Could use a callback for this or change the default, but
+    # laziness is sometimes a virtue.  ;-)
+    if options.lcp2:
+        options.deterministic_public_ips = False
 
 def print_begin(t, delim='='):
     print delim * 40
@@ -680,10 +692,7 @@ class Cluster(object):
 
         return False
 
-
-    def ctdb_takeover_run(self):
-
-        self.events += 1
+    def ctdb_takeover_run_python(self):
 
         # Don't bother with the num_healthy stuff.  It is an
         # irrelevant detail.
@@ -747,6 +756,73 @@ class Cluster(object):
             else:
                 should_loop = self.basic_failback(retries_l)
 
+    def ctdb_takeover_run_external(self):
+
+        # Written while asleep...
+
+        # Convert the cluster state to something that be fed to
+        # ctdb_takeover_tests ctdb_takeover_run_core ...
+
+        in_lines = []
+        for ip in sorted(list(self.all_public_ips)):
+            allowed = []
+            assigned = -1
+            for (i, n) in enumerate(self.nodes):
+                if n.can_node_serve_ip(ip):
+                    allowed.append("%s" % i)
+                if ip in n.current_addresses:
+                    assigned = i
+            line = "%s\t%d\t%s" % (ip, assigned, ",".join(allowed))
+            in_lines.append(line)
+
+        nodestates = ",".join(["0" if n.healthy else "1" for n in self.nodes])
+
+        if options.lcp2:
+            os.environ["CTDB_LCP2"] = "yes"
+        if options.verbose > 1:
+            os.environ["CTDB_TEST_LOGLEVEL"] = "4"
+        elif options.verbose == 1:
+            os.environ["CTDB_TEST_LOGLEVEL"] = "3"
+        else:
+            os.environ["CTDB_TEST_LOGLEVEL"] = "0"
+
+        p = subprocess.Popen("../bin/ctdb_takeover_tests ctdb_takeover_run_core %s 2>&1" % nodestates,
+                             shell=True,
+                             stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+        p.stdin.write("\n".join(in_lines))
+        p.stdin.close()
+
+        # Flush all of the assigned IPs.
+        for n in self.nodes:
+            n.current_addresses = set()
+
+        # Uses the results to populate the current_addresses for each
+        # node.
+        for line in p.stdout.read().split("\n"):
+            # Some lines are debug, some are the final IP
+            # configuration.  Let's use a gross hack that assumes any
+            # line with 2 words is IP configuration.  That will do for
+            # now.
+            words = re.split("\s+", line)
+            if len(words) == 2:
+                # Add the IP as current for the specified node.
+                self.nodes[int(words[1])].current_addresses.add(words[0])
+            else:
+                 # First 3 words are log date/time, remove them...
+                 print " ".join(words[3:])
+
+        # Now fake up the LCP calculations.
+        for n in self.nodes:
+            n.set_imbalance()
+
+    def ctdb_takeover_run(self):
+
+        self.events += 1
+
+        if options.external:
+            return self.ctdb_takeover_run_external()
+        else:
+            return self.ctdb_takeover_run_python()
 
     def recover(self):
         verbose_begin("TAKEOVER")


-- 
CTDB repository


More information about the samba-cvs mailing list