summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xctdb/tests/takeover/ctdb_takeover.py86
1 files changed, 81 insertions, 5 deletions
diff --git a/ctdb/tests/takeover/ctdb_takeover.py b/ctdb/tests/takeover/ctdb_takeover.py
index c8c0ed6e33..bc24fd4162 100755
--- a/ctdb/tests/takeover/ctdb_takeover.py
+++ b/ctdb/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")