Package ganeti :: Package client :: Module gnt_debug
[hide private]
[frames] | no frames]

Source Code for Module ganeti.client.gnt_debug

  1  # 
  2  # 
  3   
  4  # Copyright (C) 2006, 2007, 2010, 2011, 2012 Google Inc. 
  5  # All rights reserved. 
  6  # 
  7  # Redistribution and use in source and binary forms, with or without 
  8  # modification, are permitted provided that the following conditions are 
  9  # met: 
 10  # 
 11  # 1. Redistributions of source code must retain the above copyright notice, 
 12  # this list of conditions and the following disclaimer. 
 13  # 
 14  # 2. Redistributions in binary form must reproduce the above copyright 
 15  # notice, this list of conditions and the following disclaimer in the 
 16  # documentation and/or other materials provided with the distribution. 
 17  # 
 18  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 
 19  # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 
 20  # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
 21  # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
 22  # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
 23  # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 24  # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
 25  # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
 26  # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
 27  # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
 28  # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 29   
 30  """Debugging commands""" 
 31   
 32  # pylint: disable=W0401,W0614,C0103 
 33  # W0401: Wildcard import ganeti.cli 
 34  # W0614: Unused import %s from wildcard import (since we need cli) 
 35  # C0103: Invalid name gnt-backup 
 36   
 37  import simplejson 
 38  import time 
 39  import socket 
 40  import logging 
 41   
 42  from ganeti.cli import * 
 43  from ganeti import cli 
 44  from ganeti import constants 
 45  from ganeti import opcodes 
 46  from ganeti import utils 
 47  from ganeti import errors 
 48  from ganeti import compat 
 49  from ganeti import ht 
 50  from ganeti import metad 
 51  from ganeti import wconfd 
 52   
 53   
 54  #: Default fields for L{ListLocks} 
 55  _LIST_LOCKS_DEF_FIELDS = [ 
 56    "name", 
 57    "mode", 
 58    "owner", 
 59    "pending", 
 60    ] 
 61   
 62   
