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 TestOsParams(opts, _):
587 """Set secret os parameters. 588 589 """ 590 op = opcodes.OpTestOsParams(osparams_secret=opts.osparams_secret) 591 SubmitOrSend(op, opts) 592 593 return 0
594 595
596 -def ListLocks(opts, args): # pylint: disable=W0613
597 """List all locks. 598 599 @param opts: the command line options selected by the user 600 @type args: list 601 @param args: should be an empty list 602 @rtype: int 603 @return: the desired exit code 604 605 """ 606 selected_fields = ParseFields(opts.output, _LIST_LOCKS_DEF_FIELDS) 607 608 def _DashIfNone(fn): 609 def wrapper(value): 610 if not value: 611 return "-" 612 return fn(value) 613 return wrapper 614 615 def _FormatPending(value): 616 """Format pending acquires. 617 618 """ 619 return utils.CommaJoin("%s:%s" % (mode, ",".join(map(str, threads))) 620 for mode, threads in value) 621 622 # Format raw values 623 fmtoverride = { 624 "mode": (_DashIfNone(str), False), 625 "owner": (_DashIfNone(",".join), False), 626 "pending": (_DashIfNone(_FormatPending), False), 627 } 628 629 while True: 630 ret = GenericList(constants.QR_LOCK, selected_fields, None, None, 631 opts.separator, not opts.no_headers, 632 format_override=fmtoverride, verbose=opts.verbose) 633 634 if ret != constants.EXIT_SUCCESS: 635 return ret 636 637 if not opts.interval: 638 break 639 640 ToStdout("") 641 time.sleep(opts.interval) 642 643 return 0 644 645
646 -def Metad(opts, args): # pylint: disable=W0613
647 """Send commands to Metad. 648 649 @param opts: the command line options selected by the user 650 @type args: list 651 @param args: the command to send, followed by the command-specific arguments 652 @rtype: int 653 @return: the desired exit code 654 655 """ 656 if args[0] == "echo": 657 if len(args) != 2: 658 ToStderr("Command 'echo' takes only precisely argument.") 659 return 1 660 result = metad.Client().Echo(args[1]) 661 print "Answer: %s" % (result,) 662 else: 663 ToStderr("Command '%s' not supported", args[0]) 664 return 1 665 666 return 0 667 668
669 -def Wconfd(opts, args): # pylint: disable=W0613
670 """Send commands to WConfD. 671 672 @param opts: the command line options selected by the user 673 @type args: list 674 @param args: the command to send, followed by the command-specific arguments 675 @rtype: int 676 @return: the desired exit code 677 678 """ 679 if args[0] == "echo": 680 if len(args) != 2: 681 ToStderr("Command 'echo' takes only precisely argument.") 682 return 1 683 result = wconfd.Client().Echo(args[1]) 684 print "Answer: %s" % (result,) 685 elif args[0] == "cleanuplocks": 686 if len(args) != 1: 687 ToStderr("Command 'cleanuplocks' takes no arguments.") 688 return 1 689 wconfd.Client().CleanupLocks() 690 print "Stale locks cleaned up." 691 elif args[0] == "listlocks": 692 if len(args) != 2: 693 ToStderr("Command 'listlocks' takes precisely one argument.") 694 return 1 695 wconfdcontext = (int(args[1]), 696 utils.livelock.GuessLockfileFor("masterd_1")) 697 result = wconfd.Client().ListLocks(wconfdcontext) 698 print "Answer: %s" % (result,) 699 elif args[0] == "listalllocks": 700 if len(args) != 1: 701 ToStderr("Command 'listalllocks' takes no arguments.") 702 return 1 703 result = wconfd.Client().ListAllLocks() 704 print "Answer: %s" % (result,) 705 elif args[0] == "listalllocksowners": 706 if len(args) != 1: 707 ToStderr("Command 'listalllocks' takes no arguments.") 708 return 1 709 result = wconfd.Client().ListAllLocksOwners() 710 print "Answer: %s" % (result,) 711 elif args[0] == "flushconfig": 712 if len(args) != 1: 713 ToStderr("Command 'flushconfig' takes no arguments.") 714 return 1 715 wconfd.Client().FlushConfig() 716 print "Configuration flushed." 717 else: 718 ToStderr("Command '%s' not supported", args[0]) 719 return 1 720 721 return 0 722 723 724 commands = { 725 "delay": ( 726 Delay, [ArgUnknown(min=1, max=1)], 727 [cli_option("--no-master", dest="on_master", default=True, 728 action="store_false", help="Do not sleep in the master code"), 729 cli_option("-n", dest="on_nodes", default=[], 730 action="append", help="Select nodes to sleep on"), 731 cli_option("-r", "--repeat", type="int", default="0", dest="repeat", 732 help="Number of times to repeat the sleep"), 733 cli_option("-i", "--interruptible", default=False, dest="interruptible", 734 action="store_true", 735 help="Allows the opcode to be interrupted by using a domain " 736 "socket"), 737 cli_option("-l", "--no-locks", default=False, dest="no_locks", 738 action="store_true", 739 help="Don't take locks while performing the delay"), 740 DRY_RUN_OPT, PRIORITY_OPT] + SUBMIT_OPTS, 741 "[opts...] <duration>", "Executes a TestDelay OpCode"), 742 "submit-job": ( 743 GenericOpCodes, [ArgFile(min=1)], 744 [VERBOSE_OPT, 745 cli_option("--op-repeat", type="int", default="1", dest="rep_op", 746 help="Repeat the opcode sequence this number of times"), 747 cli_option("--job-repeat", type="int", default="1", dest="rep_job", 748 help="Repeat the job this number of times"), 749 cli_option("--timing-stats", default=False, 750 action="store_true", help="Show timing stats"), 751 cli_option("--each", default=False, action="store_true", 752 help="Submit each job separately"), 753 DRY_RUN_OPT, PRIORITY_OPT, 754 ], 755 "<op_list_file...>", "Submits jobs built from json files" 756 " containing a list of serialized opcodes"), 757 "iallocator": ( 758 TestAllocator, [ArgUnknown(min=1)], 759 [cli_option("--dir", dest="direction", default=constants.IALLOCATOR_DIR_IN, 760 choices=list(constants.VALID_IALLOCATOR_DIRECTIONS), 761 help="Show allocator input (in) or allocator" 762 " results (out)"), 763 IALLOCATOR_OPT, 764 cli_option("-m", "--mode", default="relocate", 765 choices=list(constants.VALID_IALLOCATOR_MODES), 766 help=("Request mode (one of %s)" % 767 utils.CommaJoin(constants.VALID_IALLOCATOR_MODES))), 768 cli_option("--memory", default=128, type="unit", 769 help="Memory size for the instance (MiB)"), 770 cli_option("--disks", default="4096,4096", 771 help="Comma separated list of disk sizes (MiB)"), 772 DISK_TEMPLATE_OPT, 773 cli_option("--nics", default="00:11:22:33:44:55", 774 help="Comma separated list of nics, each nic" 775 " definition is of form mac/ip/bridge, if" 776 " missing values are replace by None"), 777 OS_OPT, 778 cli_option("-p", "--vcpus", default=1, type="int", 779 help="Select number of VCPUs for the instance"), 780 cli_option("--tags", default=None, 781 help="Comma separated list of tags"), 782 cli_option("--evac-mode", default=constants.NODE_EVAC_ALL, 783 choices=list(constants.NODE_EVAC_MODES), 784 help=("Node evacuation mode (one of %s)" % 785 utils.CommaJoin(constants.NODE_EVAC_MODES))), 786 cli_option("--target-groups", help="Target groups for relocation", 787 default=[], action="append"), 788 cli_option("--spindle-use", help="How many spindles to use", 789 default=1, type="int"), 790 cli_option("--count", help="How many instances to allocate", 791 default=2, type="int"), 792 DRY_RUN_OPT, PRIORITY_OPT, 793 ], 794 "{opts...} <instance>", "Executes a TestAllocator OpCode"), 795 "test-jobqueue": ( 796 TestJobqueue, ARGS_NONE, [PRIORITY_OPT], 797 "", "Test a few aspects of the job queue"), 798 "test-osparams": ( 799 TestOsParams, ARGS_NONE, [OSPARAMS_SECRET_OPT] + SUBMIT_OPTS, 800 "[--os-parameters-secret <params>]", 801 "Test secret os parameter transmission"), 802 "locks": ( 803 ListLocks, ARGS_NONE, 804 [NOHDR_OPT, SEP_OPT, FIELDS_OPT, INTERVAL_OPT, VERBOSE_OPT], 805 "[--interval N]", "Show a list of locks in the master daemon"), 806 "wconfd": ( 807 Wconfd, [ArgUnknown(min=1)], [], 808 "<cmd> <args...>", "Directly talk to WConfD"), 809 "metad": ( 810 Metad, [ArgUnknown(min=1)], [], 811 "<cmd> <args...>", "Directly talk to Metad"), 812 } 813 814 #: dictionary with aliases for commands 815 aliases = { 816 "allocator": "iallocator", 817 } 818 819
820 -def Main():
821 return GenericMain(commands, aliases=aliases)
822