X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/2f505cb5fa2a976d27d8ca5c8b5333590acb7ae0..e2212007105454572424bcff0ccfcc890f568c18:/tools/burnin diff --git a/tools/burnin b/tools/burnin index 0a3a640..cfa848a 100755 --- a/tools/burnin +++ b/tools/burnin @@ -26,6 +26,7 @@ import os import sys import optparse +import time from itertools import izip, islice, cycle from cStringIO import StringIO @@ -62,9 +63,8 @@ class Burner(object): def __init__(self): """Constructor.""" - logger.SetupLogging(debug=False, program="ganeti/burnin") + logger.SetupLogging(program="ganeti/burnin", debug=False) self._feed_buf = StringIO() - self.proc = mcpu.Processor(feedback=self.Feedback) self.nodes = [] self.instances = [] self.to_rem = [] @@ -82,15 +82,14 @@ class Burner(object): def Feedback(self, msg): """Acumulate feedback in our buffer.""" - self._feed_buf.write(msg) - self._feed_buf.write("\n") + self._feed_buf.write("%s %s\n" % (time.ctime(msg[0]), msg[2])) if self.opts.verbose: Log(msg) def ExecOp(self, op): """Execute an opcode and manage the exec buffer.""" self.ClearFeedbackBuf() - return self.proc.ExecOpCode(op) + return cli.SubmitOpCode(op, feedback_fn=self.Feedback) def ParseOptions(self): """Parses the command line options. @@ -112,6 +111,8 @@ class Burner(object): default=4 * 1024, type="unit", metavar="") parser.add_option("--swap-size", dest="swap_size", help="Swap size", default=4 * 1024, type="unit", metavar="") + parser.add_option("--mem-size", dest="mem_size", help="Memory size", + default=128, type="unit", metavar="") parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False, help="print command execution messages to stdout") @@ -130,6 +131,10 @@ class Burner(object): parser.add_option("--no-startstop", dest="do_startstop", help="Skip instance stop/start", action="store_false", default=True) + parser.add_option("--rename", dest="rename", default=None, + help="Give one unused instance name which is taken" + " to start the renaming sequence", + metavar="") parser.add_option("-t", "--disk-template", dest="disk_template", choices=("diskless", "file", "plain", "drbd"), default="drbd", @@ -138,6 +143,11 @@ class Burner(object): parser.add_option("-n", "--nodes", dest="nodes", default="", help="Comma separated list of nodes to perform" " the burnin on (defaults to all nodes)") + parser.add_option("--iallocator", dest="iallocator", + default=None, type="string", + help="Perform the allocation using an iallocator" + " instead of fixed node spread (node restrictions no" + " longer apply, therefore -n/--nodes must not be used") options, args = parser.parse_args() if len(args) < 1 or options.os is None: @@ -151,6 +161,10 @@ class Burner(object): Log("Unknown disk template '%s'" % options.disk_template) sys.exit(1) + if options.nodes and options.iallocator: + Log("Give either the nodes option or the iallocator option, not both") + sys.exit(1) + self.opts = options self.instances = args @@ -192,8 +206,18 @@ class Burner(object): islice(cycle(self.nodes), 1, None), self.instances) for pnode, snode, instance in mytor: + if self.opts.iallocator: + pnode = snode = None + Log("- Add instance %s (iallocator: %s)" % + (instance, self.opts.iallocator)) + elif self.opts.disk_template not in constants.DTS_NET_MIRROR: + snode = None + Log("- Add instance %s on node %s" % (instance, pnode)) + else: + Log("- Add instance %s on nodes %s/%s" % (instance, pnode, snode)) + op = opcodes.OpCreateInstance(instance_name=instance, - mem_size=128, + mem_size=self.opts.mem_size, disk_size=self.opts.os_size, swap_size=self.opts.swap_size, disk_template=self.opts.disk_template, @@ -210,8 +234,8 @@ class Burner(object): initrd_path=None, hvm_boot_order=None, file_driver="loop", - file_storage_dir=None) - Log("- Add instance %s on nodes %s/%s" % (instance, pnode, snode)) + file_storage_dir=None, + iallocator=self.opts.iallocator) self.ExecOp(op) self.to_rem.append(instance) @@ -232,9 +256,12 @@ class Burner(object): mytor = izip(islice(cycle(self.nodes), 2, None), self.instances) for tnode, instance in mytor: + if self.opts.iallocator: + tnode = None op = opcodes.OpReplaceDisks(instance_name=instance, mode=mode, remote_node=tnode, + iallocator=self.opts.iallocator, disks=["sda", "sdb"]) Log("- Replace secondary (%s) for instance %s" % (mode, instance)) self.ExecOp(op) @@ -260,10 +287,24 @@ class Burner(object): self.instances) for pnode, snode, enode, instance in mytor: + + if self.opts.iallocator: + pnode = snode = None + import_log_msg = ("- Import instance %s from node %s (iallocator: %s)" % + (instance, enode, self.opts.iallocator)) + elif self.opts.disk_template not in constants.DTS_NET_MIRROR: + snode = None + import_log_msg = ("- Import instance %s from node %s to node %s" % + (instance, enode, pnode)) + else: + import_log_msg = ("- Import instance %s from node %s to nodes %s/%s" % + (instance, enode, pnode, snode)) + exp_op = opcodes.OpExportInstance(instance_name=instance, target_node=enode, shutdown=True) - rem_op = opcodes.OpRemoveInstance(instance_name=instance) + rem_op = opcodes.OpRemoveInstance(instance_name=instance, + ignore_failures=True) nam_op = opcodes.OpQueryInstances(output_fields=["name"], names=[instance]) full_name = self.ExecOp(nam_op)[0][0] @@ -282,35 +323,69 @@ class Burner(object): start=True, ip_check=True, wait_for_sync=True, - mac="auto") + mac="auto", + file_storage_dir=None, + file_driver=None, + iallocator=self.opts.iallocator) + erem_op = opcodes.OpRemoveExport(instance_name=instance) Log("- Export instance %s to node %s" % (instance, enode)) self.ExecOp(exp_op) Log("- Remove instance %s" % (instance)) self.ExecOp(rem_op) self.to_rem.remove(instance) - Log("- Import instance %s from node %s to node %s" % - (instance, enode, pnode)) + Log(import_log_msg) self.ExecOp(imp_op) + Log("- Remove export of instance %s" % (instance)) + self.ExecOp(erem_op) + self.to_rem.append(instance) + def StopInstance(self, instance): + """Stop given instance.""" + op = opcodes.OpShutdownInstance(instance_name=instance) + Log("- Shutdown instance %s" % instance) + self.ExecOp(op) + + def StartInstance(self, instance): + """Start given instance.""" + op = opcodes.OpStartupInstance(instance_name=instance, force=False) + Log("- Start instance %s" % instance) + self.ExecOp(op) + + def RenameInstance(self, instance, instance_new): + """Rename instance.""" + op = opcodes.OpRenameInstance(instance_name=instance, + new_name=instance_new) + Log("- Rename instance %s to %s" % (instance, instance_new)) + self.ExecOp(op) + def StopStart(self): """Stop/start the instances.""" for instance in self.instances: - op = opcodes.OpShutdownInstance(instance_name=instance) - Log("- Shutdown instance %s" % instance) - self.ExecOp(op) - op = opcodes.OpStartupInstance(instance_name=instance, force=False) - Log("- Start instance %s" % instance) - self.ExecOp(op) + self.StopInstance(instance) + self.StartInstance(instance) def Remove(self): """Remove the instances.""" for instance in self.to_rem: - op = opcodes.OpRemoveInstance(instance_name=instance) + op = opcodes.OpRemoveInstance(instance_name=instance, + ignore_failures=True) Log("- Remove instance %s" % instance) self.ExecOp(op) + + def Rename(self): + """Rename the instances.""" + rename = self.opts.rename + for instance in self.instances: + self.StopInstance(instance) + self.RenameInstance(instance, rename) + self.StartInstance(rename) + self.StopInstance(rename) + self.RenameInstance(rename, instance) + self.StartInstance(instance) + def BurninCluster(self): """Test a cluster intensively. @@ -348,6 +423,9 @@ class Burner(object): if opts.do_startstop: self.StopStart() + if opts.rename: + self.Rename() + has_err = False finally: if has_err: @@ -363,17 +441,7 @@ def main(): """Main function""" burner = Burner() - try: - utils.Lock('cmd', max_retries=15, debug=True) - except errors.LockError, err: - logger.ToStderr(str(err)) - return 1 - try: - retval = burner.BurninCluster() - finally: - utils.Unlock('cmd') - utils.LockCleanup() - return retval + return burner.BurninCluster() if __name__ == "__main__":