63 -def Delay(opts, args):
64 """Sleeps for a while 65 66 @param opts: the command line options selected by the user 67 @type args: list 68 @param args: should contain only one element, the duration 69 the sleep 70 @rtype: int 71 @return: the desired exit code 72 73 """ 74 delay = float(args[0]) 75 op = opcodes.OpTestDelay(duration=delay, 76 on_master=opts.on_master, 77 on_nodes=opts.on_nodes, 78 repeat=opts.repeat, 79 interruptible=opts.interruptible, 80 no_locks=opts.no_locks) 81 SubmitOrSend(op, opts) 82 83 return 0
84 85
86 -def GenericOpCodes(opts, args):
87 """Send any opcode to the master. 88 89 @param opts: the command line options selected by the user 90 @type args: list 91 @param args: should contain only one element, the path of 92 the file with the opcode definition 93 @rtype: int 94 @return: the desired exit code 95 96 """ 97 cl = cli.GetClient() 98 jex = cli.JobExecutor(cl=cl, verbose=opts.verbose, opts=opts) 99 100 job_cnt = 0 101 op_cnt = 0 102 if opts.timing_stats: 103 ToStdout("Loading...") 104 for job_idx in range(opts.rep_job): 105 for fname in args: 106 # pylint: disable=W0142 107 op_data = simplejson.loads(utils.ReadFile(fname)) 108 op_list = [opcodes.OpCode.LoadOpCode(val) for val in op_data] 109 op_list = op_list * opts.rep_op 110 jex.QueueJob("file %s/%d" % (fname, job_idx), *op_list) 111 op_cnt += len(op_list) 112 job_cnt += 1 113 114 if opts.timing_stats: 115 t1 = time.time() 116 ToStdout("Submitting...") 117 118 jex.SubmitPending(each=opts.each) 119 120 if opts.timing_stats: 121 t2 = time.time() 122 ToStdout("Executing...") 123 124 jex.GetResults() 125 if opts.timing_stats: 126 t3 = time.time() 127 ToStdout("C:op %4d" % op_cnt) 128 ToStdout("C:job %4d" % job_cnt) 129 ToStdout("T:submit %4.4f" % (t2 - t1)) 130 ToStdout("T:exec %4.4f" % (t3 - t2)) 131 ToStdout("T:total %4.4f" % (t3 - t1)) 132 return 0
133 134
135 -def TestAllocator(opts, args):
136 """Runs the test allocator opcode. 137 138 @param opts: the command line options selected by the user 139 @type args: list 140 @param args: should contain only one element, the iallocator name 141 @rtype: int 142 @return: the desired exit code 143 144 """ 145 try: 146 disks = [{ 147 constants.IDISK_SIZE: utils.ParseUnit(val), 148 constants.IDISK_MODE: constants.DISK_RDWR, 149 } for val in opts.disks.split(",")] 150 except errors.UnitParseError, err: 151 ToStderr("Invalid disks parameter '%s': %s", opts.disks, err) 152 return 1 153 154 nics = [val.split("/") for val in opts.nics.split(",")] 155 for row in nics: 156 while len(row) < 3: 157 row.append(None) 158 for i in range(3): 159 if row[i] == "": 160 row[i] = None 161 nic_dict = [{ 162 constants.INIC_MAC: v[0], 163 constants.INIC_IP: v[1], 164 # The iallocator interface defines a "bridge" item 165 "bridge": v[2], 166 } for v in nics] 167 168 if opts.tags is None: 169 opts.tags = [] 170 else: 171 opts.tags = opts.tags.split(",") 172 if opts.target_groups is None: 173 target_groups = [] 174 else: 175 target_groups = opts.target_groups 176 177 op = opcodes.OpTestAllocator(mode=opts.mode, 178 name=args[0], 179 instances=args, 180 memory=opts.memory, 181 disks=disks, 182 disk_template=opts.disk_template, 183 nics=nic_dict, 184 os=opts.os, 185 vcpus=opts.vcpus, 186 tags=opts.tags, 187 direction=opts.direction, 188 iallocator=opts.iallocator, 189 evac_mode=opts.evac_mode, 190 target_groups=target_groups, 191 spindle_use=opts.spindle_use, 192 count=opts.count) 193 result = SubmitOpCode(op, opts=opts) 194 ToStdout("%s" % result) 195 return 0
196 197
198 -def _TestJobDependency(opts):
199 """Tests job dependencies. 200 201 """ 202 ToStdout("Testing job dependencies") 203 204 try: 205 cl = cli.GetClient() 206 SubmitOpCode(opcodes.OpTestDelay(duration=0, depends=[(-1, None)]), cl=cl) 207 except errors.GenericError, err: 208 if opts.debug: 209 ToStdout("Ignoring error for 'wrong dependencies' test: %s", err) 210 else: 211 raise errors.OpExecError("Submitting plain opcode with relative job ID" 212 " did not fail as expected") 213 214 # TODO: Test dependencies on errors 215 jobs = [ 216 [opcodes.OpTestDelay(duration=1)], 217 [opcodes.OpTestDelay(duration=1, 218 depends=[(-1, [])])], 219 [opcodes.OpTestDelay(duration=1, 220 depends=[(-2, [constants.JOB_STATUS_SUCCESS])])], 221 [opcodes.OpTestDelay(duration=1, 222 depends=[])], 223 [opcodes.OpTestDelay(duration=1, 224 depends=[(-2, [constants.JOB_STATUS_SUCCESS])])], 225 ] 226 227 # Function for checking result 228 check_fn = ht.TListOf(ht.TAnd(ht.TIsLength(2), 229 ht.TItems([ht.TBool, 230 ht.TOr(ht.TNonEmptyString, 231 ht.TJobId)]))) 232 233 cl = cli.GetClient() 234 result = cl.SubmitManyJobs(jobs) 235 if not check_fn(result): 236 raise errors.OpExecError("Job submission doesn't match %s: %s" % 237 (check_fn, result)) 238 239 # Wait for jobs to finish 240 jex = JobExecutor(cl=cl, opts=opts) 241 242 for (status, job_id) in result: 243 jex.AddJobId(None, status, job_id) 244 245 job_results = jex.GetResults() 246 if not compat.all(row[0] for row in job_results): 247 raise errors.OpExecError("At least one of the submitted jobs failed: %s" % 248 job_results) 249 250 # Get details about jobs 251 data = cl.QueryJobs([job_id for (_, job_id) in result], 252 ["id", "opexec", "ops"]) 253 data_job_id = [job_id for (job_id, _, _) in data] 254 data_opexec = [opexec for (_, opexec, _) in data] 255 data_op = [[opcodes.OpCode.LoadOpCode(op) for op in ops] 256 for (_, _, ops) in data] 257 258 assert compat.all(not op.depends or len(op.depends) == 1 259 for ops in data_op 260 for op in ops) 261 262 # Check resolved job IDs in dependencies 263 for (job_idx, res_jobdep) in [(1, data_job_id[0]), 264 (2, data_job_id[0]), 265 (4, data_job_id[2])]: 266 if data_op[job_idx][0].depends[0][0] != res_jobdep: 267 raise errors.OpExecError("Job %s's opcode doesn't depend on correct job" 268 " ID (%s)" % (job_idx, res_jobdep)) 269 270 # Check execution order 271 if not (data_opexec[0] <= data_opexec[1] and 272 data_opexec[0] <= data_opexec[2] and 273 data_opexec[2] <= data_opexec[4]): 274 raise errors.OpExecError("Jobs did not run in correct order: %s" % data) 275 276 assert len(jobs) == 5 and compat.all(len(ops) == 1 for ops in jobs) 277 278 ToStdout("Job dependency tests were successful")
279 280
281 -def _TestJobSubmission(opts):
282 """Tests submitting jobs. 283 284 """ 285 ToStdout("Testing job submission") 286 287 testdata = [ 288 (0, 0, constants.OP_PRIO_LOWEST), 289 (0, 0, constants.OP_PRIO_HIGHEST), 290 ] 291 292 for priority in (constants.OP_PRIO_SUBMIT_VALID | 293 frozenset([constants.OP_PRIO_LOWEST, 294 constants.OP_PRIO_HIGHEST])): 295 for offset in [-1, +1]: 296 testdata.extend([ 297 (0, 0, priority + offset), 298 (3, 0, priority + offset), 299 (0, 3, priority + offset), 300 (4, 2, priority + offset), 301 ]) 302 303 for before, after, failpriority in testdata: 304 ops = [] 305 ops.extend([opcodes.OpTestDelay(duration=0) for _ in range(before)]) 306 ops.append(opcodes.OpTestDelay(duration=0, priority=failpriority)) 307 ops.extend([opcodes.OpTestDelay(duration=0) for _ in range(after)]) 308 309 try: 310 cl = cli.GetClient() 311 cl.SubmitJob(ops) 312 except errors.GenericError, err: 313 if opts.debug: 314 ToStdout("Ignoring error for 'wrong priority' test: %s", err) 315 else: 316 raise errors.OpExecError("Submitting opcode with priority %s did not" 317 " fail when it should (allowed are %s)" % 318 (failpriority, constants.OP_PRIO_SUBMIT_VALID)) 319 320 jobs = [ 321 [opcodes.OpTestDelay(duration=0), 322 opcodes.OpTestDelay(duration=0, dry_run=False), 323 opcodes.OpTestDelay(duration=0, dry_run=True)], 324 ops, 325 ] 326 try: 327 cl = cli.GetClient() 328 cl.SubmitManyJobs(jobs) 329 except errors.GenericError, err: 330 if opts.debug: 331 ToStdout("Ignoring error for 'wrong priority' test: %s", err) 332 else: 333 raise errors.OpExecError("Submitting manyjobs with an incorrect one" 334 " did not fail when it should.") 335 ToStdout("Job submission tests were successful")
336 337
338 -class _JobQueueTestReporter(cli.StdioJobPollReportCb):
339 - def __init__(self):
340 """Initializes this class. 341 342 """ 343 cli.StdioJobPollReportCb.__init__(self) 344 self._expected_msgcount = 0 345 self._all_testmsgs = [] 346 self._testmsgs = None 347 self._job_id = None
348
349 - def GetTestMessages(self):
350 """Returns all test log messages received so far. 351 352 """ 353 return self._all_testmsgs
354
355 - def GetJobId(self):
356 """Returns the job ID. 357 358 """ 359 return self._job_id
360
361 - def ReportLogMessage(self, job_id, serial, timestamp, log_type, log_msg):
362 """Handles a log message. 363 364 """ 365 if self._job_id is None: 366 self._job_id = job_id 367 elif self._job_id != job_id: 368 raise errors.ProgrammerError("The same reporter instance was used for" 369 " more than one job") 370 371 if log_type == constants.ELOG_JQUEUE_TEST: 372 (sockname, test, arg) = log_msg 373 return self._ProcessTestMessage(job_id, sockname, test, arg) 374 375 elif (log_type == constants.ELOG_MESSAGE and 376 log_msg.startswith(constants.JQT_MSGPREFIX)): 377 if self._testmsgs is None: 378 raise errors.OpExecError("Received test message without a preceding" 379 " start message") 380 testmsg = log_msg[len(constants.JQT_MSGPREFIX):] 381 self._testmsgs.append(testmsg) 382 self._all_testmsgs.append(testmsg) 383 return 384 385 return cli.StdioJobPollReportCb.ReportLogMessage(self, job_id, serial, 386 timestamp, log_type, 387 log_msg)
388
389 - def _ProcessTestMessage(self, job_id, sockname, test, arg):
390 """Handles a job queue test message. 391 392 """ 393 if test not in constants.JQT_ALL: 394 raise errors.OpExecError("Received invalid test message %s" % test) 395 396 sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) 397 try: 398 sock.settimeout(30.0) 399 400 logging.debug("Connecting to %s", sockname) 401 sock.connect(sockname) 402 403 logging.debug("Checking status") 404 jobdetails = cli.GetClient().QueryJobs([job_id], ["status"])[0] 405 if not jobdetails: 406 raise errors.OpExecError("Can't find job %s" % job_id) 407 408 status = jobdetails[0] 409 410 logging.debug("Status of job %s is %s", job_id, status) 411 412 if test == constants.JQT_EXPANDNAMES: 413 if status != constants.JOB_STATUS_WAITING: 414 raise errors.OpExecError("Job status while expanding names is '%s'," 415 " not '%s' as expected" % 416 (status, constants.JOB_STATUS_WAITING)) 417 elif test in (constants.JQT_EXEC, constants.JQT_LOGMSG): 418 if status != constants.JOB_STATUS_RUNNING: 419 raise errors.OpExecError("Job status while executing opcode is '%s'," 420 " not '%s' as expected" % 421 (status, constants.JOB_STATUS_RUNNING)) 422 423 if test == constants.JQT_STARTMSG: 424 logging.debug("Expecting %s test messages", arg) 425 self._testmsgs = [] 426 elif test == constants.JQT_LOGMSG: 427 if len(self._testmsgs) != arg: 428 raise errors.OpExecError("Received %s test messages when %s are" 429 " expected" % (len(self._testmsgs), arg)) 430 finally: 431 logging.debug("Closing socket") 432 sock.close()
433 434
435 -def TestJobqueue(opts, _):
436 """Runs a few tests on the job queue. 437 438 """ 439 _TestJobSubmission(opts) 440 _TestJobDependency(opts) 441 442 (TM_SUCCESS, 443 TM_MULTISUCCESS, 444 TM_FAIL, 445 TM_PARTFAIL) = range(4) 446 TM_ALL = compat.UniqueFrozenset([ 447 TM_SUCCESS, 448 TM_MULTISUCCESS, 449 TM_FAIL, 450 TM_PARTFAIL, 451 ]) 452 453 for mode in TM_ALL: 454 test_messages = [ 455 "Testing mode %s" % mode, 456 "Hello World", 457 "A", 458 "", 459 "B", 460 "Foo|bar|baz", 461 utils.TimestampForFilename(), 462 ] 463 464 fail = mode in (TM_FAIL, TM_PARTFAIL) 465 466 if mode == TM_PARTFAIL: 467 ToStdout("Testing partial job failure") 468 ops = [ 469 opcodes.OpTestJqueue(notify_waitlock=True, notify_exec=True, 470 log_messages=test_messages, fail=False), 471 opcodes.OpTestJqueue(notify_waitlock=True, notify_exec=True, 472 log_messages=test_messages, fail=False), 473 opcodes.OpTestJqueue(notify_waitlock=True, notify_exec=True, 474 log_messages=test_messages, fail=True), 475 opcodes.OpTestJqueue(notify_waitlock=True, notify_exec=True, 476 log_messages=test_messages, fail=False), 477 ] 478 expect_messages = 3 * [test_messages] 479 expect_opstatus = [ 480 constants.OP_STATUS_SUCCESS, 481 constants.OP_STATUS_SUCCESS, 482 constants.OP_STATUS_ERROR, 483 constants.OP_STATUS_ERROR, 484 ] 485 expect_resultlen = 2 486 elif mode == TM_MULTISUCCESS: 487 ToStdout("Testing multiple successful opcodes") 488 ops = [ 489 opcodes.OpTestJqueue(notify_waitlock=True, notify_exec=True, 490 log_messages=test_messages, fail=False), 491 opcodes.OpTestJqueue(notify_waitlock=True, notify_exec=True, 492 log_messages=test_messages, fail=False), 493 ] 494 expect_messages = 2 * [test_messages] 495 expect_opstatus = [ 496 constants.OP_STATUS_SUCCESS, 497 constants.OP_STATUS_SUCCESS, 498 ] 499 expect_resultlen = 2 500 else: 501 if mode == TM_SUCCESS: 502 ToStdout("Testing job success") 503 expect_opstatus = [constants.OP_STATUS_SUCCESS] 504 elif mode == TM_FAIL: 505 ToStdout("Testing job failure") 506 expect_opstatus = [constants.OP_STATUS_ERROR] 507 else: 508 raise errors.ProgrammerError("Unknown test mode %s" % mode) 509 510 ops = [ 511 opcodes.OpTestJqueue(notify_waitlock=True, 512 notify_exec=True, 513 log_messages=test_messages, 514 fail=fail), 515 ] 516 expect_messages = [test_messages] 517 expect_resultlen = 1 518 519 cl = cli.GetClient() 520 cli.SetGenericOpcodeOpts(ops, opts) 521 522 # Send job to master daemon 523 job_id = cli.SendJob(ops, cl=cl) 524 525 reporter = _JobQueueTestReporter() 526 results = None 527 528 try: 529 results = cli.PollJob(job_id, cl=cl, reporter=reporter) 530 except errors.OpExecError, err: 531 if not fail: 532 raise 533 ToStdout("Ignoring error for 'job fail' test: %s", err) 534 else: 535 if fail: 536 raise errors.OpExecError("Job didn't fail when it should") 537 538 # Check length of result 539 if fail: 540 if results is not None: 541 raise errors.OpExecError("Received result from failed job") 542 elif len(results) != expect_resultlen: 543 raise errors.OpExecError("Received %s results (%s), expected %s" % 544 (len(results), results, expect_resultlen)) 545 546 # Check received log messages 547 all_messages = [i for j in expect_messages for i in j] 548 if reporter.GetTestMessages() != all_messages: 549 raise errors.OpExecError("Received test messages don't match input" 550 " (input %r, received %r)" % 551 (all_messages, reporter.GetTestMessages())) 552 553 # Check final status 554 reported_job_id = reporter.GetJobId() 555 if reported_job_id != job_id: 556 raise errors.OpExecError("Reported job ID %s doesn't match" 557 "submission job ID %s" % 558 (reported_job_id, job_id)) 559 560 jobdetails = cli.GetClient().QueryJobs([job_id], ["status", "opstatus"])[0] 561 if not jobdetails: 562 raise errors.OpExecError("Can't find job %s" % job_id) 563 564 if fail: 565 exp_status = constants.JOB_STATUS_ERROR 566 else: 567 exp_status = constants.JOB_STATUS_SUCCESS 568 569 (final_status, final_opstatus) = jobdetails 570 if final_status != exp_status: 571 raise errors.OpExecError("Final job status is %s, not %s as expected" % 572 (final_status, exp_status)) 573 if len(final_opstatus) != len(ops): 574 raise errors.OpExecError("Did not receive status for all opcodes (got %s," 575 " expected %s)" % 576 (len(final_opstatus), len(ops))) 577 if final_opstatus != expect_opstatus: 578 raise errors.OpExecError("Opcode status is %s, expected %s" % 579 (final_opstatus, expect_opstatus)) 580 581 ToStdout("Job queue test successful") 582 583 return 0
584 585
586 -def ListLocks(opts, args): # pylint: disable=W0613
587 """List all locks. 588 589 @param opts: the command line options selected by the user 590 @type args: list 591 @param args: should be an empty list 592 @rtype: int 593 @return: the desired exit code 594 595 """ 596 selected_fields = ParseFields(opts.output, _LIST_LOCKS_DEF_FIELDS) 597 598 def _DashIfNone(fn): 599 def wrapper(value): 600 if not value: 601 return "-" 602 return fn(value) 603 return wrapper 604 605 def _FormatPending(value): 606 """Format pending acquires. 607 608 """ 609 return utils.CommaJoin("%s:%s" % (mode, ",".join(map(str, threads))) 610 for mode, threads in value) 611 612 # Format raw values 613 fmtoverride = { 614 "mode": (_DashIfNone(str), False), 615 "owner": (_DashIfNone(",".join), False), 616 "pending": (_DashIfNone(_FormatPending), False), 617 } 618 619 while True: 620 ret = GenericList(constants.QR_LOCK, selected_fields, None, None, 621 opts.separator, not opts.no_headers, 622 format_override=fmtoverride, verbose=opts.verbose) 623 624 if ret != constants.EXIT_SUCCESS: 625 return ret 626 627 if not opts.interval: 628 break 629 630 ToStdout("") 631 time.sleep(opts.interval) 632 633 return 0 634 635
636 -def Metad(opts, args): # pylint: disable=W0613
637 """Send commands to Metad. 638 639 @param opts: the command line options selected by the user 640 @type args: list 641 @param args: the command to send, followed by the command-specific arguments 642 @rtype: int 643 @return: the desired exit code 644 645 """ 646 if args[0] == "echo": 647 if len(args) != 2: 648 ToStderr("Command 'echo' takes only precisely argument.") 649 return 1 650 result = metad.Client().Echo(args[1]) 651 print "Answer: %s" % (result,) 652 else: 653 ToStderr("Command '%s' not supported", args[0]) 654 return 1 655 656 return 0 657 658
659 -def Wconfd(opts, args): # pylint: disable=W0613
660 """Send commands to WConfD. 661 662 @param opts: the command line options selected by the user 663 @type args: list 664 @param args: the command to send, followed by the command-specific arguments 665 @rtype: int 666 @return: the desired exit code 667 668 """ 669 if args[0] == "echo": 670 if len(args) != 2: 671 ToStderr("Command 'echo' takes only precisely argument.") 672 return 1 673 result = wconfd.Client().Echo(args[1]) 674 print "Answer: %s" % (result,) 675 elif args[0] == "cleanuplocks": 676 if len(args) != 1: 677 ToStderr("Command 'cleanuplocks' takes no arguments.") 678 return 1 679 wconfd.Client().CleanupLocks() 680 print "Stale locks cleaned up." 681 elif args[0] == "listlocks": 682 if len(args) != 2: 683 ToStderr("Command 'listlocks' takes precisely one argument.") 684 return 1 685 wconfdcontext = (int(args[1]), 686 utils.livelock.GuessLockfileFor("masterd_1")) 687 result = wconfd.Client().ListLocks(wconfdcontext) 688 print "Answer: %s" % (result,) 689 elif args[0] == "listalllocks": 690 if len(args) != 1: 691 ToStderr("Command 'listalllocks' takes no arguments.") 692 return 1 693 result = wconfd.Client().ListAllLocks() 694 print "Answer: %s" % (result,) 695 elif args[0] == "listalllocksowners": 696 if len(args) != 1: 697 ToStderr("Command 'listalllocks' takes no arguments.") 698 return 1 699 result = wconfd.Client().ListAllLocksOwners() 700 print "Answer: %s" % (result,) 701 elif args[0] == "flushconfig": 702 if len(args) != 1: 703 ToStderr("Command 'flushconfig' takes no arguments.") 704 return 1 705 wconfd.Client().FlushConfig() 706 print "Configuration flushed." 707 else: 708 ToStderr("Command '%s' not supported", args[0]) 709 return 1 710 711 return 0 712 713 714 commands = { 715 "delay": ( 716 Delay, [ArgUnknown(min=1, max=1)], 717 [cli_option("--no-master", dest="on_master", default=True, 718 action="store_false", help="Do not sleep in the master code"), 719 cli_option("-n", dest="on_nodes", default=[], 720 action="append", help="Select nodes to sleep on"), 721 cli_option("-r", "--repeat", type="int", default="0", dest="repeat", 722 help="Number of times to repeat the sleep"), 723 cli_option("-i", "--interruptible", default=False, dest="interruptible", 724 action="store_true", 725 help="Allows the opcode to be interrupted by using a domain " 726 "socket"), 727 cli_option("-l", "--no-locks", default=False, dest="no_locks", 728 action="store_true", 729 help="Don't take locks while performing the delay"), 730 DRY_RUN_OPT, PRIORITY_OPT] + SUBMIT_OPTS, 731 "[opts...] <duration>", "Executes a TestDelay OpCode"), 732 "submit-job": ( 733 GenericOpCodes, [ArgFile(min=1)], 734 [VERBOSE_OPT, 735 cli_option("--op-repeat", type="int", default="1", dest="rep_op", 736 help="Repeat the opcode sequence this number of times"), 737 cli_option("--job-repeat", type="int", default="1", dest="rep_job", 738 help="Repeat the job this number of times"), 739 cli_option("--timing-stats", default=False, 740 action="store_true", help="Show timing stats"), 741 cli_option("--each", default=False, action="store_true", 742 help="Submit each job separately"), 743 DRY_RUN_OPT, PRIORITY_OPT, 744 ], 745 "<op_list_file...>", "Submits jobs built from json files" 746 " containing a list of serialized opcodes"), 747 "iallocator": ( 748 TestAllocator, [ArgUnknown(min=1)], 749 [cli_option("--dir", dest="direction", default=constants.IALLOCATOR_DIR_IN, 750 choices=list(constants.VALID_IALLOCATOR_DIRECTIONS), 751 help="Show allocator input (in) or allocator" 752 " results (out)"), 753 IALLOCATOR_OPT, 754 cli_option("-m", "--mode", default="relocate", 755 choices=list(constants.VALID_IALLOCATOR_MODES), 756 help=("Request mode (one of %s)" % 757 utils.CommaJoin(constants.VALID_IALLOCATOR_MODES))), 758 cli_option("--memory", default=128, type="unit", 759 help="Memory size for the instance (MiB)"), 760 cli_option("--disks", default="4096,4096", 761 help="Comma separated list of disk sizes (MiB)"), 762 DISK_TEMPLATE_OPT, 763 cli_option("--nics", default="00:11:22:33:44:55", 764 help="Comma separated list of nics, each nic" 765 " definition is of form mac/ip/bridge, if" 766 " missing values are replace by None"), 767 OS_OPT, 768 cli_option("-p", "--vcpus", default=1, type="int", 769 help="Select number of VCPUs for the instance"), 770 cli_option("--tags", default=None, 771 help="Comma separated list of tags"), 772 cli_option("--evac-mode", default=constants.NODE_EVAC_ALL, 773 choices=list(constants.NODE_EVAC_MODES), 774 help=("Node evacuation mode (one of %s)" % 775 utils.CommaJoin(constants.NODE_EVAC_MODES))), 776 cli_option("--target-groups", help="Target groups for relocation", 777 default=[], action="append"), 778 cli_option("--spindle-use", help="How many spindles to use", 779 default=1, type="int"), 780 cli_option("--count", help="How many instances to allocate", 781 default=2, type="int"), 782 DRY_RUN_OPT, PRIORITY_OPT, 783 ], 784 "{opts...} <instance>", "Executes a TestAllocator OpCode"), 785 "test-jobqueue": ( 786 TestJobqueue, ARGS_NONE, [PRIORITY_OPT], 787 "", "Test a few aspects of the job queue"), 788 "locks": ( 789 ListLocks, ARGS_NONE, 790 [NOHDR_OPT, SEP_OPT, FIELDS_OPT, INTERVAL_OPT, VERBOSE_OPT], 791 "[--interval N]", "Show a list of locks in the master daemon"), 792 "wconfd": ( 793 Wconfd, [ArgUnknown(min=1)], [], 794 "<cmd> <args...>", "Directly talk to WConfD"), 795 "metad": ( 796 Metad, [ArgUnknown(min=1)], [], 797 "<cmd> <args...>", "Directly talk to Metad"), 798 } 799 800 #: dictionary with aliases for commands 801 aliases = { 802 "allocator": "iallocator", 803 } 804 805
806 -def Main():
807 return GenericMain(commands, aliases=aliases)
808