Revision 836d59d7
b/tools/burnin | ||
---|---|---|
56 | 56 |
sys.exit(2) |
57 | 57 |
|
58 | 58 |
|
59 |
def Log(msg): |
|
59 |
def Log(msg, indent=0):
|
|
60 | 60 |
"""Simple function that prints out its argument. |
61 | 61 |
|
62 | 62 |
""" |
63 |
print msg |
|
63 |
headers = { |
|
64 |
0: "- ", |
|
65 |
1: "* ", |
|
66 |
2: "" |
|
67 |
} |
|
68 |
sys.stdout.write("%*s%s%s\n" % (2*indent, "", |
|
69 |
headers.get(indent, " "), msg)) |
|
64 | 70 |
sys.stdout.flush() |
65 | 71 |
|
72 |
def Err(msg, exit_code=1): |
|
73 |
"""Simple error logging that prints to stderr. |
|
74 |
|
|
75 |
""" |
|
76 |
sys.stderr.write(msg + "\n") |
|
77 |
sys.stderr.flush() |
|
78 |
sys.exit(exit_code) |
|
66 | 79 |
|
67 | 80 |
class Burner(object): |
68 | 81 |
"""Burner class.""" |
... | ... | |
92 | 105 |
self._feed_buf.write("%s %s\n" % (time.ctime(utils.MergeTime(msg[0])), |
93 | 106 |
msg[2])) |
94 | 107 |
if self.opts.verbose: |
95 |
Log(msg) |
|
108 |
Log(msg, indent=3)
|
|
96 | 109 |
|
97 | 110 |
def ExecOp(self, op): |
98 | 111 |
"""Execute an opcode and manage the exec buffer.""" |
... | ... | |
109 | 122 |
""" |
110 | 123 |
self.ClearFeedbackBuf() |
111 | 124 |
job_ids = [cli.SendJob(job, cl=self.cl) for job in jobs] |
112 |
Log("- Submitted job IDs %s" % ", ".join(job_ids))
|
|
125 |
Log("Submitted job IDs %s" % ", ".join(job_ids), indent=1)
|
|
113 | 126 |
results = [] |
114 | 127 |
for jid in job_ids: |
115 |
Log("- Waiting for job %s" % jid)
|
|
128 |
Log("Waiting for job %s" % jid, indent=2)
|
|
116 | 129 |
results.append(cli.PollJob(jid, cl=self.cl, feedback_fn=self.Feedback)) |
117 | 130 |
|
118 | 131 |
return results |
... | ... | |
217 | 230 |
constants.DT_PLAIN, |
218 | 231 |
constants.DT_DRBD8) |
219 | 232 |
if options.disk_template not in supported_disk_templates: |
220 |
Log("Unknown disk template '%s'" % options.disk_template) |
|
221 |
sys.exit(1) |
|
233 |
Err("Unknown disk template '%s'" % options.disk_template) |
|
222 | 234 |
|
223 | 235 |
if options.disk_template == constants.DT_DISKLESS: |
224 | 236 |
disk_size = disk_growth = [] |
... | ... | |
228 | 240 |
disk_growth = [utils.ParseUnit(v) |
229 | 241 |
for v in options.disk_growth.split(",")] |
230 | 242 |
if len(disk_growth) != len(disk_size): |
231 |
Log("Wrong disk sizes/growth combination") |
|
232 |
sys.exit(1) |
|
243 |
Err("Wrong disk sizes/growth combination") |
|
233 | 244 |
if ((disk_size and options.disk_template == constants.DT_DISKLESS) or |
234 | 245 |
(not disk_size and options.disk_template != constants.DT_DISKLESS)): |
235 |
Log("Wrong disk count/disk template combination") |
|
236 |
sys.exit(1) |
|
246 |
Err("Wrong disk count/disk template combination") |
|
237 | 247 |
|
238 | 248 |
self.disk_size = disk_size |
239 | 249 |
self.disk_growth = disk_growth |
240 | 250 |
self.disk_count = len(disk_size) |
241 | 251 |
|
242 | 252 |
if options.nodes and options.iallocator: |
243 |
Log("Give either the nodes option or the iallocator option, not both") |
|
244 |
sys.exit(1) |
|
253 |
Err("Give either the nodes option or the iallocator option, not both") |
|
245 | 254 |
|
246 | 255 |
self.opts = options |
247 | 256 |
self.instances = args |
... | ... | |
264 | 273 |
result = self.ExecOp(op) |
265 | 274 |
except errors.GenericError, err: |
266 | 275 |
err_code, msg = cli.FormatError(err) |
267 |
Log(msg) |
|
268 |
sys.exit(err_code) |
|
276 |
Err(msg, exit_code=err_code) |
|
269 | 277 |
self.nodes = [data[0] for data in result if not data[1]] |
270 | 278 |
|
271 | 279 |
result = self.ExecOp(opcodes.OpDiagnoseOS(output_fields=["name", "valid"], |
272 | 280 |
names=[])) |
273 | 281 |
|
274 | 282 |
if not result: |
275 |
Log("Can't get the OS list") |
|
276 |
sys.exit(1) |
|
283 |
Err("Can't get the OS list") |
|
277 | 284 |
|
278 | 285 |
# filter non-valid OS-es |
279 | 286 |
os_set = [val[0] for val in result if val[1]] |
280 | 287 |
|
281 | 288 |
if self.opts.os not in os_set: |
282 |
Log("OS '%s' not found" % self.opts.os) |
|
283 |
sys.exit(1) |
|
289 |
Err("OS '%s' not found" % self.opts.os) |
|
284 | 290 |
|
285 | 291 |
def CreateInstances(self): |
286 | 292 |
"""Create the given instances. |
... | ... | |
292 | 298 |
self.instances) |
293 | 299 |
jobset = [] |
294 | 300 |
|
301 |
Log("Creating instances") |
|
295 | 302 |
for pnode, snode, instance in mytor: |
303 |
Log("instance %s" % instance, indent=1) |
|
296 | 304 |
if self.opts.iallocator: |
297 | 305 |
pnode = snode = None |
298 |
Log("- Add instance %s (iallocator: %s)" % |
|
299 |
(instance, self.opts.iallocator)) |
|
306 |
msg = "with iallocator %s" % self.opts.iallocator |
|
300 | 307 |
elif self.opts.disk_template not in constants.DTS_NET_MIRROR: |
301 | 308 |
snode = None |
302 |
Log("- Add instance %s on node %s" % (instance, pnode))
|
|
309 |
msg = "on %s" % pnode
|
|
303 | 310 |
else: |
304 |
Log("- Add instance %s on nodes %s/%s" % (instance, pnode, snode)) |
|
311 |
msg = "on %s, %s" % (pnode, snode) |
|
312 |
|
|
313 |
Log(msg, indent=2) |
|
305 | 314 |
|
306 | 315 |
op = opcodes.OpCreateInstance(instance_name=instance, |
307 | 316 |
disks = [ {"size": size} |
... | ... | |
338 | 347 |
|
339 | 348 |
def GrowDisks(self): |
340 | 349 |
"""Grow both the os and the swap disks by the requested amount, if any.""" |
350 |
Log("Growing disks") |
|
341 | 351 |
for instance in self.instances: |
352 |
Log("instance %s" % instance, indent=1) |
|
342 | 353 |
for idx, growth in enumerate(self.disk_growth): |
343 | 354 |
if growth > 0: |
344 | 355 |
op = opcodes.OpGrowDisk(instance_name=instance, disk=idx, |
345 | 356 |
amount=growth, wait_for_sync=True) |
346 |
Log("- Increase %s's disk/%s by %s MB" % (instance, idx, growth))
|
|
357 |
Log("increase disk/%s by %s MB" % (idx, growth), indent=2)
|
|
347 | 358 |
self.ExecOp(op) |
348 | 359 |
|
349 | 360 |
def ReplaceDisks1D8(self): |
350 | 361 |
"""Replace disks on primary and secondary for drbd8.""" |
362 |
Log("Replacing disks on the same nodes") |
|
351 | 363 |
for instance in self.instances: |
364 |
Log("instance %s" % instance, indent=1) |
|
352 | 365 |
for mode in constants.REPLACE_DISK_SEC, constants.REPLACE_DISK_PRI: |
353 | 366 |
op = opcodes.OpReplaceDisks(instance_name=instance, |
354 | 367 |
mode=mode, |
355 | 368 |
disks=[i for i in range(self.disk_count)]) |
356 |
Log("- Replace disks (%s) for instance %s" % (mode, instance))
|
|
369 |
Log("run %s" % mode, indent=2)
|
|
357 | 370 |
self.ExecOp(op) |
358 | 371 |
|
359 | 372 |
def ReplaceDisks2(self): |
360 | 373 |
"""Replace secondary node.""" |
374 |
Log("Changing the secondary node") |
|
361 | 375 |
mode = constants.REPLACE_DISK_CHG |
362 | 376 |
|
363 | 377 |
mytor = izip(islice(cycle(self.nodes), 2, None), |
364 | 378 |
self.instances) |
365 | 379 |
for tnode, instance in mytor: |
380 |
Log("instance %s" % instance, indent=1) |
|
366 | 381 |
if self.opts.iallocator: |
367 | 382 |
tnode = None |
383 |
msg = "with iallocator %s" % self.opts.iallocator |
|
384 |
else: |
|
385 |
msg = tnode |
|
368 | 386 |
op = opcodes.OpReplaceDisks(instance_name=instance, |
369 | 387 |
mode=mode, |
370 | 388 |
remote_node=tnode, |
371 | 389 |
iallocator=self.opts.iallocator, |
372 | 390 |
disks=[i for i in range(self.disk_count)]) |
373 |
Log("- Replace secondary (%s) for instance %s" % (mode, instance))
|
|
391 |
Log("run %s %s" % (mode, msg), indent=2)
|
|
374 | 392 |
self.ExecOp(op) |
375 | 393 |
|
376 | 394 |
def Failover(self): |
377 | 395 |
"""Failover the instances.""" |
378 |
|
|
396 |
Log("Failing over instances") |
|
379 | 397 |
for instance in self.instances: |
398 |
Log("instance %s" % instance, indent=1) |
|
380 | 399 |
op = opcodes.OpFailoverInstance(instance_name=instance, |
381 | 400 |
ignore_consistency=False) |
382 | 401 |
|
383 |
Log("- Failover instance %s" % (instance)) |
|
384 | 402 |
self.ExecOp(op) |
385 | 403 |
for instance in self.instances: |
386 | 404 |
self._CheckInstanceAlive(instance) |
... | ... | |
389 | 407 |
"""Export the instance, delete it, and import it back. |
390 | 408 |
|
391 | 409 |
""" |
392 |
|
|
410 |
Log("Exporting and re-importing instances") |
|
393 | 411 |
mytor = izip(cycle(self.nodes), |
394 | 412 |
islice(cycle(self.nodes), 1, None), |
395 | 413 |
islice(cycle(self.nodes), 2, None), |
396 | 414 |
self.instances) |
397 | 415 |
|
398 | 416 |
for pnode, snode, enode, instance in mytor: |
399 |
|
|
417 |
Log("instance %s" % instance, indent=1) |
|
400 | 418 |
if self.opts.iallocator: |
401 | 419 |
pnode = snode = None |
402 |
import_log_msg = ("- Import instance %s from node %s"
|
|
403 |
" (iallocator: %s)" %
|
|
404 |
(instance, enode, self.opts.iallocator))
|
|
420 |
import_log_msg = ("import from %s"
|
|
421 |
" with iallocator %s" %
|
|
422 |
(enode, self.opts.iallocator)) |
|
405 | 423 |
elif self.opts.disk_template not in constants.DTS_NET_MIRROR: |
406 | 424 |
snode = None |
407 |
import_log_msg = ("- Import instance %s from node %s to node %s" %
|
|
408 |
(instance, enode, pnode))
|
|
425 |
import_log_msg = ("import from %s to %s" %
|
|
426 |
(enode, pnode)) |
|
409 | 427 |
else: |
410 |
import_log_msg = ("- Import instance %s from node %s to nodes %s/%s" %
|
|
411 |
(instance, enode, pnode, snode))
|
|
428 |
import_log_msg = ("import from %s to %s, %s" %
|
|
429 |
(enode, pnode, snode)) |
|
412 | 430 |
|
413 | 431 |
exp_op = opcodes.OpExportInstance(instance_name=instance, |
414 | 432 |
target_node=enode, |
... | ... | |
441 | 459 |
|
442 | 460 |
erem_op = opcodes.OpRemoveExport(instance_name=instance) |
443 | 461 |
|
444 |
Log("- Export instance %s to node %s" % (instance, enode))
|
|
462 |
Log("export to node %s" % enode, indent=2)
|
|
445 | 463 |
self.ExecOp(exp_op) |
446 |
Log("- Remove instance %s" % (instance))
|
|
464 |
Log("remove instance", indent=2)
|
|
447 | 465 |
self.ExecOp(rem_op) |
448 | 466 |
self.to_rem.remove(instance) |
449 |
Log(import_log_msg) |
|
467 |
Log(import_log_msg, indent=2)
|
|
450 | 468 |
self.ExecOp(imp_op) |
451 |
Log("- Remove export of instance %s" % (instance))
|
|
469 |
Log("remove export", indent=2)
|
|
452 | 470 |
self.ExecOp(erem_op) |
453 | 471 |
|
454 | 472 |
self.to_rem.append(instance) |
... | ... | |
459 | 477 |
def StopInstance(self, instance): |
460 | 478 |
"""Stop given instance.""" |
461 | 479 |
op = opcodes.OpShutdownInstance(instance_name=instance) |
462 |
Log("- Shutdown instance %s" % instance)
|
|
480 |
Log("shutdown", indent=2)
|
|
463 | 481 |
self.ExecOp(op) |
464 | 482 |
|
465 | 483 |
def StartInstance(self, instance): |
466 | 484 |
"""Start given instance.""" |
467 | 485 |
op = opcodes.OpStartupInstance(instance_name=instance, force=False) |
468 |
Log("- Start instance %s" % instance)
|
|
486 |
Log("startup", indent=2)
|
|
469 | 487 |
self.ExecOp(op) |
470 | 488 |
|
471 | 489 |
def RenameInstance(self, instance, instance_new): |
472 | 490 |
"""Rename instance.""" |
473 | 491 |
op = opcodes.OpRenameInstance(instance_name=instance, |
474 | 492 |
new_name=instance_new) |
475 |
Log("- Rename instance %s to %s" % (instance, instance_new))
|
|
493 |
Log("rename to %s" % instance_new, indent=2)
|
|
476 | 494 |
self.ExecOp(op) |
477 | 495 |
|
478 | 496 |
def StopStart(self): |
479 | 497 |
"""Stop/start the instances.""" |
498 |
Log("Stopping and starting instances") |
|
480 | 499 |
for instance in self.instances: |
500 |
Log("instance %s" % instance, indent=1) |
|
481 | 501 |
self.StopInstance(instance) |
482 | 502 |
self.StartInstance(instance) |
483 | 503 |
|
... | ... | |
486 | 506 |
|
487 | 507 |
def Remove(self): |
488 | 508 |
"""Remove the instances.""" |
509 |
Log("Removing instances") |
|
489 | 510 |
for instance in self.to_rem: |
511 |
Log("instance %s" % instance, indent=1) |
|
490 | 512 |
op = opcodes.OpRemoveInstance(instance_name=instance, |
491 | 513 |
ignore_failures=True) |
492 |
Log("- Remove instance %s" % instance) |
|
493 | 514 |
self.ExecOp(op) |
494 | 515 |
|
495 | 516 |
def Rename(self): |
496 | 517 |
"""Rename the instances.""" |
518 |
Log("Renaming instances") |
|
497 | 519 |
rename = self.opts.rename |
498 | 520 |
for instance in self.instances: |
521 |
Log("instance %s" % instance, indent=1) |
|
499 | 522 |
self.StopInstance(instance) |
500 | 523 |
self.RenameInstance(instance, rename) |
501 | 524 |
self.StartInstance(rename) |
... | ... | |
509 | 532 |
|
510 | 533 |
def Reinstall(self): |
511 | 534 |
"""Reinstall the instances.""" |
535 |
Log("Reinstalling instances") |
|
512 | 536 |
for instance in self.instances: |
537 |
Log("instance %s" % instance, indent=1) |
|
513 | 538 |
self.StopInstance(instance) |
514 | 539 |
op = opcodes.OpReinstallInstance(instance_name=instance) |
515 |
Log("- Reinstall instance %s without passing the OS" % (instance,))
|
|
540 |
Log("reinstall without passing the OS", indent=2)
|
|
516 | 541 |
self.ExecOp(op) |
517 | 542 |
op = opcodes.OpReinstallInstance(instance_name=instance, |
518 | 543 |
os_type=self.opts.os) |
519 |
Log("- Reinstall instance %s specifying the OS" % (instance,))
|
|
544 |
Log("reinstall specifying the OS", indent=2)
|
|
520 | 545 |
self.ExecOp(op) |
521 | 546 |
self.StartInstance(instance) |
522 | 547 |
for instance in self.instances: |
523 | 548 |
self._CheckInstanceAlive(instance) |
524 | 549 |
|
525 | 550 |
def Reboot(self): |
526 |
"""Reinstall the instances.""" |
|
551 |
"""Reboot the instances.""" |
|
552 |
Log("Rebooting instances") |
|
527 | 553 |
for instance in self.instances: |
554 |
Log("instance %s" % instance, indent=1) |
|
528 | 555 |
for reboot_type in constants.REBOOT_TYPES: |
529 | 556 |
op = opcodes.OpRebootInstance(instance_name=instance, |
530 | 557 |
reboot_type=reboot_type, |
531 | 558 |
ignore_secondaries=False) |
532 |
Log("- Reboot instance %s with type '%s'" % (instance, reboot_type))
|
|
559 |
Log("reboot with type '%s'" % reboot_type, indent=2)
|
|
533 | 560 |
self.ExecOp(op) |
534 | 561 |
self._CheckInstanceAlive(instance) |
535 | 562 |
|
536 | 563 |
def ActivateDisks(self): |
537 | 564 |
"""Activate and deactivate disks of the instances.""" |
565 |
Log("Activating/deactivating disks") |
|
538 | 566 |
for instance in self.instances: |
567 |
Log("instance %s" % instance, indent=1) |
|
539 | 568 |
op_act = opcodes.OpActivateInstanceDisks(instance_name=instance) |
540 | 569 |
op_deact = opcodes.OpDeactivateInstanceDisks(instance_name=instance) |
541 |
Log("- Activate disks of online instance %s" % (instance,))
|
|
570 |
Log("activate disks when online", indent=2)
|
|
542 | 571 |
self.ExecOp(op_act) |
543 | 572 |
self.StopInstance(instance) |
544 |
Log("- Activate disks of offline instance %s" % (instance,))
|
|
573 |
Log("activate disks when offline", indent=2)
|
|
545 | 574 |
self.ExecOp(op_act) |
546 |
Log("- Deactivate disks of offline instance %s" % (instance,))
|
|
575 |
Log("deactivate disks (when offline)", indent=2)
|
|
547 | 576 |
self.ExecOp(op_deact) |
548 | 577 |
self.StartInstance(instance) |
549 | 578 |
for instance in self.instances: |
... | ... | |
551 | 580 |
|
552 | 581 |
def AddRemoveDisks(self): |
553 | 582 |
"""Add and remove an extra disk for the instances.""" |
583 |
Log("Adding and removing disks") |
|
554 | 584 |
for instance in self.instances: |
585 |
Log("instance %s" % instance, indent=1) |
|
555 | 586 |
op_add = opcodes.OpSetInstanceParams(\ |
556 | 587 |
instance_name=instance, |
557 | 588 |
disks=[(constants.DDM_ADD, {"size": self.disk_size[0]})]) |
558 | 589 |
op_rem = opcodes.OpSetInstanceParams(\ |
559 | 590 |
instance_name=instance, disks=[(constants.DDM_REMOVE, {})]) |
560 |
Log("- Adding a disk to instance %s" % (instance,))
|
|
591 |
Log("adding a disk", indent=2)
|
|
561 | 592 |
self.ExecOp(op_add) |
562 | 593 |
self.StopInstance(instance) |
563 |
Log("- Removing the last disk of instance %s" % (instance,))
|
|
594 |
Log("removing last disk", indent=2)
|
|
564 | 595 |
self.ExecOp(op_rem) |
565 | 596 |
self.StartInstance(instance) |
566 | 597 |
for instance in self.instances: |
... | ... | |
568 | 599 |
|
569 | 600 |
def AddRemoveNICs(self): |
570 | 601 |
"""Add and remove an extra NIC for the instances.""" |
602 |
Log("Adding and removing NICs") |
|
571 | 603 |
for instance in self.instances: |
604 |
Log("instance %s" % instance, indent=1) |
|
572 | 605 |
op_add = opcodes.OpSetInstanceParams(\ |
573 | 606 |
instance_name=instance, nics=[(constants.DDM_ADD, {})]) |
574 | 607 |
op_rem = opcodes.OpSetInstanceParams(\ |
575 | 608 |
instance_name=instance, nics=[(constants.DDM_REMOVE, {})]) |
576 |
Log("- Adding a NIC to instance %s" % (instance,))
|
|
609 |
Log("adding a NIC", indent=2)
|
|
577 | 610 |
self.ExecOp(op_add) |
578 |
Log("- Removing the last NIC of instance %s" % (instance,))
|
|
611 |
Log("removing last NIC", indent=2)
|
|
579 | 612 |
self.ExecOp(op_rem) |
580 | 613 |
|
581 | 614 |
def _CheckInstanceAlive(self, instance): |
... | ... | |
615 | 648 |
|
616 | 649 |
opts = self.opts |
617 | 650 |
|
618 |
Log("- Testing global parameters")
|
|
651 |
Log("Testing global parameters") |
|
619 | 652 |
|
620 | 653 |
if (len(self.nodes) == 1 and |
621 | 654 |
opts.disk_template not in (constants.DT_DISKLESS, constants.DT_PLAIN, |
622 | 655 |
constants.DT_FILE)): |
623 |
Log("When one node is available/selected the disk template must"
|
|
656 |
Err("When one node is available/selected the disk template must"
|
|
624 | 657 |
" be 'diskless', 'file' or 'plain'") |
625 |
sys.exit(1) |
|
626 | 658 |
|
627 | 659 |
has_err = True |
628 | 660 |
try: |
Also available in: Unified diff