"""
+import os
import sys
import optparse
from itertools import izip, islice, cycle
"""Acumulate feedback in our buffer."""
self._feed_buf.write(msg)
self._feed_buf.write("\n")
+ if self.opts.verbose:
+ Log(msg)
def ExecOp(self, op):
"""Execute an opcode and manage the exec buffer."""
parser.add_option("--no-failover", dest="do_failover",
help="Skip instance failovers", action="store_false",
default=True)
+ parser.add_option("--no-importexport", dest="do_importexport",
+ help="Skip instance export/import", action="store_false",
+ default=True)
+ parser.add_option("--no-startstop", dest="do_startstop",
+ help="Skip instance stop/start", action="store_false",
+ default=True)
parser.add_option("-t", "--disk-template", dest="disk_template",
- choices=("remote_raid1", "drbd"),
- default="remote_raid1",
- help="Template type for network mirroring (remote_raid1"
- " or drbd) [remote_raid1]")
+ choices=("diskless", "plain", "remote_raid1", "drbd"),
+ default="drbd",
+ help="Template type (plain, diskless, drbd, remote_raid1)"
+ " [drbd]")
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:
Usage()
- supported_disk_templates = (constants.DT_PLAIN, constants.DT_REMOTE_RAID1,
+ supported_disk_templates = (constants.DT_DISKLESS, constants.DT_PLAIN,
+ constants.DT_REMOTE_RAID1,
constants.DT_DRBD8)
if options.disk_template not in supported_disk_templates:
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
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,
disk_size=self.opts.os_size,
wait_for_sync=True,
mac="auto",
kernel_path=None,
- initrd_path=None)
- Log("- Add instance %s on node %s" % (instance, pnode))
+ initrd_path=None,
+ hvm_boot_order=None,
+ iallocator=self.opts.iallocator)
self.ExecOp(op)
self.to_rem.append(instance)
Log("- Failover instance %s" % (instance))
self.ExecOp(op)
+ def ImportExport(self):
+ """Export the instance, delete it, and import it back.
+
+ """
+
+ mytor = izip(cycle(self.nodes),
+ islice(cycle(self.nodes), 1, None),
+ islice(cycle(self.nodes), 2, None),
+ self.instances)
+
+ for pnode, snode, enode, instance in mytor:
+ exp_op = opcodes.OpExportInstance(instance_name=instance,
+ target_node=enode,
+ shutdown=True)
+ rem_op = opcodes.OpRemoveInstance(instance_name=instance)
+ nam_op = opcodes.OpQueryInstances(output_fields=["name"],
+ names=[instance])
+ full_name = self.ExecOp(nam_op)[0][0]
+ imp_dir = os.path.join(constants.EXPORT_DIR, full_name)
+ imp_op = opcodes.OpCreateInstance(instance_name=instance,
+ mem_size=128,
+ disk_size=self.opts.os_size,
+ swap_size=self.opts.swap_size,
+ disk_template=self.opts.disk_template,
+ mode=constants.INSTANCE_IMPORT,
+ src_node=enode,
+ src_path=imp_dir,
+ pnode=pnode,
+ snode=snode,
+ vcpus=1,
+ start=True,
+ ip_check=True,
+ wait_for_sync=True,
+ mac="auto")
+ 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))
+ self.ExecOp(imp_op)
+ Log("- Remove export of instance %s" % (instance))
+ self.ExecOp(erem_op)
+
+ self.to_rem.append(instance)
+
def StopStart(self):
"""Stop/start the instances."""
for instance in self.instances:
Log("- Testing global parameters")
- if len(self.nodes) == 1 and opts.disk_template != constants.DT_PLAIN:
+ if (len(self.nodes) == 1 and
+ opts.disk_template not in (constants.DT_DISKLESS, constants.DT_PLAIN)):
Log("When one node is available/selected the disk template must"
- " be 'plain'")
+ " be 'plain' or 'diskless'")
sys.exit(1)
has_err = True
if opts.do_failover and opts.disk_template in constants.DTS_NET_MIRROR:
self.Failover()
- self.StopStart()
+ if opts.do_importexport:
+ self.ImportExport()
+
+ if opts.do_startstop:
+ self.StopStart()
+
has_err = False
finally:
if has_err: