Revision c832b6c8 lib/client/gnt_node.py
b/lib/client/gnt_node.py | ||
---|---|---|
100 | 100 |
_MODIFIABLE_STORAGE_TYPES = constants.MODIFIABLE_STORAGE_FIELDS.keys() |
101 | 101 |
|
102 | 102 |
|
103 |
_OOB_COMMAND_ASK = frozenset([constants.OOB_POWER_OFF, |
|
104 |
constants.OOB_POWER_CYCLE]) |
|
105 |
|
|
106 |
|
|
103 | 107 |
NONODE_SETUP_OPT = cli_option("--no-node-setup", default=True, |
104 | 108 |
action="store_false", dest="node_setup", |
105 | 109 |
help=("Do not make initial SSH setup on remote" |
... | ... | |
487 | 491 |
@return: the desired exit code |
488 | 492 |
|
489 | 493 |
""" |
490 |
command = args[0] |
|
491 |
node = args[1] |
|
494 |
client = GetClient() |
|
495 |
command = args.pop(0) |
|
496 |
|
|
497 |
if opts.no_headers: |
|
498 |
headers = None |
|
499 |
else: |
|
500 |
headers = {"node": "Node", "status": "Status"} |
|
492 | 501 |
|
493 | 502 |
if command not in _LIST_POWER_COMMANDS: |
494 | 503 |
ToStderr("power subcommand %s not supported." % command) |
495 | 504 |
return constants.EXIT_FAILURE |
496 | 505 |
|
506 |
nodes = [node for (node, ) in client.QueryNodes(args, ["name"], False)] |
|
497 | 507 |
oob_command = "power-%s" % command |
498 | 508 |
|
509 |
if oob_command in _OOB_COMMAND_ASK: |
|
510 |
if not args and not opts.show_all: |
|
511 |
ToStderr("Please provide at least one node or use --all for this command" |
|
512 |
" as this is a potentially harmful command") |
|
513 |
return constants.EXIT_FAILURE |
|
514 |
elif args and opts.show_all: |
|
515 |
ToStderr("Please provide either nodes or use --all, can not use both at" |
|
516 |
" the same time") |
|
517 |
return constants.EXIT_FAILURE |
|
518 |
elif not opts.force and not ConfirmOperation(nodes, "nodes", |
|
519 |
"power %s" % command): |
|
520 |
return constants.EXIT_FAILURE |
|
521 |
|
|
499 | 522 |
opcodelist = [] |
500 | 523 |
if not opts.ignore_status and oob_command == constants.OOB_POWER_OFF: |
501 |
opcodelist.append(opcodes.OpNodeSetParams(node_name=node, offline=True, |
|
502 |
auto_promote=opts.auto_promote)) |
|
524 |
# TODO: This is a little ugly as we can't catch and revert |
|
525 |
for node in nodes: |
|
526 |
opcodelist.append(opcodes.OpNodeSetParams(node_name=node, offline=True, |
|
527 |
auto_promote=opts.auto_promote)) |
|
503 | 528 |
|
504 |
opcodelist.append(opcodes.OpOobCommand(node_names=[node],
|
|
529 |
opcodelist.append(opcodes.OpOobCommand(node_names=nodes,
|
|
505 | 530 |
command=oob_command, |
506 | 531 |
ignore_status=opts.ignore_status, |
507 | 532 |
force_master=opts.force_master)) |
... | ... | |
514 | 539 |
# If it fails PollJob gives us the error message in it |
515 | 540 |
result = cli.PollJob(job_id)[-1] |
516 | 541 |
|
517 |
if result: |
|
518 |
(_, data_tuple) = result[0] |
|
519 |
if data_tuple[0] != constants.RS_NORMAL: |
|
520 |
if data_tuple[0] == constants.RS_UNAVAIL: |
|
521 |
result = "OOB is not supported" |
|
522 |
else: |
|
523 |
result = "RPC failed, look out for warning in the output" |
|
524 |
ToStderr(result) |
|
525 |
return constants.EXIT_FAILURE |
|
526 |
else: |
|
542 |
errs = 0 |
|
543 |
data = [] |
|
544 |
for node_result in result: |
|
545 |
(node_tuple, data_tuple) = node_result |
|
546 |
(_, node_name) = node_tuple |
|
547 |
(data_status, data_node) = data_tuple |
|
548 |
if data_status == constants.RS_NORMAL: |
|
527 | 549 |
if oob_command == constants.OOB_POWER_STATUS: |
528 |
text = "The machine is %spowered" |
|
529 |
if data_tuple[1][constants.OOB_POWER_STATUS_POWERED]: |
|
530 |
result = text % "" |
|
550 |
if data_node[constants.OOB_POWER_STATUS_POWERED]: |
|
551 |
text = "powered" |
|
531 | 552 |
else: |
532 |
result = text % "not " |
|
533 |
ToStdout(result) |
|
553 |
text = "unpowered" |
|
554 |
data.append([node_name, text]) |
|
555 |
else: |
|
556 |
# We don't expect data here, so we just say, it was successfully invoked |
|
557 |
data.append([node_name, "invoked"]) |
|
558 |
else: |
|
559 |
errs += 1 |
|
560 |
data.append([node_name, cli.FormatResultError(data_status)]) |
|
561 |
|
|
562 |
data = GenerateTable(separator=opts.separator, headers=headers, |
|
563 |
fields=["node", "status"], data=data) |
|
564 |
|
|
565 |
for line in data: |
|
566 |
ToStdout(line) |
|
534 | 567 |
|
535 |
return constants.EXIT_SUCCESS |
|
568 |
if errs: |
|
569 |
return constants.EXIT_FAILURE |
|
570 |
else: |
|
571 |
return constants.EXIT_SUCCESS |
|
536 | 572 |
|
537 | 573 |
|
538 | 574 |
def Health(opts, args): |
... | ... | |
826 | 862 |
'power': ( |
827 | 863 |
PowerNode, |
828 | 864 |
[ArgChoice(min=1, max=1, choices=_LIST_POWER_COMMANDS), |
829 |
ArgNode(min=1, max=1)],
|
|
865 |
ArgNode()], |
|
830 | 866 |
[SUBMIT_OPT, AUTO_PROMOTE_OPT, PRIORITY_OPT, IGNORE_STATUS_OPT, |
831 |
FORCE_MASTER_OPT], |
|
832 |
"on|off|cycle|status <node>",
|
|
867 |
FORCE_MASTER_OPT, FORCE_OPT, NOHDR_OPT, SEP_OPT, ALL_OPT],
|
|
868 |
"on|off|cycle|status [nodes...]",
|
|
833 | 869 |
"Change power state of node by calling out-of-band helper."), |
834 | 870 |
'remove': ( |
835 | 871 |
RemoveNode, ARGS_ONE_NODE, [DRY_RUN_OPT, PRIORITY_OPT], |
Also available in: Unified diff